Microsoft Bot Frameworkには、ボットのインターフェースとしてSkype, Slack, Facebook, Teamsなどの他に、単純なREST APIとして呼べるDirect Lineが用意されています。
Second Lifeのオブジェクトの周りで喋ったら反応するボットのスクリプトを書いたついでに、現時点でのDirect Lineの使い方を整理してみました。
サーバ側の準備
- Botを稼働させるサーバを用意
- インターネットからアクセスできれば(理論上は)何でも良い
- 特にこだわりがなければAzureにした方が楽
- Botサーバ部分の開発
- ローカルでテスト
- Bot Emulatorをインストール
-
ここに書かれている通りに、ngrokを連携させておく
- これを怠るとサーバにデプロイした後の確認でハマる
- サーバにデプロイ
- ボットとして登録
-
Bot Framework Portalにログインし、こちらの手順の通りに操作
- Application InsightsやAnalytics(分析)の設定はスキップで良い
- C#.NETやNode.jsで作っている人は設定ファイルや環境変数の修正を忘れずに
-
Bot Framework Portalにログインし、こちらの手順の通りに操作
- Direct Lineチャネルをボット定義に追加
- こちらの手順の通りに操作
- 実はデフォルトで作られているWeb Chatでも良かったりする...
REST呼び出しの準備
マニュアル
Build a client
が、ボットクライアントを作る際に必要なAPIの記事となります。その直前のBuild a bot
は、C#やNode.jsのSDKを使わずに、自力でチャネルやMicrosoftのボットサービスと連携させる際に必要となる記事ですので、大多数のライトユーザは読む必要がありません。
記事の場所がわかりづらいので、マニュアルのツリーの画面キャプチャを貼っておきます。
WebSocketを使わない単純なHTTP呼び出しなら、以下のマニュアルで事足ります。
- 認証の方法
- 会話の開始
- ボットにメッセージを送信
- ボットからのメッセージを受信
- 会話の終了
- APIリファレンス
以下、2017年10月現在のDirect Line 3.0を前提として説明します。
Secret Keyの取得
Bot Framework PortalでCHANNELS
を開き、Direct Lineチャネルの行のEdit
をクリックします。下のような画面が出てきたShow
をクリックし、出てきた文字列をコピーして、どこかに保存しておきます。(以下、SECRET_KEYとします)
2個ありますが、どちらを使っても構いません(なぜ2個あるかは謎)。
RESTの呼び出し方法
会話の開始
初回のみ実行します。
リクエスト
- メソッド:
POST
- URL:
https://directline.botframework.com/v3/directline/conversations
- ヘッダ:
-
Authorization
:Bearer SECRET_KEY
-
- 本文(Body): なし
レスポンス
- ステータスコード:
201
- 本文: 今後必要なのは以下のみ
-
conversationId
(以下、CONVERSATION_IDとします) -
token
(以下、TOKEN_STRINGとします) -
expires_in
: トークンの期限が切れる秒数(2017年10月現在は1800
)
-
{
"conversationId": "1BLDHwkJbAI9OaQ7kaawFy",
"token": "QXnIh2YOvyA.dAA.MQBCAEwARABIAHcAawBKAGIAQQBJADkATwBhAFEANwBrAGEAYQB3AEYAeQA.0YpbcG5D0wE.W_6rw0NK2ug.3kmUW-UAyM6T2eXX_VyU8UM4IVM36fAlBP_Vo43nQfs",
"expires_in": 1800,
"streamUrl": "wss://directline.botframework.com/v3/directline/conversations/1BLDHwkJbAI9OaQ7kaawFy/stream?watermark=-&t=QXnIh2YOvyA.dAA.MQBCAEwARABIAHcAawBKAGIAQQBJADkATwBhAFEANwBrAGEAYQB3AEYAeQA.0Zw8Y2pD0wE.bzda8JskN9c.8lxihTYtXiuXh3drL_O8xa8Ml6atIH4p4J7VS2aUB6o",
"referenceGrammarId": "1799972b-e9cb-5455-89fc-220485899d8a"
}
ボットにメッセージを送信
リクエスト
- メソッド:
POST
- URL:
https://directline.botframework.com/v3/directline/conversations/CONVERSATION_ID/activities
- ヘッダ:
-
Authorization
:Bearer TOKEN_STRING
-
Content-Type
:application/json
-
- 本文(Body):
-
type
:message
-
id
: クライアントの識別子(何でも良い?) -
text
: ボットに送信する文字列
-
{
"type": "message",
"from": {
"id": "user1"
},
"text": "hello"
}
レスポンス
- ステータスコード:
200
- 本文:
id
のみ。今後の操作には不要な情報
ボットからメッセージを受信
メッセージの送信と1対1の関係というわけではなく、このAPIを呼び出したら、(watermark
以降)API呼び出し時点までの全ての会話ログを返してきます。会話ログには、ボットの発言だけでなく、こちらから送信したメッセージも含まれます。
リクエスト
- メソッド:
GET
- URL:
https://directline.botframework.com/v3/directline/conversations/CONVERSATION_ID/activities?watermark=WATERMARK_STRING
- ヘッダ:
-
Authorization
:Bearer TOKEN_STRING
-
レスポンス
- ステータスコード:
200
- 本文: (主に必要なもののみ抜粋)
-
activities
-
from
-id
: 発言者 -
text
: 受信した文字列
-
watermark
-
前回取得したwatermark
をWATERMARK_STRINGの位置に指定すると、未読のアクティビティのみが取得できます。初回の呼び出しでは?watermark=
の部分は不要です。?watermark=0
でも良いです。
会話の終了
放っておいてもexpires_in
の秒数が経過すると会話は終了しますし、ボットのサーバ側から会話を終了させることもできますが、こちらから会話を終了する手段も用意されています。
リクエスト
- メソッド:
POST
- URL:
https://directline.botframework.com/v3/directline/conversations/CONVERSATION_ID/activities
- ヘッダ:
-
Authorization
:Bearer TOKEN_STRING
-
Content-Type
:application/json
-
- 本文(Body):
-
type
:endOfConversation
-
id
: クライアントの識別子(何でも良い?)
-
{
"type": "endOfConversation",
"from": {
"id": "user1"
}
}
レスポンス
- ステータスコード:
200
- 本文:
id
のみ。今後の操作には不要な情報
例外処理
ステータスコードが400番台と500番台は、エラー扱いとなります。
- 本文(Body):
-
error
-
code
: エラー種別 -
message
: 詳細なメッセージ
-
-
{
"error": {
"code": "BadArgument",
"message": "Security token not valid for this conversation"
}
}
会話の延長
expires_in
の時間が経過すると、直前までどんなに激しい会話の応酬がされていても、ボットは会話を終了してしまいます。それを防ぐために、会話が終了してしまう前にトークンを更新する必要があります。
リクエスト
- メソッド:
POST
- URL:
https://directline.botframework.com/v3/directline/tokens/refresh
- ヘッダ:
-
Authorization
:Bearer TOKEN_STRING
-
- 本文(Body): なし
レスポンス
- ステータスコード:
201
- 本文: 今後必要なのは以下のみ
conversationId
token
expires_in
以後は、レスポンスに記載されたconversationId
とtoken
を使うようにします。