API Gateway + Lambda で Facebook bot を作ってみる


Facebook bot が作れるようになったので、早速エコーバックする bot を試してみました。

bot を作るには、Facebook ページとアプリを作成しておく必要があります。
facebook for developers の [QuickStart](https://developers.facebook.com/docs/messenger-platform/quickstart) に簡単な手順が書いてありますので、こちらに従って作成していきます。


基本方針としては、

- API Gateway + Lambda + Express で構築する
  - インスタンスを立てるのは面倒
  - リクエスト数が多くなければ初期コストは 0 で運用できる
  - 将来的な各種 AWS サービス連携を視野に入れられる

とし、[aglex](https://www.npmjs.com/package/aglex) を使って構築しました。

> aglex の詳細については、[aglex: API Gateway + Lambda + Express4 で サーバレス API を作成する](http://qiita.com/u-minor/items/42061564cdc0b145a221) を参照してください。

## Facebook ページの作成

右上のメニューから、新規に Facebook ページを作成します。
カテゴリー等の情報は、自分の好みに合わせて適切に設定してください。

![Facebook.png](https://qiita-image-store.s3.amazonaws.com/0/15611/29204146-d0d1-4036-c5ad-25c9955a3c98.png "Facebook.png")

既に Facebook ページを持っている場合は既存のページを使っても OK でしょう。 
以下の様な Facebook ページが作成できれば完了です。

![Testbot.png](https://qiita-image-store.s3.amazonaws.com/0/15611/58cfc218-7693-96b5-79b5-99023ff1b6ea.png "Testbot.png")

## Facebook アプリの作成

[facebook for developers](https://developers.facebook.com/) から、新規にアプリを作成します。
右上のメニューから「Add a New App」 を選択し、Website 用のアプリを作成していきます。

![All_Apps_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/d0497f79-26ce-e2ba-d420-17f924e6d98f.png "All_Apps_-_Facebook_for_Developers.png")

以下の様なアプリが作成できれば完了です。

![testbot_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/f75c5f1d-d2d1-d95f-44a3-15df6a6d7df8.png "testbot_-_Facebook_for_Developers.png")

## ページアクセストークン の生成

アプリから Messenger API を使うには、ページアクセストークンを生成しておく必要があります。
アプリのメニューで「Messenger」をクリックし、作成した Facebook ページを選択してトークンを生成し、コピーしておきます。

![testbot_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/ebe6b8c8-37b9-0840-bf87-a26c7b80a8ae.png "testbot_-_Facebook_for_Developers.png")

## Lambda 用 IAM ロールの作成

Lambda を実行するための IAM Role を作成します。
ローカルに `AssumeRolePolicy.json` を作成し、

```AssumeRolePolicy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

awscli を用いて IAM Role を作成します。

```
aws iam create-role --role-name lambda-facebook-testbot --assume-role-policy-document file://AssumeRolePolicy.json
```

> AWS Management Console 経由で作成しても OK です。

## API Gateway + Lambda の作成

[facebook-testbot](https://github.com/u-minor/facebook-testbot) を clone します。

```
git clone -b v0.1.0 git@github.com:u-minor/facebook-testbot.git
```

### 設定ファイルの準備

aglex 用設定ファイル aglex.yml.example を aglex-development.yml にコピーします。

Lambda 用の設定ファイル config/environment.yml.example を config/development.yml にコピーし、`facebook.pageAccessToken` に先ほど生成したページアクセストークンを設定、`facebook.verifyToken`
 に適当な文字列（`TESTBOTTOKEN`等）を設定します。

![development_yml_—__Users_minoru_workspace_facebook-testbot.png](https://qiita-image-store.s3.amazonaws.com/0/15611/55fd9874-1174-deaa-74b6-5f9ab2a690c1.png "development_yml_—__Users_minoru_workspace_facebook-testbot.png")

### npm パッケージのインストール
 
`npm install` で必要な関連パッケージをインストールします。

### Lambda function の登録

`gulp updateLambda --env=development` で Lambda function を登録します。

`gulp addLambdaPermission --env=development` で API Gateway から Lambda function を実行できるよう権限設定します。

### API Gateway の登録

`gulp updateApi --env=development` で API Gateway の設定を行います。

`gulp deployApi --env=development --stage=dev` で設定した API Gateway をデプロイします。

### API Gateway の動作確認

API Gateway をデプロイするとベース URL が決定します。AWS Management Console からも確認できます。

> `https://{API_ID}.execute-api.ap-northeast-1.amazonaws.com/{STAGE_NAME}` という形式になります。

API ID を確認した上で `https://{API_ID}.execute-api.ap-northeast-1.amazonaws.com/dev/webhook?hub.verify_token=TESTBOTTOKEN&hub.challenge=CHALLENGE` にアクセスし、「CHALLENGE」が返ってくれば成功です。

## webhook の登録

Facebook アプリの設定に戻り、Setup Webhooks をクリック、

![testbot_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/4b24453d-79db-ee30-35b5-fde59e3f1cec.png "testbot_-_Facebook_for_Developers.png")

作成した API のエンドポイントを入力します。

![testbot_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/25965ff2-9d29-1a3d-4230-df96941f8fe6.png "testbot_-_Facebook_for_Developers.png")

登録後に緑色の「Complete」が表示されれば、疎通確認は OK となります。

![testbot_-_Facebook_for_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/15611/af2935ea-9266-4dd2-9e0b-b92200110d1d.png "testbot_-_Facebook_for_Developers.png")

## bot の動作確認

作成した bot に対して、メッセージを送ってみます。

エコーバックされれば無事成功です。

![_2__Facebook.png](https://qiita-image-store.s3.amazonaws.com/0/15611/28cafefd-9462-a650-6dac-d074a5bb3725.png "_2__Facebook.png")

## 総括

今回はガイドに従って取得したメッセージをそのまま返す bot を作成しましたが、ユーザの入力したテキストがそのまま取得できますので、後は自由に処理してね、というシンプルな作りになっています。
Slack bot でも同じようなことが出来ますが、Facebook や LINE のような一般の人が使うメッセージングサービスの上で bot が作れるようになったのは極めて大きいですね。

また、Messenger アプリの対応はまだですが、Facebook ページの Messages からは QR コードに似た画像がダウンロードできるようになっており、簡単に bot を登録できるような仕組みが用意されるようです。

![_1__Testbot.png](https://qiita-image-store.s3.amazonaws.com/0/15611/61f110e7-df1a-cb5c-cd04-f1b5499e7c3d.png "_1__Testbot.png")

![_1__Testbot.png](https://qiita-image-store.s3.amazonaws.com/0/15611/c61354d3-e426-66df-6b4a-1d4a457bc835.png "_1__Testbot.png")

bot engine である wit.ai も試してみましたが、こちらも英語のみではあるものの、シンプルな作りで会話シーケンスを簡単に登録できるので、よく考えられていて面白いと感じました。

簡易なコマンドインターフェースとして扱うもよし、wit.ai のような簡易会話エンジンと連携させるもよし、機械学習による高度な AI を組み込むもよし。
bot をどのようにサービスで活用していくか、夢がいろいろ広がります。