Edited at

英語のドキュメントを読みたくない人の為のBot Framework入門(C#編)

More than 3 years have passed since last update.

 やや話題に乗り遅れた感がありますが、マイクロソフトがBuild2016でBot Frameworkを発表しましたね。これを使えば簡単にBotを作れるようになるそうです。ほー。

 BotといえばBombtterの印象しかない私ですが、いつの間にやら世間的には次のステージへ到達しているようですね。

 さて、このBot Frameworkですが触れ込み通り割と簡単にBotを作り始める事ができます。情報はまだ少ないですが公式のドキュメントがマイクロソフト製とは思えないくらい親切で充実しているので、これを読むだけなんとかなります。が、残念なことに現時点では英語しかありません。

 そ・こ・で

 せっかくなので、Bot Frameworkを使いたいけど公式ドキュメントは読みたくないぞ、という方向けに入門記事を書きたいと思います。パチパチ。

 記事を執筆中にBot Frameworkがv3へと更新されました。何てタイミングにやってんだこのヤロー。記事でもv3の内容を反映しました(スクショの取り直し面倒くせぇ)


目標

 オウム返し + αをする簡単なbotをBot Frameworkを使って作れるようにする。さらに、それを外部サービス(Facebook)と連携させてみる。


前提


  • C#の読み書きができる。

  • Visual Studioを使ったことがある。

 Bot FrameworkではC#とnode.jsが使えますが、この記事ではC# + Visual Studioを使います。

 SNSとの連携とAzureへのデプロイもやりますが、その都度解説するので前提にはしません。


準備


最新版のVisual Studioをインストール

 2015 Update3 が現在の最新です。個人利用ならCommunity版がタダで使えます(リンク)。

 インストールの際にカスタムインストールで"Microsoft Web Developer Tools"を入れてください。これがないとプロジェクトを作れません。

vs.png


マイクロソフトアカウントを作る

 マイクロソフトのサービスを使うので必須です。

※@outlook.com、@hotmail.comなどで終わるアカウントがあればそれが使えます。Gmailを使っていればそれと繋ぐこともできます。


Azureサブスクリプションに登録

 ホスティングの為に必要です。

 作り方はこちらの記事などを参考にしてください。

※クレジットカードが必須ですが、無料プランを利用すればお金はかからない、はずです(自分のカードで利用したことないので断言はできないです。大丈夫だと思うのですが)。

 Azure以外の場所へ上げる事ももちろん可能です。その場合、解説は適宜読み替えてください。


Bot Framworkを使う


Bot Applicationテンプレートでプロジェクト作成


テンプレート配置

 Bot Frameworkのプロジェクトを作るためにマイクロソフトがテンプレートを用意してくれました。こちらよりダウンロードしてください。ダウンロードしたzipファイルをVisual Studio 2015のテンプレートフォルダに入れてください(デフォルトでは %USERPROFILE%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C# です。エクスプローラーのアドレスバーに貼り付けて飛んでください)。

template.png


プロジェクト作成

 テンプレートを入れたらVisual Studioを起動して、新しいプロジェクトを作ってみてください。問題がなければ、Bot Applicationというテンプレートが選べるはずです。

bot_template.png


ビルド

 プロジェクトを作成したら、そのままビルドをしてください。ブラウザが開き、下の画像のようなページが表示されればオッケーです。

debug_boot.png


エミュレーターで動作確認

 実はさきほど入れたテンプレートには、動くbotがもう書いてあります。なので、もう半分終わった……といいたい所ですが、まだまだですね。今のままではbotはどこともつながっていません。壁と話してろよ状態です。

 ここからいきなり実際のSNSサービスに接続してもよいのですが、それには少し手間がいります。でも早く動いている所を見たいですよね。

 こういう事を想定してマイクロソフトが動作確認用のエミュレーターを用意してくれてます。

※v3でエミュレーターもバージョンアップしました。7/9時点で3.0.0.54です。


インストール

 このリンクからインストールできます。

 インストールが終われば、自動的にエミュレーターが起動します。


接続設定

 エミュレーターをbotにつなげるには次の3つの項目を設定する必要があります

※v3より「AppId」は「MicrosoftAppId」に、「AppSecret」は「MicrosoftAppPassword」へ変更されました。


  1. URL: さきほどビルドをして開いたページがあると思います。そのページのアドレスをコピーしてエミュレーターのURLのボックスにペーストしてください。さらに、ペーストした文字列の後ろに"/api/messages"を足してください。

2-3. MicrosoftAppId/MicrosoftAppPassword: プロジェクト内に"Web.config"というファイルがあるはずです。それを開くと

  <appSettings>

<!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
<add key="BotId" value="YourBotId" />
<add key="MicrosoftAppId" value="" />
<add key="MicrosoftAppPassword" value="" />
</appSettings>

という項目があるので、MicrosoftAppIdとMicrosoftAppPasswordが空白になっているのを確認してください。この値はBotの登録後にちゃんとしたものを入れます。

 埋めた結果次のようになりました(具体的な値は環境や時期によって変わるかもしれません)。

new_emulator.png


エミュレーター上でbotと会話

 できましたか? それではbotに話しかけてください(画面最下部のボックスが入力欄です)。

bot_error.png

 あらら、エラーです。

 どうやらプログラムを起動し忘れてたみたいですね。よくある事です(上手くいった人は経験者かズボラで毎回終了するのを忘れるタイプの人でしょう)。

 もう一度起動してから、話してみましょう

bot_succsess.png

 できましたね!

 どうやらこれは、話しかけた内容の文字数を返すbotのようです。


bot改造

 目標ではオウム返しをするbotと書いたので、オウム返しをするようコードを書き換えてみましょう。

 まず、ソリューションエクスプローラーからControllers/MessagesController.csを開いてください。

 その中のPostメソッドを見てください。

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)

{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;

// return our reply to the user
Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}

 なんとなく分かると思いますが、ユーザーから呼びかけがあるとこのPostメソッドが呼ばれます。その中身もだいたい分かりますね、送られたメッセージの文字数を数えて返しているだけです。

 ここをオウム返しするように書き換えます。本当にそのまま戻すだけだと芸がないので、かぎかっこでくくった上でビックリマークをつけてあげましょう。ちょっとだけ愛嬌度が上がります。

if (activity.Type == ActivityTypes.Message)

{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

// 「オウム返しだ」「オウム返しだ!」
Activity reply = activity.CreateReply($"「{activity.Text}!」");
await connector.Conversations.ReplyToActivityAsync(reply);
}

parroting.png

 できました。簡単でしょう?


MessageTypeについて

 おおざっぱなタイプの人がそろそろ「はよサーバーにあげろ」と言ってきそうですが、その前に重箱の隅が気になってしょうがない几帳面な方々(世に言う早死にするタイプ。プログラマーに多い)の疑問に答えましょう。HandleSystemMessageメソッドについてです。

 今見たオウム返しのように、ユーザーの送信に応答するというのはよくある使用例ですが、それ以外の特定の状況をトリガーにメッセージを出したい場合が考えられます。例えば、会話が始まったときにあいさつをしたい、というケースです。

 このような場面に対応するために、Bot FrameworkではMessageTypeというものが用意されています。具体的に以下のものがあります(2016/7/7現時点1

※v3で大きな変更が入りました。以下はv3の説明です。(2016/7/9現時点2)

MessageType
MessageType (訳)
説明

Message
メッセージ
通常の会話

DeleteUserData
ユーザー情報削除
ユーザー固有の情報(例:個人情報)の削除を希望する

ConversationUpdate
会話の更新
Botやユーザーが会話に加わったり、外れたりした事を伝えるメッセージ。 MembersAddedとMembersRemovedプロパティで具体的な内容を取得。

ContactRelationUpdate
連絡帳の更新
連絡帳(やそれに類似する機能)が存在するサービス(例:Skype)などの場合、それに変更があった事を知らせる。Actionプロパティの値に"add"/"remove"が入っている。

Typing
タイピング中
ユーザーがタイピング中である事を知らせる。

Ping
Ping
Botの状態を確認するためのシステムリクエスト

 特筆するべきなのは、これが汎用的に使える事です。それぞれのメッセージへの応答を書いておけばBot Frameworkが実際に利用しているサービス(SkypeならSkypeの、FacebookならFacebookの)のメッセージに変換してくれます。この汎用性がBot Frameworkを使う大きなメリットの1つです(そのサービスで利用できない機能は単に無視されます)。

 それでは簡単な例を提示します。ユーザーが会話に参加したときにあいさつをするようにしましょう。以下のコード加えます。

if(message.MembersAdded.Count > 0)

{
//アイサツは実際大事。古事記にもそう書かれている。
return message.CreateReply($"「こんにちは!」");
}

そして、呼び出し側で応答を返します。以下が全体のコードです。

[BotAuthentication]

public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

if (activity.Type == ActivityTypes.Message)
{
// 「オウム返しだ」「オウム返しだ!」
Activity reply = activity.CreateReply($"「{activity.Text}!」");
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
var reply = HandleSystemMessage(activity);
//システムメッセージに対する応答
if (reply != null)
{
await connector.Conversations.ReplyToActivityAsync(reply);
}
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}

private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
if(message.MembersAdded.Count > 0)
{
//アイサツは実際大事。古事記にもそう書かれている。
return message.CreateReply($"「こんにちは!」");
}
}
//省略

return null;
}
}

