将对话历史记录从MS bot保存到cosmos db [英] Save conversation history from MS bot to cosmos db
问题描述
我正在开发的机器人取代了希望与公司联系的潜在客户的联系表格,因此用户输入必须保存在数据库中.我已成功将Cosmos DB连接到我的机器人,该机器人在使用机器人时会收集状态数据.我有一个对话框堆栈,每个用户输入(名称,电子邮件和用户要离开的消息)只有一个对话框.
The bot I'm developing is a replacement for a contact form for potential clients that want to be contacted by a company, so the user inputs have to be saved in a database. I have successfully connected a Cosmos DB to my bot which collect the state data when the bot is used. I have a dialog stack with one dialog per user input (Name, email and the message the user want to leave).
我找不到任何有关如何保存用C#编写的机器人的对话历史记录的有用文档.谁能帮我吗?我仍然是Bot Framework和C#的初学者.
I can't find any helpful documentation on how to save conversation history for bots written in C#. Can anyone help me out? I'm still a beginner in Bot Framework and C#.
这是我的global.asax文件:
Here is my global.asax file:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var uri = new Uri(ConfigurationManager.AppSettings["DocumentDbUrl"]);
var key = ConfigurationManager.AppSettings["DocumentDbKey"];
var store = new DocumentDbBotDataStore(uri, key);
Conversation.UpdateContainer(
builder =>
{
builder.Register(c => store)
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.AsSelf()
.SingleInstance();
builder.Register(c => new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
.As<IBotDataStore<BotData>>()
.AsSelf()
.InstancePerLifetimeScope();
});
}
}
这是我的NameDialog,用于收集用户名:(其他对话框几乎与此相同)
Here is my NameDialog to collect the user's name: (the other dialogs are almost identical to this)
[Serializable]
public class NameDialog : IDialog<string>
{
private int attempts = 3;
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("What's your name?");
context.Wait(this.MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if ((message.Text != null) && (message.Text.Trim().Length > 0))
{
context.Done(message.Text);
}
else
{
--attempts;
if (attempts > 0)
{
await context.PostAsync("I couldn't understand, can you try again?");
context.Wait(this.MessageReceivedAsync);
}
else
{
context.Fail(new TooManyAttemptsException("This is not a valid input"));
}
}
}
}
推荐答案
我提交了几条评论,要求您对所要查找的内容进行澄清,但我想我也可能会提供一个全面的答案.
I submitted a couple of comments asking for clarification in what you're looking for, but figured I may as well just provide an all-encompassing answer.
>
使用V4
如果您的机器人是新机器人,只需使用BotBuilder/BotFramework的V4.更容易,功能更多,支持更好.无论如何,我都会提供答案.
If your bot is new, just use V4 of BotBuilder/BotFramework. It's easier, there's more features, and better support. I'll provide answers for both, anyway.
参考:
- 对于自定义存储,您可以在其中指定用户ID:
// Create Cosmos Storage private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions { AuthKey = CosmosDBKey, CollectionId = CosmosDBCollectionName, CosmosDBEndpoint = new Uri(CosmosServiceEndpoint), DatabaseId = CosmosDBDatabaseName, }); // Write var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" }; var changes = Dictionary<string, object>(); { changes.Add("UserId", userData); }; await _myStorage.WriteAsync(changes, cancellationToken); // Read var userDataFromStorage = await _myStorage.read(["UserId"]);
对于机器人处理ID的用户数据:
关键部分:
public class GreetingState { public string Name { get; set; } public string City { get; set; } }
private readonly IStatePropertyAccessor<GreetingState> _greetingStateAccessor; [...] _greetingStateAccessor = _userState.CreateProperty<GreetingState>(nameof(GreetingState)); [...] Dialogs.Add(new GreetingDialog(_greetingStateAccessor));
await _userState.SaveChangesAsync(turnContext);
var greetingState = await UserProfileAccessor.GetAsync(stepContext.Context, () => null); [...] greetingState.Name = char.ToUpper(lowerCaseName[0]) + lowerCaseName.Substring(1); await UserProfileAccessor.SetAsync(stepContext.Context, greetingState);
在V4中保存完整的对话历史记录
参考文献:
Saving Full Conversation History in V4
References:
Just read the docs and look at the sample for this one. Too much code to copy/paste.
参考:
-
我将复制/粘贴来自对于StackOverflow类似问题的一个很好的答案,以供后代使用:
I'll copy/paste the code from this good answer to a similar question on StackOverflow, for posterity:
public class WebChatController : Controller { public ActionResult Index() { var connectionString = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString; CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference("BotStore"); string userId = Guid.NewGuid().ToString(); TableQuery<BotDataRow> query = new TableQuery<BotDataRow>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, userId)); var dataRow = table.ExecuteQuery(query).FirstOrDefault(); if(dataRow != null) { dataRow.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new { UserName = "This user's name", Email = "whatever@email.com", GraphAccessToken = "token", TokenExpiryTime = DateTime.Now.AddHours(1) }); dataRow.Timestamp = DateTimeOffset.UtcNow; table.Execute(TableOperation.Replace(dataRow)); } else { var row = new BotDataRow(userId, "userData"); row.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new { UserName = "This user's name", Email = "whatever@email.com", GraphAccessToken = "token", TokenExpiryTime = DateTime.Now.AddHours(1) }); row.Timestamp = DateTimeOffset.UtcNow; table.Execute(TableOperation.Insert(row)); } var vm = new WebChatModel(); vm.UserId = userId; return View(vm); } public class BotDataRow : TableEntity { public BotDataRow(string partitionKey, string rowKey) { this.PartitionKey = partitionKey; this.RowKey = rowKey; } public BotDataRow() { } public bool IsCompressed { get; set; } public string Data { get; set; } } }
保存用户数据:
参考:
基本上,您想首先使用
IActivityLogger
捕获所有活动,就像上面的示例中一样:Basically, you want to first capture all activity using
IActivityLogger
, like in the sample just above:创建
DebugActivityLogger
public class DebugActivityLogger : IActivityLogger { public async Task LogAsync(IActivity activity) { Debug.WriteLine($"From:{activity.From.Id} - To:{activity.Recipient.Id} - Message:{activity.AsMessageActivity()?.Text}"); // Add code to save in whatever format you'd like using "Saving Custom Data in V3" section } }
将以下内容添加到
Global.asax.cs
:public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { var builder = new ContainerBuilder(); builder.RegisterType<DebugActivityLogger>().AsImplementedInterfaces().InstancePerDependency(); builder.Update(Conversation.Container); GlobalConfiguration.Configure(WebApiConfig.Register); } }
这篇关于将对话历史记录从MS bot保存到cosmos db的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-