BotFramework - Repeat last message using c#

流过昼夜 提交于 2020-01-06 06:08:50

问题


I'm building a bot using Microsoft Bot Framework using C#. I'm controlling my flow using Dialogs, and using quick replies as buttons, they dissapear when a new message is sent.

I also created a global command to help the user. When the user types "help" the bot will give some information about what it can do.

The problem is that if the user asks for help the quick replies will dissapear and the user might not know how to continue the dialog. I was wondering if there is any way to repeat the last sent message after the help is sent (the help is not a Dialog, the Scorable sends the message).

Thanks


回答1:


Nothing stops you from keeping a record of the messages the user has sent. If you build your own UI you could do it in a common way, so pressing the up arrow for example could cycle the user through their commands.

activity.Text has the text command, just add that to a list of your own, use the bot state or whatever mechanism you want for that as you will need a storage mechanism.

There are other ways as well, don't forget that the state of each dialog is maintained so once you invoke it again it will continue from where it left off.




回答2:


I ended following @Andrei Dragotoniu idea, but I'd like to provide some implementation details.

Short story

Save the last (or more if you want) sent message in some storage (you can use the conversation id to identify it). Resend it when needed.

Long story

To save the last message the simplest way I found was to create a IBotToUser implementation and add it to the IBotToUser chain.

public class StoreLastActivity : IBotToUser
{
    private readonly IBotToUser inner;

    public StoreLastActivity(IBotToUser inner)
    {
        SetField.NotNull(out this.inner, nameof(inner), inner);
    }

    public IMessageActivity MakeMessage()
    {
        return this.inner.MakeMessage();
    }

    public async Task PostAsync(IMessageActivity message, CancellationToken cancellationToken = default(CancellationToken))
    {
        // Save the message here!!!

        await this.inner.PostAsync(message, cancellationToken);
    }
}

In Global.asax.cs or in some Module class register the class and the new chain. Update the Conversation container.

Conversation.UpdateContainer(builder =>
{
    // Registers the class the saves the last send message for each conversation.
    builder
        .RegisterKeyedType<StoreLastActivity, IBotToUser>()
        .InstancePerLifetimeScope();

    // Adds the class on the IBotToUser chain.
    builder
        .RegisterAdapterChain<IBotToUser>
        (
            typeof(AlwaysSendDirect_BotToUser),
            typeof(AutoInputHint_BotToUser),
            typeof(MapToChannelData_BotToUser),
            typeof(StoreLastActivity),
            typeof(LogBotToUser)
        )
        .InstancePerLifetimeScope();
}

This means that every message sent to the user will pass by StoreLastActivity.PostAsync, so you can save it anywhere and use message.Conversation.Id as an id. I saved the entire IMessageActivity as it not always just text, it may contains cards, buttons etc...

Now just retrieve the IMessageActivity and send it whenever you need.

If anyone got a simpler solution I'd like to hear it.

Thank you.



来源:https://stackoverflow.com/questions/45374223/botframework-repeat-last-message-using-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!