エミュレーターにはシステムメッセージを直接送信する機能があるので、これでテストできます。

added_user_to_conversation.png


Azureへのアップロード

 お待たせしました。ようやくサーバーへアップロードします。今回はAzureへアップロードしますが、場所はどこでもいいです。


Visual Studioから公開


  • 「ソリューションエクスプローラー」> プロジェクトを右クリック > 「公開」

publish.png


  • Azure App Serviceを選択

public2.png


  • App Serviceの項目を埋める


  1. 「アカウントの追加」からマイクロソフトアカウントを設定

  2. 自分のサブスクリプションを選択

  3. 既にApp Serviceを作っていたらそれを選びます、なければ「新規作成」を選択

public3.png

 「種類の変更」でWeb Appに変更してください。リソースグループとプランを作成してない方はここでそれぞれ「新規作成」してください。

create_app_service.png

 無料で使いたい人はプラン内で「無料」プランを選んでください。

plan_dialog.png

4. App Serviceを選んで「OK」すると、デプロイ画面になります。設定値は既に埋まってるので、「発行」でデプロイしてください。

deploy_new.png

5. 「宛先URL」でローカルの時と同じページが開きます。次の登録処理で使うので、アドレスバーの値はコピーしておいてください。

hosted_to_azure.png

 Visual Studioの「Azure App Serviceのアクティビティ」ウィンドウで発行状況を確認します。

