问题
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