LoginSignup
9
7

More than 5 years have passed since last update.

AWS API GatewayとAWS LambdaとWit.aiで自動応答 Facebook Botを作成する

Last updated at Posted at 2016-05-04

事前準備

Node.jsで、Wit.aiをテストする
http://qiita.com/akira-sasaki/items/72ab3d405a6f64942720

AWS API GatewayとAWS Lambdaで、HelloWorldを作成する
http://qiita.com/akira-sasaki/items/b9e8e8a0330818e3b71d

AWS API GatewayとAWS Lambdaで、Facebook Botを作成する
http://qiita.com/akira-sasaki/items/961cb7a1aa7386764863

Facebook Bot向けアプリをAWS Lambdaで実装する
http://qiita.com/akira-sasaki/items/cbb667653579db9743ec

Scriptの作成

index.js
'use strict';

var http = require ('https');
const Wit = require('node-wit').Wit;

var accessToken = "FacebookBot用のアクセストークン";
var clientTokenWIT = "Wit.ai用のクライアントトークン";
var sendingCount = 0;
var myContext;


exports.handler = function(event, context) {
    console.log('Received event:', JSON.stringify(event, null, 2));
    myContext = context;

    // Wit.aiのAction
    const actions = {
      say(sessionId, context, message, cb) {
        console.log(message);
        cb();
        sendMessage(sender, {text: message});
      },
      merge(sessionId, context, entities, message, cb) {
        cb(context);
      },
      error(sessionId, context, err) {
        console.log(err.message);
      },
    };

    // Wit.aiのインスタンス
    const client = new Wit(clientTokenWIT, actions);

    // パラメータチェック
    var entry = event.entry;
    if (!entry || entry.length === 0) {
        context.fail("invalid parameter");
        return;
    }

    // 各メッセージの処理
    for (var i = 0; i < entry.length; i++) {
        var messaging_events = entry[i].messaging;
        var timestamp = entry[i].time;
        for (var j = 0; j < messaging_events.length; j++) {
            var messaging = entry[i].messaging[j];
            var sender = messaging.sender.id;
            // メッセージ
            if (messaging.message && messaging.message.text) {
                var text = messaging.message.text;

                // 取得したメッセージをWit.aiに渡す
                var sessionContext = {};
                client.runActions(
                    "lamdba_test001", // the user's current session
                    text, // the user's message 
                    sessionContext, // the user's current session state
                    (error, context) => {
                    if (error) {
                        console.log('Oops! Got an error from Wit:', error);
                    } else {
                        console.log('Waiting for futher messages.');
                    }
                });

            }
        }
    }
    // context.done();
};

// メッセージ送信
function sendMessage(sender, messageData) {
    var json_data = {
        recipient: {id: sender},
        message: messageData
    };
    var post_data = JSON.stringify(json_data);
    console.log("* sendMessage *" + post_data);

    var post_options = {
        host: 'graph.facebook.com',
        port: '443',
        path: '/v2.6/me/messages?access_token='+accessToken,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(post_data)
        }
    };

    var post_req = http.request(post_options, function(res) {
        res.setEncoding('utf8');
        // res.on('data', function (chunk) {
        //     console.log('Response: ' + chunk);
        // });
        res.on('end', function () {
            // console.log('End');
            sendingCount -= 1;
            if (sendingCount === 0) {
                myContext.done();
            }
        });
    });

    post_req.on('error', function (e) {
        console.error('HTTP error: ' + e.message);
        sendingCount -= 1;
        if (sendingCount === 0) {
            myContext.done();
        }
    });

    // post the data
    post_req.write(post_data);
    post_req.end();
}

アップロードファイルの作成

  • index.js
  • node_modules/node-wit/

というフォルダ構成になっているので

$ zip -r lamdba.zip index.js node_modules/

を実行して、ZIP形式でパッケージにまとめる。

アップロード

lamdba.zipをアップロードする。

lam001.png

lam002.png

lam003.png

It looks like your Lambda function "FacebookBotCallback" is unable to be edited inline, so you need to re-upload any changes. This may be because your file is too large or your zip file contains more than one file to edit. However, you can still invoke your function right now.

というメッセージが表示されますが、問題なくアップロードされているはずです。

TEST

test001.png

テスト用のJSONを作成する。messaging.sender.idは、実在するIDにすれば、メッセージがそのIDに返信される。messaging.textは、Wit.aiで設定している「こんにちわ」にする。

Test用
{
  "object":"page",
  "entry":[
    {
      "id":1,
      "time":1457764198246,
      "messaging":[
        {
          "sender":{
            "id":111111111111
          },
          "recipient":{
            "id":1
          },
          "timestamp":1457764197627,
          "message":{
            "mid":"mid.1457764197618:41d102a3e1ae206a38",
            "seq":73,
            "text":"こんにちわ"
          }
        }
      ]
    }
  ]
}

test002.png

Timeoutの時間を10秒にしておく。

test003.png

Logで「こんにちわ!!」が返ってくれば、Wit.aiの結果が正常に取れたことになる。

test004.png

Facebookで実行

実行するとこんな感じ。

fbook001.png

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7