
Docomo 知識Q&Aを使用したLine Bot開発
今回は、Line BotとAIを組み合わせたアプリケーションを作成します。
概要として、ユーザ側で何かしらの言葉を入力するとその言葉に対して連想されるURLを3つまで返してくれるLine Botです。

某漫画〇のように~クマと語尾につきますが、その辺りはカスタマイズできます。
連想されるURLについてはAIの機能を使用しており、Docomo APIで提供されている知識Q&Aを使用します。
また、Line BotとDocomo APIの橋渡しとしてGoogle App Scriptを使用します。
アプリケーション構成図
次の3つのサービスを組み合わせることでアプリケーションを作成します。
・Line Bot
・Docomo API
・Google App Script

① Lineからメッセージを送信し、Google App Scriptで受け取る
② メッセージをDocomo API(知識Q&A)のパラメータに変換して送信する
③ Docomo API(知識Q&A)から連想されるURLが返却される
④ Google App Scriptにて結果を整形してLineにメッセージを返却する
このように、Line Bot、Google App Script、Docomo APIを連携させることで、アプリケーションを作成していきます。
ソースコード
Google App Scriptのコードです。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | // トークンの設定 var channel_access_token = "★LINEのアクセストークン★"; var APIKEY   = "★Docomo APIキー★"; // LineBotからのメッセージ受信 function doPost(e) { var events = JSON.parse(e.postData.contents).events;   events.forEach(function(event) {     if(event.type == "message"){     if (event.message.type == 'text'){         /* テキスト */          message = getDocomoQAMessage(event.message.text)       } else if (event.message.type == 'image'){         /* イメージ */        }       lineReply(event,message);     }     else if(event.type == "follow"){       /* 友だち追加・ブロック解除 */      }     else if(event.type == "unfollow"){       /* ブロック */      }   }); } // Docomo APIの知識Q&Aに問い合わせる function getDocomoQAMessage(mes) {   var q = mes;   var url = 'https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask' + '?q=' + q + '&APIKEY=' + APIKEY;   var response = UrlFetchApp.fetch(url, {'method':'get'});   // ドコモ知識Q&Aにメッセージを投げる   var jsonData = JSON.parse(response.getContentText());   var intNum = Object.keys(jsonData.answers).length   Logger.log(intNum);   var message;   if(intNum == 0) {      message = "その言葉ないクマー。別な言葉で教えてクマ";   }   else{      Logger.log(jsonData.answers[0].answerText);      Logger.log(jsonData.answers[0].linkText);      Logger.log(jsonData.answers[0].linkUrl);      message  = "「" + mes + "」" + "で連想されるURLクマ"      message += "\n\n"      if (intNum>3) {        intNum=3      }      for(i=0;i<intNum;i++){          message += (i+1) + "件目クマ"          message += "\n"          message += jsonData.answers[i].answerText          message += "\n\n"          message += jsonData.answers[i].linkText          message += "\n\n"          message += jsonData.answers[i].linkUrl          message += "\n\n"      }   }   Logger.log(message)   return message; } // LineBotへメッセージを返却 function lineReply(event,message) {    var postData = {     "replyToken" : event.replyToken,     "messages" : [       {         "type" : "text",         "text" : message       }     ]   };   var options = {     "method" : "post",     "headers" : {       "Content-Type" : "application/json",       "Authorization" : "Bearer " + channel_access_token     },     "payload" : JSON.stringify(postData)   };   UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options); } | 
ソースコードの詳細
トークンの設定
| 1 2 3 | // トークンの設定 var channel_access_token = "★LINEのアクセストークン★"; var APIKEY   = "★Docomo APIキー★"; | 
★の箇所にLineのアクセストークンとDocomoのAPIキーを設定してください
LineBotからのメッセージ受信
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // LineBotからのメッセージ受信 function doPost(e) { var events = JSON.parse(e.postData.contents).events;   events.forEach(function(event) {     if(event.type == "message"){     if (event.message.type == 'text'){         /* テキスト */          message = getDocomoQAMessage(event.message.text)       } else if (event.message.type == 'image'){         /* イメージ */        }       lineReply(event,message);     }     else if(event.type == "follow"){       /* 友だち追加・ブロック解除 */      }     else if(event.type == "unfollow"){       /* ブロック */      }   }); } | 
今回対象となるのは、メッセージ且つテキストとなり、event.typeが"message"、event.message.typeは'text'です。その場合、Docomo APIの知識Q&Aに問い合わせるために専用の関数(getDocomoQAMessage)を起動します。
getDocomoQAMessage関数の引数として、Lineで受信したテキストの内容を指定しています。それ以外のメッセージについては何もしません。
Docomo APIの知識Q&Aに問い合わせる
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // Docomo APIの知識Q&Aに問い合わせる function getDocomoQAMessage(mes) {   var q = mes;   var url = 'https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask' + '?q=' + q + '&APIKEY=' + APIKEY;   var response = UrlFetchApp.fetch(url, {'method':'get'});   // ドコモ知識Q&Aにメッセージを投げる   var jsonData = JSON.parse(response.getContentText());   var intNum = Object.keys(jsonData.answers).length   Logger.log(intNum);   var message;   if(intNum == 0) {      message = "その言葉ないクマー。別な言葉で教えてクマ";   }   else{      Logger.log(jsonData.answers[0].answerText);      Logger.log(jsonData.answers[0].linkText);      Logger.log(jsonData.answers[0].linkUrl);      message  = "「" + mes + "」" + "で連想されるURLクマ"      message += "\n\n"      if (intNum>3) {        intNum=3      }      for(i=0;i<intNum;i++){          message += (i+1) + "件目クマ"          message += "\n"          message += jsonData.answers[i].answerText          message += "\n\n"          message += jsonData.answers[i].linkText          message += "\n\n"          message += jsonData.answers[i].linkUrl          message += "\n\n"      }   }   Logger.log(message)   return message; } | 
クエリーはLineより受信したテキストそのままを入力しています。
0件の場合はその言葉は無かったというコメントを返却して終了します。1件以上の場合は知識Q&Aより受信したメッセージを多少加工して返却します。
通常では最大5件まで情報をもらえますが、長文となってしまうため最大3件までにしています。
LineBotへメッセージを返却
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // LineBotへメッセージを返却 function lineReply(event,message) {    var postData = {     "replyToken" : event.replyToken,     "messages" : [       {         "type" : "text",         "text" : message       }     ]   };   var options = {     "method" : "post",     "headers" : {       "Content-Type" : "application/json",       "Authorization" : "Bearer " + channel_access_token     },     "payload" : JSON.stringify(postData)   };   UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options); } | 
UrlFetchApp.fetch関数を使用することにより、LineBotに返却することが出来ます。
以外と簡単だったのではないでしょうか?
次回から知識Q&A以外でもいろいろ試してみます。