SkypeとチャットAIのGateWayを作ってみた。

昨今チャットボットが流行っているが、今度はSkypeで・・・という要望を受けた。

AIエンジンは既にRestAPIで持っている。問題はSkypeとAIの仲介役をどう実現するかだ。
手探りであったがどうやら「Bot Framework REST APIs」なるもので実現できそうだ。


ざっくり構成はこんな形だ。
1.PNG


次のような順で解説する。尚、AIは単純なRestAPIなので省く。
(1)GateWay Server 構築
(2)Azure Bot Frameworkの設定


(1)GateWay Server 構築
・まずBotFrameworkからのイベント通知はWebhookなので受け取れる口を準備する。
 Https対応必須なのでHAProxyやspring-bootなどで対応する。
 FireWallの口開けも忘れずに。
 今回はJava+HAProxyで対応した。中身についてはAzureからきた質問をAIにRestリクエスト
 で流す。回答はWebhookで連携されるので、こいつをBotFrameworkにRestリクエストで返すだけだ。実際はAIエンジン用のユーザ管理などやっているが、今回の記事には関係ないことなので省く。


(2)Azure Bot Frameworkの設定
・ここが今回のメインになる。
 Azure Portalから設定する。
 BOTの実現方法にはAzure上にアプリを配置する方法もあるようだが、今回はアプリは別鯖に用意 してWebhookだけかけてもらうこととする。(過去資材を流用したらこうなっただけで、特段お勧めなわけではない。)

 1)BotChannelの作成
選んでいくだけだ。
2.PNG

3.PNG

4.PNG

Botの名前やサブスクリプション方法、WebhookをかけてもらうエンドポイントURLなどを入力する。
5.PNG

2)Channel設定
作ったBOTを選択
6.PNG

7.PNG

自前のGateWayServerからBotFrameworkに回答をRestリクエストするには、認証のためのアクセストークンが必要だ。こいつはRestAPIで発行可能だが、そのためにはアプリケーションIDとシークレットキーが必要になる。それを下記の画面で取得しておく。これらは永久に利用できるようだ。(ただし、アクセストークンは時間限定なので期限切れになる前に再発行する仕組みをGateWayServer側に作りこんでおく必要はある。)
8.PNG

BOTにデフォルトで紐付けされているチャンネルは、Webページ埋め込みパーツ用のみである。
ここにSkypeチャンネルを追加する。(正確にはSkypeには無料で利用できる一般消費者向けとSkype for Businessのエンタープライズ向けがある。この記事で扱うのは前者である。)
9.PNG

10.PNG

作ったチャンネルの動作確認
11.PNG

12.PNG

Skypeが開くので発話してWebhookが飛んでくれば問題なく動いている。
13.PNG


2018/4/10追記
Skypeに送れるメッセージを抜粋で紹介。詳しくはー>Bot Framework REST APIs

※前段階としてACCESS_TOKENを取得しておく必要がある。
 AzureサイトからBOT作成時に取得した
 ・アプリケーションID (ApplicationId)
 ・アプリケーションシークレット (ApplicationSecret)
 を用いてRestAPIをたたくことで取得できる。有効期限は1時間のもよう。
haml:Header
POST https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

BODY
grant_type=client_credentials&client_id=<ApplicationId>&client_secret=<ApplicationSecret>&scope=https%3A%2F%2Fapi.botframework.com%2F.default

1.URLリンク
 テキストメッセージ中に特殊文として埋め込める。

Header
POST https://smba.trafficmanager.net/apis/v3/conversations/<conversationId>/activities/<replyTokenId>
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
//www.google.co.jp/)めっせーじ```
2.ボタン付きテンプレート
 以下のJSONでリクエスト

```haml:Header
POST https://smba.trafficmanager.net/apis/v3/conversations/<conversationId>/activities/<replyTokenId>
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
JSON
{
    "type": "message",
    "from": {
        "id": "28:bdbc4595-004c-41a9-af22-1bf2b48ab542",
        "name": "cotohaBotPOC"
    },
    "conversation": {
        "id": "29:1nMbiqCmbifApQ_B6qVcx_ydAvvdO4jlhpLEyJwSvy3w"
    },
    "recipient": {
        "id": "29:1nMbiqCmbifApQ_B6qVcx_ydAvvdO4jlhpLEyJwSvy3w",
        "name": "yuka toyoda"
    },
    "attachments": [
        {
            "contentType": "application/vnd.microsoft.card.hero",
            "content": {
                "title": "title",
                "subtitle": "subtitle",
                "images": [
                    {
                        "url": "画像パス、URL"
                    }
                ],
                "buttons": [
                    {
                        "type": "imBack",
                        "title": "button1",
                        "value": "button1"
                    },
                    {
                        "type": "openUrl",
                        "title": "button1",
                        "value": "任意のURL"
                    }
                ]
            }
        }
    ]
}

表示例:
1.PNG

3.画像付きボタン(画像小)
 以下のJSONでリクエスト

Header
POST https://smba.trafficmanager.net/apis/v3/conversations/<conversationId>/activities/<replyTokenId>
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
JSON
{
    "type": "message",
    "from": {
        "id": "28:bdbc4595-004c-41a9-af22-1bf2b48ab542",
        "name": "cotohaBotPOC"
    },
    "conversation": {
        "id": "29:1nMbiqCmbifApQ_B6qVcx_ydAvvdO4jlhpLEyJwSvy3w"
    },
    "recipient": {
        "id": "29:1nMbiqCmbifApQ_B6qVcx_ydAvvdO4jlhpLEyJwSvy3w",
        "name": "yuka toyoda"
    },
    "attachments": [
        {
            "contentType": "application/vnd.microsoft.card.thumbnail",
            "content": {
                "title": "title",
                "subtitle": "subtitle",
                "images": [
                    {
                        "url": "画像パス、URL"
                    }
                ],
                "buttons": [
                    {
                        "type": "openUrl",
                        "title": "button1",
                        "value": "任意のURL"
                    },
                    {
                        "type": "openUrl",
                        "title": "button1",
                        "value": "任意のURL"
                    }
                ]
            }
        }
    ]
}

表示例:
2.PNG

3.サジェスト
 以下のJSONでリクエスト

Header
POST https://smba.trafficmanager.net/apis/v3/conversations/<conversationId>/activities/<replyTokenId>
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
JSON
{
    "type": "message",
    "from": {
        "id": "12345678",
        "name": "sender's name"
    },
    "conversation": {
        "id": "abcd1234",
        "name": "conversation's name"
   },
   "recipient": {
        "id": "1234abcd",
        "name": "recipient's name"
    },
    "text": "I have colors in mind, but need your help to choose the best one.",
    "inputHint": "expectingInput",
    "suggestedActions": {
        "actions": [
            {
                "type": "imBack",
                "title": "Blue",
                "value": "Blue"
            },
            {
                "type": "imBack",
                "title": "Red",
                "value": "Red"
            },
            {
                "type": "imBack",
                "title": "Green",
                "value": "Green"
            }
        ]
    },
    "replyToId": "5d5cdc723"
}

表示例:
3.PNG


まとめ

とりあえずAzurePortalでの解説になっているが、時間を見てアクセストークン発行や各メッセージのRest仕様について追記していきたい。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.