AWS LambdaとDocomoの雑談対話APIを連携させてLINE BOT APIと会話する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、せーのです。 今日は前回まででユーザ管理が出来るようになったLINE BOTを使用して会話をしてみようと思います。

雑談対話API

現在作ったLINE BOT「くらめそちゃん」はDevelopers.ioの新着記事が届くと通知してくれる、という機能を持たせてあります。また複数人にそれぞれ届けるように友達になったユーザーのMIDをDynamoDBに入れて保管しています。
先日このBOTを社内にて公開した所「話しかけても何も返ってこないからつまんない」というフィードバックを受けまして、オウム返しするのも何かな、と思い雑談機能をつけることにしました。

雑談機能にはDocomoの公開している「雑談対話API」を使用します。これはいい感じに話しかけるといい感じに返してくれる、というとても便利なAPIです。なぜかしりとり機能までついています!SDKはAndroid, iOS, Javaがあるようですが今回はNode.jsで作っているのでREST APIをそのまま使用してみたいと思います。

雑談対話APIのリクエスト部分は

  • URL: https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue
  • クエリ: API KEY(DocomoにDeveloper登録してこのAPIを使用登録するともらえる)
  • method: POST
  • ヘッダ: Content-typeにapplication/jsonを指定

body部分 - URLを参照

やってみる

仕様を決める

雑談APIが連続した会話として成立するにはREST APIのレスポンスに含まれる「context」と「mode」というのを次のリクエスト時に含めればいいそうです。なので

  • 通常の会話がきたときにMIDを元にDynamoDBをgetItemする
  • contextとmodeという項目があるかどうかをチェック
  • あればそれを含めて会話内容を雑談対話APIに投げる
  • レスポンスに含まれているcontextとmodeを使ってDynamoDBを上書きする
  • 対象のMIDに対してレスポンス内容を送る

という感じの仕様にしました。

実装

今回はそんなに難しくありません。基本的な仕様や設定、変数は前回の記事を参照してください。

まずはdocomoのAPIに送る部分を書きます。

var APIKEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

var docomo_options = {
    url: 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY=' + APIKEY,
    headers: {
        'Content-Type': 'application/json'
    },
    body: "",
    json: true
};

リクエスト内容がtoType:1(テキスト)の場合にMIDを元にしてDynamoDBを検索します。

var usermid = event.body.result[0].content.from;
//会話の場合はcontextとmodeを引き継ぐ
if (event.body.result[0].content.toType == 1){
    dbparams.Key = {
            mid: usermid
        };
    dynamo.getItem(dbparams, function(err, data) {
            if (err) {
                console.log(err, err.stack);
            } else {
                console.log('get item from DynamoDB.');

検索した結果contextとmodeがあればそれを含めてDocomo APIになげます。

//contextがあるかどうかチェック
                        var body = {
                         "utt":event.msg,
                         "user":data.Item.mid,
                         "nickname":data.Item.name,
                         "t": "30"
                        };
                        if (data.Item.context){
                            body.context = data.Item.context;
                            body.mode = data.Item.mode;
                        }
                        body.utt = event.body.result[0].content.text;

                        docomo_options.body = body;
                        request.post(docomo_options, function (error, response, ret) {
                          if (!error) {
                            console.log(ret);

返ってきたレスポンスのうちcontextとmodeをDynamoDBに保管します。

//DynamoDBに入れる
var UpdateDBparams = {
    TableName: 'linebotusers',
    Item: {
        "mid": usermid,
        "name": data.Item.name,
        "context": ret.context,
        "mode": ret.mode
    }
};
console.log('put to DynamoDB.');
dynamo.putItem(UpdateDBparams, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {

MID宛にLINEを返します。Lambdaの場合、連続して呼ぶと前回のFunctionの変数が残っている場合がありますのでtoの変数を一回初期化してからMIDをpushします。

senddata.to = [];
senddata.to.push(usermid);
senddata.content.text = ret.utt;
sendOptions.body = senddata;

request.post(sendOptions, function(error, response, body){
    if (!error) {
        console.log(JSON.stringify(response));
        console.log(JSON.stringify(body));
        console.log('send to LINE.');

        context.succeed('done.');

    } else {
        console.log('error: ' + JSON.stringify(error));
    }
});

これで会話できるようになりました。やってみましょう。

line_chat1

誤字があってもなんなく読みこなしているようです。ただあまり気持ちを汲んだ応対にはなっていないようです。もう少し優しいといいんですが。。。

なお、標準機能であるしりとりもできます。

line_chat3

line_chat2

まとめ

いかがでしたでしょうか。これといって役に立つかと言われると微妙ですが、位置情報や誕生日、年齢等パーソナルな情報をリクエストに加えるとそれに応じた会話が成立するようなので、そこを突き詰めていくと面白いかもしれません。何より暇つぶしになります。みなさんも是非やってみてください。

参考URL