Facebook Messenger API + Flask 備忘録 [導入編]

Facebook Graph API の一部である [Facebook Messenger Platform](https://developers.facebook.com/docs/messenger-platform/) の使い方メモ

- FBアプリを作り、自分が admin になっている FBページに紐付けて、様々なメッセージ送信が可能
- 直接POSTリクエストでも送信できるが、Webhook 機能があるので、PHP や Flask などの別サーバーにおいたプログラムとリンクして高度な処理が可能
- **予め Facebook for Developers で登録した admin, developer, tester しか使えない。**また、友達でない人のアプリへの追加は不可。一般公開して誰もが使えるようにするためには、Review 申請をして審査に通る必要あり。
- Flask アプリは Heroku (USAリージョン) と AWS EC2 (シンガポールリージョン) において試してみたが、AWS の方がレスポンスが速い。
- NLP機能もあるが、日本語・タイ語などは未対応 (2020-12)

# 初期設定

[https://developers.facebook.com/apps/](https://developers.facebook.com/apps/) から `Create App` でアプリを作成


What do you need your app to do? は **Manage Business Integrations** を選んだが、**Something Else** でも良さそう

**App Display Name** を入れて、`Create App`

![Screen Shot 2020-12-12 at 3.38.12 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/bf3a6030-7658-c37e-35be-d7133fda9ef2.png)

**Add Products** がたくさん出てくるが、とりあえず **Messenger** だけ選んで追加

![Screen Shot 2020-12-12 at 3.40.11 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/89726a88-79d1-5f5d-baa5-a5b12beb6852.png)

真ん中あたりの **Access Tokens** で、連携するFacebookページを追加。**Add or Remove Pages** で
自分が admin のページ一覧が出るので選択。

![Screen Shot 2020-12-12 at 3.41.50 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/fdc27abf-8d92-e548-659f-7759d2b81c01.png)

ページが登録されたら、右の **Generate Token** でアクセストークンを発行し、記録しておく。とりあえず環境変数 `.env` に保存。

これは Facebook Graph API を通してリクエストを送る時にパラメタとして毎回必ず添付する必要がある。めっちゃ長い。

![Screen Shot 2020-12-12 at 3.47.50 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/39364916-f358-f3a4-593d-3bdca064c109.png)

次に **Webhook** の設定。**Callback URL** は Flask アプリのコールバックプログラムがあるURLを指定、HTTP は不可なので、AWS EC2インスタンスのIPアドレスをそのまま使うことはできない（EC2のHTTPS化は別記載）。Heroku にデプロイするのなら HTTPS通信が可能。

URLは `https://.../callback` と設定した。ここに記入する **Verify Token** は Facebook 側からリクエストを送って返事がくるかどうかのテストをするためのものであり、なんでも良い。とりあえず `test` としておき、`.env` に `VERIFY_TOKEN=test` と保存したが、個人用ならそのままプログラム内にハードコーディングしてもいいかもしれない。プログラムが正常なら、**Verify and Save** できる。

![Screen Shot 2020-12-12 at 3.52.51 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/3771cbe1-1251-b161-8024-31d8fc1019ea.png)

ここで、Flask 側のプログラムは以下。このテスト用のリクエストは **GET** メソッドである。実際のコールバック関数となる `'POST'` の部分は後で追記。

~~~python3
import os
from flask import Flask, request
from dotenv import load_dotenv
load_dotenv() # 環境変数ファイル .env の読み込み
VERIFY_TOKEN = os.getenv('VERIFY_TOKEN')

@app.route('/callback', methods=['GET', 'POST'])
def receive_message():
    if request.args.get("hub.verify_token") == VERIFY_TOKEN:
        return request.args.get("hub.challenge")
    else:
        return 'ちがうよ'
~~~

リクエストにどんなパラメータがあるかは、[ここ](https://developers.facebook.com/docs/graph-api/webhooks/getting-started/)を参照。

要するに、送られてきた `hub.verify_token` の値をチェックし、同じならば `hub.challenge` の値を返しているだけ。ブラウザのURLバーに

`https://.../callback?hub.verify_token=test&hub.challenge=SUCCESS`

と入力して SUCCESS と表示されればOK

Webhook の登録が完了したら、今度は **Add Subscription** で使う API のタイプを選択。多すぎて違いがわからない ([ここ](https://developers.facebook.com/docs/messenger-platform/webhook)を参照) が、とりあえず **messages**, **message_deliveries**, **messaging_postbacks** を選ぶ。必要ならば後でいくらでも追加できる。

![Screen Shot 2020-12-12 at 4.19.55 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/6a5c14ff-cbb3-13fd-bba0-bbb80d2afc41.png)

![Screen Shot 2020-12-12 at 4.22.38 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/c6da8f12-cad7-fc24-3a2e-e1ec80cc9647.png)

この後自分が管理しているFBページにいき、Page Settings > Advanced Messaging > Connected Apps のところに登録したアプリがあればOK。

返信用の Python プログラム実装は次回

[実装編 1](https://qiita.com/nozomiyamada/items/12a9ec21059e9955de09)