Bot Framework Composer でボット開発 : その 10 OAuth カードとアクセストークン

[前回](https://qiita.com/kenakamu/items/c0bce7ff54711ff53cbe)の記事では、ボットを Azure に展開して、LINE クライアントなどに公開しました。今回は Azure に展開した後に使える機能として認証を見ていきます。

# OAuth 利用の準備

Bot Framework Composer は「ボットチャンネル登録」が提供する OAuth 認証機能と連携します。
OAuth 2.0 を実装しているサービスが対象となるため、例えば Qiita のように独自実装しているサービスでは、残念ながらこの機能は使えません。そこで今回はインスタグラム API を使ってみます。

## Facebook アプリの作成

詳細は、[公式:スタートアップガイド](https://developers.facebook.com/docs/instagram-basic-display-api/getting-started)を参照してください。ここでは簡単に必要な箇所だけピックアップしています。

1\. [Facebook 開発者ポータル](https://developers.facebook.com/) より開発者登録をして、アプリを作成。任意の名前をつける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/caba9014-fc7a-9393-03e4-629e522bc882.png)

2\. Instagram を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/3202a940-4d99-c14f-b239-587a64c96bda.png)

3\.「Basic Display」より、「リダイレクト URI」に「https://token.botframework.com/.auth/web/redirect」を設定。アプリ ID とシークレットは後程使うので保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/75d9d461-2548-1b80-2909-6fd47401e4b0.png)

4\.「承認を取り消す」と「データの削除リクエスト」にそれぞれ適当なアドレスを追加して「変更を保存」をクリック。

5\. 役割より Instagram テスターを追加。自分のアカウントを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/3b32b320-5675-70d7-f7e2-c3994f8754ed.png)

6\. 自身のインスタアカウントにログインして、プロファイルの編集 | Apps and Websites よりテスターの招待を承諾。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/4224d34b-b8c7-3721-d8ed-fd3dc7b97e28.png)

## ボットチャネル登録の設定

1\. [Azure ポータル](https://portal.azure.com) より、ボット公開時に作成した「ボットチャンネル登録」を開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/74d64356-d18e-2c17-8c1e-21e42f6c22a8.png)

2\.「設定」より OAuth 接続設定で「設定の追加」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/689f4f6a-7330-0d26-fea5-6b6128be169b.png)

3\. サービスプロバイダーより「Instagram」を選択。スコープに user_profile,user_media を設定して「保存」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/4960276b-92f0-7037-b45e-6992c1fc0c4b.png)

## Bot Framework Composer の設定

最後に Composer での設定です。

設定メニューより MicrosoftAppId と MicrosoftAppPassword を設定。展開で使ったものをそのまま指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/61546200-f5f6-c240-26cb-b28631becd08.png)

# ダイアログの追加

準備ができたので、ダイアログを追加していきます。OAuth に利用できる OAuth Login アクションを使います。

## 画像の取得

まずは画像を取得して表示してみましょう。

1\. 新規ダイアログより「GetPictures」ダイアログを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ea52b8ea-2d1f-13de-fdb5-79ae15ab37fa.png)

2\. BeginDialog トリガーに「OAuth login」アクションを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/9a96b312-92e5-7f15-f8cb-7def86a8337a.png)

3\. 接続名は先ほど登録した認証設定と同じものを指定。取得したトークンを user.oauth に保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/94cd1efa-8535-e195-2d83-292d8bfd8997.png)

4\. 続けて自身の id を取得するため HTTP 要求を追加。GET メソッドで ```https://graph.instagram.com/me?fields=id&access_token=${user.oauth.token}``` に送信し、結果を dialog.response に格納。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/452d1cd9-c167-c0f4-2d78-886c739cf995.png)

5\. さらに公開している写真の id を取得するため HTTP 要求を追加。GET メソッドで ```https://graph.instagram.com/${dialog.response.content.id}/media?access_token=${user.oauth.token}``` に送信し、結果を dialog.response に上書き格納。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/7ee3c7b8-c25f-ef75-bc40-ffc9d4b78d11.png)

6\. 写真の情報は data プロパティに配列で返ってくるため、Loop 制御を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/09726790-7365-174c-0024-fc3bc3fd474b.png)

7\. ループの中で写真のアドレスを取得するため HTTP 要求を追加。GET メソッドで ```https://graph.instagram.com/${dialog.foreach.value.id}?fields=media_type,media_url,caption,thumbnail_url&access_token=${user.oauth.token}``` に送信し、結果を dialog.imageに格納。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/b137a9f6-0a95-3914-3225-bbbfda55c511.png)

8\. 直後にメッセージ送信アクションを追加して写真を返す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/8beb6e80-4a72-e95c-0d7c-729be29bab69.png)

9\. メインダイアログに GetPictures トリガーを追加。ダイアログ開始アクションで GetPictures ダイアログを開始。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/fdaa432f-9a39-fbcc-f20d-ab5686083c79.png)

10\. ボットを再起動してエミュレーターで検証。トリガーフレーズでログインを起動。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1631e02b-fabd-9dae-2bba-8d5875973848.png)

11\. インスタの認証画面が出るので認証を行う。認証完了後、コードを送るように言われるので、コードを送る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6bc144ce-f30a-9be2-37fe-18717d8c70b3.png)

12\. 画像が表示されることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/b9f506a8-982e-b75b-fe80-8cf7c0238362.png)

## 動画の処理

現在の処理では動画も画像も同じように処理され、結果として動画は表示されません。そこで LG 関数を使って処理を追加してみます。

1\. Bot Response の Get Pictures に関数を 2 つ追加。

```shell
# GetPictureCard ()
[HeroCard
  title=${if(dialog.image.content.caption==null,'',dialog.image.content.caption)}
  image=${dialog.image.content.media_url}
]

# GetVideoCard ()
[VideoCard
  title=${if(dialog.image.content.caption==null,'',dialog.image.content.caption)}
  image=${dialog.image.content.thumbnail_url}
  media=${dialog.image.content.media_url}
]
```

2\. もともとある関数の中身を以下に差し替え。

```shell
- IF: ${dialog.image.content.media_type== 'IMAGE'}
    - ${GetPictureCard()}
- ELSE:
   - ${GetVideoCard()}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/95d01b73-1927-4169-0a28-c648bda7c18b.png)

3\. ボットを再起動してエミュレーターで検証。ビデオはビデオカードで表示されることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/7ca300f2-faee-ca03-7f89-df25d8483cae.png)

# OAuth カードの動作

エミュレーターで「Restart Conversation - Same User ID」を使うと、トークンが有効な間は認証が聞かれません。内部的にトークンのチェックと、可能であればリフレッシュトークンでアクセストークンを更新しているためです。

# まとめ

今回は OAuth を使ったアクセストークンの取得と HTTP 要求との連携を試しました。これでより幅広いサービスと連携できます。

[次の記事へ](https://qiita.com/kenakamu/items/a9bb3530c76ce3daaa0e)
[目次へ戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883#bot-framework-composer)