deploy_success.png

 これでデプロイ完了です。


公式サイト(Developer Portal)へ登録・設定・(公開)

 デプロイをしたら、今度はBot Frameworkの公式サイトに登録します。これをする事で各種SNSサービスとの連携やBotの設定をブラウザから行う事ができるようになります。この公式サイトのサービスの事をBot FrameworkではDeveloper Portalと呼びます(v3から。v1ではBot Connectorと呼ばれ、担当範囲も少し違いました)。


登録の流れ



  1. 公式ページへ飛び、右上の「Sign in」からマイクロソフトアカウントでログインします。

  2. 上部メニューから「Register a bot(Botを登録)」を選択します。

  3. Botの情報を入力します。

  4. 登録の前にMicrosoft App Idを作成します。

  5. 登録。


Botの登録情報

 各項目の和訳と説明です。*は必須項目。

※v3アップデートで、設定項目に変更がありました。


Bot profile(Bot情報)

項目
項目の和訳
説明

*Name
名前
Botの表示名。35文字以内。

*Bot handle
Botのハンドル
Urlに使われる。英数字+_(アンダースコア)のみ。後で変更不可。

*Description
説明
Botの説明。


Configuration(設定)

項目
項目の和訳
説明

Messaging endpoint
メッセージエンドポイント
メッセージの送受信をさせるRestのエンドポイント。

*Microsoft App ID
MicrosoftアプリID
後述。

 Message endpointには公開時に表示されたページのアドレス + 後ろに/api/messagesを追記したものを入力してください


Publisher profile(公開者情報)

項目
項目の和訳
説明

*Publisher name
公開者名
-

