将聊天机器人响应用作Azure聊天机器人框架中的触发词

时间:2018-08-10 16:36:58

标签: c# azure triggers botframework chatbot

我正在使用Azure中的Bot框架开发一个聊天机器人,我目前正在尝试将我的聊天bot响应用作用户触发词,以将用户问题存储在表存储中,例如,当bot响应时显示“我” m抱歉,没有您的答案。请尝试重新回答您的问题”,它会记录用户的第一个问题,例如“我如何飞行?”。

对此将提供任何帮助!

1 个答案:

答案 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));