さて断捨離の季節です。これまで放置していたbotの供養をしたいとおもいます。今日は第1弾。ALISのコミュニティで可愛がってもらおうとおもって大昔につくったアリス娘がいます。
今回は彼女の御供養として彼女を赤裸々に公開しておきます。これをみればこのレベルのチャットボットが簡単につくれます。今回はLINEにしていますが、ここはDiscordでもALISでもTwitterでもなんでも対応可能です。
彼女はLineのbotです。Lineで接続すると彼女との会話がたのしみめました。
またALISの記事については秀逸でリクエストすると即座に結果を答えてくれます。トップ記事はなんだろうとおもったら彼女に聞けばよかったのです。また適当にALISの記事を選んでくれたりもします。
こちらから登録できます。1週間後に彼女の動作は停止します。
アリス娘はLine APIを経由して応答を行っています。Lineに送った質問はプログラムにおくられて処理が行われます。このときに、会話のハンドリングを扱っていたのがユーザーローカルのAIです。
なんと今をときめくクラウド企業のものではなく日本のAI専業の会社です。こちらの会社は基本的には業務向けのビジネスを中心におこなっていますが、無料で個人にもお試し程度で使えるAPIを公開してくれています。
特定の言葉がきたときは必要に応じたアクションを取りますが、キーワードがない問いかけの場合は全て、ユーザーローカルのAIに投げて答えをもらっています。
このbotはGASを用いてGoogleのプラットフォームにて動作させていました。LineのAPIがユーザーのインプットがきたら事前に登録してあるURLに投げます。その受け先をGoogleのGASで作っているわけです。
作成したころリサーチして一番よかったものです。時代が進んでいるので皆さんも少しさがしてみると違ういいものがあるかもしれません。ちょっとこの記事を作るにあたってググってみましたが、ユーザーローカルさんの情報はすくないかもですね。
さてコードはGASにJava Scriptクローンの Google Application Scriptにて記載します。下記がそのコードです。
このコードはデプロイしてWEB公開して使います。
POSTでLINEが投げかけをします。その情報は、e にはいってきますので、返答用のトークンとメッセージを取り出します。
とりだした言葉をif文で分岐して、 って とはいっていたら、 WikiPediaから回答をとってきたり、ALISの記事をALIS APIで取得します。
どこにも当てはまらない場合だけUSER LOCALのCHAT AIに渡して回答をもらうわけです。
回答は reply_messagesに格納し if文が終わった後にLINE MESSAGING APIに戻しています。
最初に取得したTOKENを添えて、どの問いかけへの回答かも明確にして返事をします。なので、間違って違う人に回答してしまうことがないわけですね。
var CHANNEL_ACCESS_TOKEN = LINEのアクセストークンを入れる;
var CHAT_BOT_ACCESS_TOKEN = ユーザーローカルのアクセストークンを入れる;
var line_endpoint = LINEのエンドポイント;
var chat_endpoint = ユーザーローカルのエンドポイント;
var simple_wikipedia_api = 'http://wikipedia.simpleapi.net/api';
function doPost(e) {
var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
if (typeof reply_token === 'undefined') {
return;
}
var user_message = JSON.parse(e.postData.contents).events[0].message.text;
var reply_messages = ['ごめん。わからなかった…'];
if (/って?$/.test(user_message)) {
var q = user_message.match(/(.*)って?$/)[1];
var url_and_body = getWikipediaUrlAndBody(q);
if (url_and_body !== null) {
reply_messages = [
'説明しよう! ' + q + 'とは!',
url_and_body.body.substr(0, 140) + '...',
'続きは',
url_and_body.url,
];
}
} else if(/(トップ|top)/.test(user_message)){
var url_and_body = getAlisTopArticle();
if (url_and_body !== null) {
reply_messages = [
'現在のトップ記事は' + '...\n\n' + url_and_body.url,
];
}
} else if(/(適当|random)/.test(user_message)){
var url_and_body = getRandomArticle();
if (url_and_body !== null) {
reply_messages = [
'これはどう?≈' + '...\n\n' + url_and_body.url,
];
}
}else if(/(コマンド|Command|command|こまんど|ヘルプ|help|Help|HELP)/.test(user_message)){
var url_and_body = getRandomArticle();
if (url_and_body !== null) {
reply_messages = ['トップ: ALISのトップ記事を紹介します\n適当:おもしろい記事をピックアップして紹介します'];
}
}else {
var res = UrlFetchApp.fetch(
chat_endpoint + '?key=' + encodeURIComponent(CHAT_BOT_ACCESS_TOKEN) + '&message=' + encodeURIComponent(user_message)
);
reply_messages = [JSON.parse(res).result];
}
var messages = reply_messages.map(function (v) {
return {'type': 'text', 'text': v};
});
UrlFetchApp.fetch(line_endpoint, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': reply_token,
'messages': messages,
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function getWikipediaUrlAndBody(q) {
var url = simple_wikipedia_api + '?keyword=' + encodeURIComponent(q) + '&output=json';
var res = JSON.parse(UrlFetchApp.fetch(url));
if (res !== null) {
return {'url':res[0].url, 'body': res[0].body};
} else {
return null;
}
}
//トップ記事の呼び出し
function getAlisTopArticle(){
var response = UrlFetchApp.fetch("https://alis.to/api/articles/popular?limit=1&page=1").getContentText();
var results = JSON.parse(response);
if (results !== null) {
var titleOverview=results["Items"][0]["title"]+"\n\n"+ results["Items"][0]["body"];
var topArticleUrl = 'https://alis.to/' + results["Items"][0]["user_id"] + '/articles/' + results["Items"][0]["article_id"];
return {'url':topArticleUrl, 'body': titleOverview};
} else {
return null;
}
}
//適当な記事をお勧め
function getRandomArticle(){
var response = UrlFetchApp.fetch("https://alis.to/api/articles/popular?limit=100&page=1").getContentText();
var results = JSON.parse(response);
var random = Math.floor(Math.random()*99)+10;
if (results !== null) {
var ArticleUrl = 'https://alis.to/' + results["Items"][random]["user_id"] + '/articles/' + results["Items"][random]["article_id"];
var titleOverview=results["Items"][random]["title"] +"\n\n"+ results["Items"][random]["body"];
return {'url':ArticleUrl, 'body': titleOverview};
} else {
return null;
}
}
1週間後にオペレーションを停止します。転生したら絶世の美女となって我々の元にあらわれるはず。