*Publisher Email
公開者メールアドレス
-

*Privacy statement
プライバシーポリシー
Botのプライバシーポリシーが記載されているURL。

*Term of Use
利用規約
Botの利用規約が記載されているURL。

Bot website
Botのホームページ
-

Hashtags
ハッシュタグ
コンマ区切り。具体的な意味は未調査。

Languages
言語
ISO-639-1で指定(日本語はja)。コンマ区切り。具体的な意味は未調査。

Default Conversation Language
デフォルトの会話言語
ISO-639-1で指定。


Admin(管理)

項目
項目の和訳
説明

Owners
所有者
Botを編集できる人のリスト。コンマ区切り。

Azure App Insights key
Azure App Insightsキー
キーを設定すればBotの解析結果が送られてくる。


Micosoft App Idの作成

 登録する前にMicosoft App Idを作成します。

1. 「Create Microsoft App ID and password」と書かれたボタンを押してください。

create_ms_app_id.png

2. 自動的に設定値が決められます。「Generate a password to continue」ボタンを押してください。

generate_a_password.png

3. パスワードが表示されます。この時だけしか表示されないのでコピーして、セキュリティ的に安全な所で保管してください。なお、忘れたり流出などした場合、ここで削除して作り直せばいいと思います。

new_password_generated.png

4. 「Finish and go back to Bot Framework」ボタンを押します。登録画面には自動的にさきほどのIDが入力されているはずです。

generate_a_password2.png


登録

 「Register」ボタンで登録できます。なお登録あたっては、マイクロソフトが提示するプライバシーポリシー・利用規約・行動模範を確認、内容に同意した上で行ってください。


アプリIDとアプリキーの設定

※v3よりAppIdはMicrosoftAppId、AppSecretはMicrosoftAppPasswordに変更されました

 Bot登録が完了したらVisual Studioを開きなおし、先ほど登録したBot Id(Bot handle)/Microsoft App ID/Microsoft App Passwordをプロジェクト内にある「Web.config」というファイルに反映させます。

 設定値が分からなくなった場合、ポータルの「My Bots」ページからBotの管理画面に行く事ができるので、そこから確認する事ができます(パスワードは無理)。

<appSettings>

<!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
<add key="BotId" value="<ここにBot ID(Bot handle)>" />
<add key="MicrosoftAppId" value="<ここにMicrosoft App ID>" />
<add key="MicrosoftAppPassword" value="<ここにMicrosoft App Password>" />
</appSettings>


接続確認

 Botへの接続テストを管理画面から行えます。

 左下の「Test connection to your bot(Botへの接続テスト)」というテキストの下の「Test」ボタンを押します。「Endpoint authorization suceeded(エンドポイントへの認証成功)」が出てくれば接続テスト成功です。

bot_connection_success.png


公開(任意)

 管理画面の右上にある「Publish」を押すと、マイクロソフトへレビュー申請がされ、合格するとBotが公開されます。公開されると他の人が利用したりできるようですが、やってないので詳細は分からないです。公開したくない場合はしなくていいです。


Facebook連携

 Bot Frameworkでは各種外部サービスなどと連携する事ができます。Bot Frameworkではこれらの外部サービスの事をチャンネルと呼んでいます。

channels.png

 日本では見慣れないサービスも多いですね。せめてTwitterがあればよいのですが、まぁこれは後から来るでしょう(LINEはおそらく無理でしょうか)。

 今回はFacebootと連携してみましょう。

※Bot Framework側もFacebook側も設定画面は変化が激しい部分なので、柔軟に対応してください。


準備

 Facebookの開発者アカウントを作成してください。こちらから作成してください。


設定の流れ


  1. ポータルでFacebook Messengerチャネルを追加するを選び、設定画面を開く。

  2. Facebookページを作成する。ページIDを控える。

  3. Facebook Appを作る。AppのIdとシークレットを控える。

  4. 1で開いた設定画面からBot Frameworkが使うコールバックUrlと検証トークンを入手し、それをFacebook Appに設定する。

  5. Facebookページへのアクセストークンを生成し、控える。

  6. 1で開いた設定画面に2、3、5の値を入力する

  7. 設定を反映。


