やや話題に乗り遅れた感がありますが、マイクロソフトが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"を入れてください。**これがないとプロジェクトを作れません。
マイクロソフトアカウントを作る
マイクロソフトのサービスを使うので必須です。
※@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# です。エクスプローラーのアドレスバーに貼り付けて飛んでください)。
プロジェクト作成
テンプレートを入れたらVisual Studioを起動して、新しいプロジェクトを作ってみてください。問題がなければ、Bot Applicationというテンプレートが選べるはずです。
ビルド
プロジェクトを作成したら、そのままビルドをしてください。ブラウザが開き、下の画像のようなページが表示されればオッケーです。
###エミュレーターで動作確認
実はさきほど入れたテンプレートには、動くbotがもう書いてあります。なので、もう半分終わった……といいたい所ですが、まだまだですね。今のままではbotはどこともつながっていません。壁と話してろよ状態です。
ここからいきなり実際のSNSサービスに接続してもよいのですが、それには少し手間がいります。でも早く動いている所を見たいですよね。
こういう事を想定してマイクロソフトが動作確認用のエミュレーターを用意してくれてます。
※v3でエミュレーターもバージョンアップしました。7/9時点で3.0.0.54です。
インストール
このリンクからインストールできます。
インストールが終われば、自動的にエミュレーターが起動します。
接続設定
エミュレーターをbotにつなげるには次の3つの項目を設定する必要があります
※v3より**「AppId」は「MicrosoftAppId」に、「AppSecret」は「MicrosoftAppPassword」**へ変更されました。
- 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の登録後にちゃんとしたものを入れます。
埋めた結果次のようになりました(具体的な値は環境や時期によって変わるかもしれません)。
エミュレーター上でbotと会話
できましたか? それではbotに話しかけてください(画面最下部のボックスが入力欄です)。
あらら、エラーです。
どうやらプログラムを起動し忘れてたみたいですね。よくある事です(上手くいった人は経験者かズボラで毎回終了するのを忘れるタイプの人でしょう)。
もう一度起動してから、話してみましょう
できましたね!
どうやらこれは、話しかけた内容の文字数を返す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);
}
できました。簡単でしょう?
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;
}
}
エミュレーターにはシステムメッセージを直接送信する機能があるので、これでテストできます。
Azureへのアップロード
お待たせしました。ようやくサーバーへアップロードします。今回はAzureへアップロードしますが、場所はどこでもいいです。
Visual Studioから公開
- 「ソリューションエクスプローラー」> プロジェクトを右クリック > 「公開」
- Azure App Serviceを選択
- App Serviceの項目を埋める
- 「アカウントの追加」からマイクロソフトアカウントを設定
- 自分のサブスクリプションを選択
- 既にApp Serviceを作っていたらそれを選びます、なければ「新規作成」を選択
「種類の変更」でWeb Appに変更してください。リソースグループとプランを作成してない方はここでそれぞれ「新規作成」してください。
無料で使いたい人はプラン内で「無料」プランを選んでください。
4. App Serviceを選んで「OK」すると、デプロイ画面になります。設定値は既に埋まってるので、「発行」でデプロイしてください。
5. 「宛先URL」でローカルの時と同じページが開きます。次の登録処理で使うので、アドレスバーの値はコピーしておいてください。
Visual Studioの「Azure App Serviceのアクティビティ」ウィンドウで発行状況を確認します。
これでデプロイ完了です。
公式サイト(Developer Portal)へ登録・設定・(公開)
デプロイをしたら、今度はBot Frameworkの公式サイトに登録します。これをする事で各種SNSサービスとの連携やBotの設定をブラウザから行う事ができるようになります。この公式サイトのサービスの事をBot FrameworkではDeveloper Portalと呼びます(v3から。v1ではBot Connectorと呼ばれ、担当範囲も少し違いました)。
登録の流れ
- 公式ページへ飛び、右上の「Sign in」からマイクロソフトアカウントでログインします。
- 上部メニューから「Register a bot(Botを登録)」を選択します。
- Botの情報を入力します。
- 登録の前にMicrosoft App Idを作成します。
- 登録。
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を作成します。
- 「Create Microsoft App ID and password」と書かれたボタンを押してください。
- 自動的に設定値が決められます。「Generate a password to continue」ボタンを押してください。
- パスワードが表示されます。この時だけしか表示されないのでコピーして、セキュリティ的に安全な所で保管してください。なお、忘れたり流出などした場合、ここで削除して作り直せばいいと思います。
- 「Finish and go back to Bot Framework」ボタンを押します。登録画面には自動的にさきほどのIDが入力されているはずです。
登録
「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(エンドポイントへの認証成功)」が出てくれば接続テスト成功です。
公開(任意)
管理画面の右上にある「Publish」を押すと、マイクロソフトへレビュー申請がされ、合格するとBotが公開されます。公開されると他の人が利用したりできるようですが、やってないので詳細は分からないです。公開したくない場合はしなくていいです。
Facebook連携
Bot Frameworkでは各種外部サービスなどと連携する事ができます。Bot Frameworkではこれらの外部サービスの事をチャンネルと呼んでいます。
日本では見慣れないサービスも多いですね。せめてTwitterがあればよいのですが、まぁこれは後から来るでしょう(LINEはおそらく無理でしょうか)。
今回はFacebootと連携してみましょう。
※Bot Framework側もFacebook側も設定画面は変化が激しい部分なので、柔軟に対応してください。
準備
Facebookの開発者アカウントを作成してください。こちらから作成してください。
設定の流れ
- ポータルでFacebook Messengerチャネルを追加するを選び、設定画面を開く。
- Facebookページを作成する。ページIDを控える。
- Facebook Appを作る。AppのIdとシークレットを控える。
- 1で開いた設定画面からBot Frameworkが使うコールバックUrlと検証トークンを入手し、それをFacebook Appに設定する。
- Facebookページへのアクセストークンを生成し、控える。
- 1で開いた設定画面に2、3、5の値を入力する
- 設定を反映。
設定画面
まずBotの管理画面で、「Facebook Messenger」項目にある「Add」をクリックしてください。FacebookMessengerの設定画面が開きます。
Botが動くFacebookページを作成する
ここでいう「ページ」とは、主に企業のブランドやコミュニティの為の場を提供するFacebookのサービスを指します。詳細は「facebook page」で適当にググってください。
ページ作成画面に行ってください。
作りたいBotにあった項目を選んで、ページを作ってください。
ページができたら、作成したページに行き、左サイドメニューから「基本データ」を選んでください。「FacebookページID」という項目があるので、これを控えておいてください。後で使います。
Facebook Appを作成する
Botを利用するために、Facebook Appを作成します。
現時点ではこちらのリンクからいけます。
右上の「Skip and Create App ID」をクリックします。
アプリの作成を求められるので、埋めて作成してください。
アプリを作成したら、ダッシュボードに行き、そこで表示されるApp Idとシークレットを控えてください。
ウェブフック用のコールバックURLと検証トークンを設定
Bot FrameworkのFacebook Messengerチャンネル追加画面に行き、「Set webhook callback url and verify token」を展開して、「Callback Url」と「Verify Token」を控えてください。
Facebook Appの管理画面に行き、左メニューから「+製品の追加」を選び、メインページに出てくるリストの中から「Webhooks」を選んでください。Webhooksのページで「新しいフォロー」を選び「Page」を選びます。
そうすると、Webhookの設定画面で出てくるので、Bot Frameworkの管理画面で控えておいた、コールバックUrlと検証トークンを入れます。そして、フォロー入力欄で
- message_deliveries
- messages
- messaging_optins
- messaging_postbacks
の4項目にチェックを入れます。
この操作により、ページ中でメッセージを利用した場合、Facebook側からあなたのBotへ処理を引き渡すことが可能になります。
ページへのアクセストークンを発行する
Botからページにアクセルするためのトークを発行します。
Facebook Appの管理画面から「+製品の追加」を選び「Messenger」を選択、出てくる説明を読んでから「スタート」を押します。
すると、Messengerの画面が出るので、「トークン生成」メニューから上の方で作ったページを選びトークンを生成してください。トークンは後で使うので、控えてください。
資格情報を入力
再びBot FrameworkのFacebook Messengerチャンネル追加画面に行き、「Enter your credentials(資格情報を入力)」を展開します。ここに控えておいた4つの値を入力します。
入力したら「Resubmit」を押してください。「Credentials have been validated(資格情報の検証が完了しました)」と表示されれば成功です。
設定登録
「Enable this bot on Facebook Messenger(Facebook MessengerでBotを有効化する)」にチェックを入れます。使用を止める時はここをオフにすれば、設定を残したまま無効化できるはずです(検証はしてないです)。
最後に「I'm done configuring Facebook Messenger(Facebook Messengerの設定を終えました)」を押せば設定完了です。
Botの管理画面でチャンネルのところFacebook Messengerがあり、Statusが「Running(実行中)」になっているのを確認してください。
利用
それでは実際に動いている所を見てみましょう。
作成したFacebookのページに行きます。「メッセージ」を押して会話を始めます。
できました!
グレートですよこれは。
まとめ
これで目標通り、簡単なBotを作って外部サービスと連携することができるようになりました。
あとはプログラミング次第で色々できるのではないかと思います。
なお、今回は触れませんでしたがBot FrameworkにはBot BuilderというBot構築のためのライブラリがあり、会話を統一的に実装できるようになるとかなんとかだそうです(まだよく調べていないです)。また、Botに自然言語での会話機能を組み込みたいというニーズのために、Microsoft Coginitive Serviceの1つであるLUISというサービスと連携することもできます。
初めての記事執筆で至らないこともあると思いますが、何かの役に立てれば幸いです。
ではでは。