不知大家在使用 botframework-emulator 測試 chatbot 時,有沒有發現,對話一開始時,會先將 Bot State 取出來(BotConversationData, BotPrivateConversationData 及 BotUserData),而在對話後,則將這些資料存回去,如下圖所示,
那大家會好奇那些 Bot State 都存到那裡去了呢?
預設的 BotDataStore 是使用 ConnectorStore ,它依 StateClient.BotState 去儲存,而 url 就是 {serverUrl}/v3/botstate/{channelId}/conversations/{conversationId} , {serverUrl}/v3/botstate/{channelId}/conversations/{conversationId}/users/{userId} 及 {serverUrl}/v3/botstate/{channelId}/users/{userId} ,詳細可以參考 BotState.cs ,serverUrl 是 activity.ServiceUrl ,詳細可以參考 StateClient.cs。
在 Saving State data in SQL with .NET 這篇之中,說明如何實作 IBotDataStore
客製的 BotDataStore 寫好了之後,記得要在 global.asax 中去設定讓 autofac 使用我們的 SqlBotDataStore,如下,
1 | protected void Application_Start() |
這樣在SQL中就可以看到 Bot State 存到了 SQL DB 之中,如下,
另外,像我們之前寫的 Local Direct Line Server 使用 Microsoft Bot Framework 地端的 WebChat 機器人(企業內),我們會將 Channel 的資料放在 ChannelData 之中,而在存 State 時, ChannelId 要取自 activity 的 channelData ,則可以改自 ConnectorStore ,加入讀取 activity ,如下,
1 | //modify from ConnectorStore |
而在 global.asax 之中,我們的 LDLDataStore 需要多傳入 Activity ,如下,
protected void Application_Start()
{
Conversation.UpdateContainer(builder =>
{
builder.Register(c => new CachingBotDataStore(new LDLDataStore(c.Resolve<IStateClient>(), c.Resolve<IActivity>())
, CachingBotDataStoreConsistencyPolicy.LastWriteWins))
.As<IBotDataStore<BotData>>()
.AsSelf()
.InstancePerLifetimeScope();
});
GlobalConfiguration.Configure(WebApiConfig.Register);
}
知道如何在 global.asax 中置換 BotDataStore ,只要實作 IBotDataStore