設定画面

 まずBotの管理画面で、「Facebook Messenger」項目にある「Add」をクリックしてください。FacebookMessengerの設定画面が開きます。

Configure Facebook Messenger.png


Botが動くFacebookページを作成する

 ここでいう「ページ」とは、主に企業のブランドやコミュニティの為の場を提供するFacebookのサービスを指します。詳細は「facebook page」で適当にググってください。

 ページ作成画面に行ってください。

page_create.png

 作りたいBotにあった項目を選んで、ページを作ってください。

 ページができたら、作成したページに行き、左サイドメニューから「基本データ」を選んでください。「FacebookページID」という項目があるので、これを控えておいてください。後で使います。

page_id.png


Facebook Appを作成する

 Botを利用するために、Facebook Appを作成します。

 現時点ではこちらのリンクからいけます。

fb_app_start.png

 右上の「Skip and Create App ID」をクリックします。

fb_app_create_id.png

 アプリの作成を求められるので、埋めて作成してください。

 アプリを作成したら、ダッシュボードに行き、そこで表示されるApp Idとシークレットを控えてください。

fb_appid.png


ウェブフック用のコールバックURLと検証トークンを設定

 Bot FrameworkのFacebook Messengerチャンネル追加画面に行き、「Set webhook callback url and verify token」を展開して、「Callback Url」と「Verify Token」を控えてください。

fb_webhook.png

 Facebook Appの管理画面に行き、左メニューから「+製品の追加」を選び、メインページに出てくるリストの中から「Webhooks」を選んでください。Webhooksのページで「新しいフォロー」を選び「Page」を選びます。

 そうすると、Webhookの設定画面で出てくるので、Bot Frameworkの管理画面で控えておいた、コールバックUrlと検証トークンを入れます。そして、フォロー入力欄で

* message_deliveries

* messages

* messaging_optins

* messaging_postbacks

の4項目にチェックを入れます。

fb_callback.png

 この操作により、ページ中でメッセージを利用した場合、Facebook側からあなたのBotへ処理を引き渡すことが可能になります。


ページへのアクセストークンを発行する

 Botからページにアクセルするためのトークを発行します。

 Facebook Appの管理画面から「+製品の追加」を選び「Messenger」を選択、出てくる説明を読んでから「スタート」を押します。

 すると、Messengerの画面が出るので、「トークン生成」メニューから上の方で作ったページを選びトークンを生成してください。トークンは後で使うので、控えてください。

fb_page_accesstoken.png


資格情報を入力

 再びBot FrameworkのFacebook Messengerチャンネル追加画面に行き、「Enter your credentials(資格情報を入力)」を展開します。ここに控えておいた4つの値を入力します。

fb_credentials.png

 入力したら「Resubmit」を押してください。「Credentials have been validated(資格情報の検証が完了しました)」と表示されれば成功です。

fb_credentials2.png


設定登録

 「Enable this bot on Facebook Messenger(Facebook MessengerでBotを有効化する)」にチェックを入れます。使用を止める時はここをオフにすれば、設定を残したまま無効化できるはずです(検証はしてないです)。

 最後に「I'm done configuring Facebook Messenger(Facebook Messengerの設定を終えました)」を押せば設定完了です。

 Botの管理画面でチャンネルのところFacebook Messengerがあり、Statusが「Running(実行中)」になっているのを確認してください。


利用

 それでは実際に動いている所を見てみましょう。

 作成したFacebookのページに行きます。「メッセージ」を押して会話を始めます。

facebook_message_test.png

bot answer.png

 できました!

 グレートですよこれは。


まとめ

 これで目標通り、簡単なBotを作って外部サービスと連携することができるようになりました。

 あとはプログラミング次第で色々できるのではないかと思います。

 なお、今回は触れませんでしたがBot FrameworkにはBot BuilderというBot構築のためのライブラリがあり、会話を統一的に実装できるようになるとかなんとかだそうです(まだよく調べていないです)。また、Botに自然言語での会話機能を組み込みたいというニーズのために、Microsoft Coginitive Serviceの1つであるLUISというサービスと連携することもできます。

 初めての記事執筆で至らないこともあると思いますが、何かの役に立てれば幸いです。

 ではでは。


参考