Bot Framework v3への更新に際してかなり大幅な変更があるのでとりあえずベースの部分だけまとめます。
初めに
V3対応前の最終バージョンのEmulatorを開くと以下のように警告が出ます。
hereの部分から更新用のリンクに飛べるのでそこで更新しましょう。
v3対応Emulator
hereのところから入れると、古いEmulatorの更新じゃなくて新規アプリケーションとしてインストールされるようです。
バージョン番号は、3.0.0.54のようです。
アプリ名も以前のものは、Microsoft Bot Framework EmulatorだったのがMicrosoft Bot Framework Channel Emulatorに名称が変わっています。
挙動もちょこちょこ変わっているので動かしてみます。
v1デフォルトでの動作
以前配布されていたテンプレート(v1.0.0)で実行してメッセージを投げると下記のように失敗します。
v3対応
結構大幅に変わってて辛いです。
設定ファイル
v1の設定ファイル
<add key="AppId" value="YourAppId" /> <add key="AppSecret" value="YourAppSecret" />
AppIdとAppSecretを記述する必要がありました。
v3の設定ファイル
<add key="BotId" value="YourBotId" /> <add key="MicrosoftAppId" value="" /> <add key="MicrosoftAppPassword" value="" />
AppId、AppSecretの代わりに
BotId、MicrosoftAppId、MicrosoftAppPasswordの3つを設定するように変更になります。
この中のMicrosoftAppIdとMicrosoftAppPasswordをEmulatorの上部に入れます。
公式のドキュメントだとBot Idの入力欄も用意されているように見えますが、公式の画像が3.0.0.49になっていて、最新版は、3.0.0.54になってBot Idの入力欄が省かれているので必要ないようです。
ちなみにローカルのBotに対してAppIdとAppPasswordを空白以外にしてEmulatorにもその値を入れると認証失敗で通信にコケるので一旦入力しないようにしたほうがよさそうです。
ライブラリ
Bot Builder、Bot Connectorのライブラリも3.0.0に変更されています。
3.0.0にしないとv3用のEmulatorと通信できません。
現在NuGetからBot Connectorを入れようとすると1.1.0が最新として公開されていて3.0.0が手に入らないように見えますが、Bot Builderを入れると自動的にBot Connectorの3.0.0も入るのでBot Builderだけ入れましょう。
ソースコードの改変
下記のコードは、v1用のコードです。
v3にするとほぼ完全に名称変更されたりして完全に互換性がないので修正します。
using System; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Description; using Microsoft.Bot.Connector; using Newtonsoft.Json; namespace v3Sample { [BotAuthentication] public class MessagesController : ApiController { ////// POST: api/Messages /// Receive a message from a user and reply to it /// public async TaskPost([FromBody]Message message) { if (message.Type == "Message") { // calculate something for us to return int length = (message.Text ?? string.Empty).Length; // return our reply to the user return message.CreateReplyMessage($"You sent {length} characters"); } else { return HandleSystemMessage(message); } } private Message HandleSystemMessage(Message message) { if (message.Type == "Ping") { Message reply = message.CreateReplyMessage(); reply.Type = "Ping"; return reply; } else if (message.Type == "DeleteUserData") { // Implement user deletion here // If we handle user deletion, return a real message } else if (message.Type == "BotAddedToConversation") { } else if (message.Type == "BotRemovedFromConversation") { } else if (message.Type == "UserAddedToConversation") { } else if (message.Type == "UserRemovedFromConversation") { } else if (message.Type == "EndOfConversation") { } return null; } } }
v3用のベースコードは、下記のような感じになります。
using System; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Description; using Microsoft.Bot.Connector; using Newtonsoft.Json; namespace v3Sample2 { [BotAuthentication] public class MessagesController : ApiController { ////// POST: api/Messages /// Receive a message from a user and reply to it /// public async TaskPost([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; } 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) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels } else if (message.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (message.Type == ActivityTypes.Typing) { // Handle knowing tha the user is typing } else if (message.Type == ActivityTypes.Ping) { } return null; } } }
以前のコードでは、Botとのやり取りは、大体WebAPIのリクエストとレスポンスの一対一のやり取りをメインに据えている感じでしたが、
このコードを見る限りだと、POSTのレスポンスにメッセージを乗せるのではなく、ConnectorClientクラスでBot Connectorと明示的に接続してReplyToActivityAsyncメソッドでメッセージを送信する形を推奨するのかなって感じです。
また、今までMessageクラスをメッセージの一つの単位として扱ってましたが、これからは、Activityクラスを使うようになるようです。というかMessageクラスは、消滅したっぽいので気を付けましょう。
このコードを使うと、v3用のEmulatroと下記のように通信できます。
v3用のEmulatorで通信出来たら、一応v3対応ができたのではないかと思われます。
まとめ
とりあえず公式の提供するテンプレートを使ってざっくりv1とv3の変更点とどうすればv3用になるのかをざっくりまとめました。
v1はバージョン番号の扱い的に完全にベータ扱いっぽい雰囲気でしたがここまで変更してくるのは想定外です。
すさまじい量の変更点があるっぽいので誰かまとめてください。