我正在使用Azure中的Bot框架开发一个聊天机器人,我目前正在尝试将我的聊天bot响应用作用户触发词,以将用户问题存储在表存储中,例如,当bot响应时显示“我” m抱歉,没有您的答案。请尝试重新回答您的问题”,它会记录用户的第一个问题,例如“我如何飞行?”。
对此将提供任何帮助!
答案 0 :(得分:1)
这是完成此操作的一种方法。您可以将每个问题文本存储在Dictionary
中,如果查询未正确回答,则将其发送到永久存储。
首先,创建一个静态字典来保存值:
public static class Utils
{
public static Dictionary<string, string> MessageDictionary = new Dictionary<string, string>();
}
第二,在您的消息控制器中,您可以在bot收到这样的消息时将来自每个用户的每条消息存储起来:
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
var userId = activity.From.Id;
var message = activity.Text;
if (!Utils.MessageDictionary.ContainsKey(userId))
{
ConnectorClient connector = new ConnectorClient(new System.Uri(activity.ServiceUrl));
var reply = activity.CreateReply();
//save all incoming messages to a dictionary
Utils.MessageDictionary.Add(userId, message);
// this can be removed it just confirms it was saved
reply.Text = $"Message saved {userId} - {Utils.MessageDictionary[userId]}";
await connector.Conversations.ReplyToActivityAsync(reply);
}
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
嵌套创建一个从IBotToUser
继承的类,该类可以在消息发布给用户之前对其进行拦截。如果返回给用户的文本是您提供的文本,我们将在此处将消息保存到永久存储中:“抱歉,我没有答案。请尝试重新回答您的问题”:
public sealed class CustomBotToUser : IBotToUser
{
private readonly IBotToUser inner;
private readonly IConnectorClient client;
public CustomBotToUser(IBotToUser inner, IConnectorClient client)
{
SetField.NotNull(out this.inner, nameof(inner), inner);
SetField.NotNull(out this.client, nameof(client), client);
}
public async Task PostAsync(IMessageActivity message,
CancellationToken cancellationToken = default(CancellationToken))
{
if (message.Text == "I’m Sorry, I don’t have an answer for you. Please try and rephrase your question")
{
//save to permanant storage here
//if you would like to use a database
//I have a very simple database bot example here
//https://github.com/JasonSowers/DatabaseBotExample
}
//user is the recipient
var userId = message.Recipient.Id;
//remove entry from dictionary
Utils.MessageDictionary.Remove(userId);
//this is just for testing purposes and can be removed
try
{
await inner.PostAsync($"{userId} - {Utils.MessageDictionary[userId]}");
}
catch (Exception e)
{
await inner.PostAsync($"No entry found for {userId}");
}
await inner.PostAsync((Activity) message, cancellationToken);
}
public IMessageActivity MakeMessage()
{
return inner.MakeMessage();
}
}
您还需要使用Autofac在Global.asax
中注册此类,使Aplication_Start()
方法看起来像这样:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
Conversation.UpdateContainer(
builder =>
{
builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
// Bot Storage: Here we register the state storage for your bot.
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: [https://github.com/Microsoft/BotBuilder-Azure](https://github.com/Microsoft/BotBuilder-Azure)
var store = new InMemoryDataStore();
// Other storage options
// var store = new TableBotDataStore("...DataStorageConnectionString..."); // requires Microsoft.BotBuilder.Azure Nuget package
// var store = new DocumentDbBotDataStore("cosmos db uri", "cosmos db key"); // requires Microsoft.BotBuilder.Azure Nuget package
builder.Register(c => store)
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.AsSelf()
.SingleInstance();
builder
.RegisterType<CustomBotToUser>()
.Keyed<IBotToUser>(typeof(LogBotToUser));
});
}
这是我共享的Global.asax
代码的重要部分:
builder
.RegisterType<CustomBotToUser>()
.Keyed<IBotToUser>(typeof(LogBotToUser));