问题
I tried using IActivityLogger to capture the conversation of a user, is there a way to compile the conversation of the user and the bot to a temporary holder like a variable or session? I need to temporarily store it somewhere that is readily available only when the user wants to talk to a real person instead of a bot. An email containing the previous conversation of the user and the bot will be sent. I don't want to save it to a DB since some user will not opt to do so.
See Codes used. Logger Class:
public class Logger:IActivityLogger
{
public async Task LogAsync(IActivity activity)
{
var a = ($"From:{activity.From.Id} - To:{activity.Recipient.Id} - Message:{activity.AsMessageActivity()?.Text}" + "\b\r");
}
}
Global Asax:
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterType<Logger>().AsImplementedInterfaces().InstancePerDependency();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
回答1:
As suggested by Ezequiel in the comments, you could store the activities in a dictionary. Something like:
public class Logger : IActivityLogger
{
public static ConcurrentDictionary<string, List<IActivity>> Messages = new ConcurrentDictionary<string, List<IActivity>>();
public Task LogAsync(IActivity activity)
{
var list = new List<IActivity>() { activity };
Messages.AddOrUpdate(activity.Conversation.Id, list, (k, v) => { v.Add(activity); return v; });
return Task.FromResult(false);
}
}
Then send them to the user later:
case ActivityTypes.Message:
if (!string.IsNullOrEmpty(activity.Text) && activity.Text.ToLower() == "history")
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var reply = activity.CreateReply();
var storedActivities = new List<IActivity>();
var found = Logger.Messages.TryGetValue(activity.Conversation.Id, out storedActivities);
if (storedActivities != null)
{
foreach (var storedActivity in storedActivities)
{
reply.Text += $"\n\n {storedActivity.From.Name}: {storedActivity.AsMessageActivity().Text}";
}
}
else
{
reply.Text = "no history yet";
}
//or, send an email here...
var client = scope.Resolve<IConnectorClient>();
await client.Conversations.ReplyToActivityAsync(reply);
}
}
else
await Conversation.SendAsync(activity, MakeRootDialog);
break;
You'll also need to remove the conversation from the list at some point. You'll probably want an expiration policy of some sort, since not every channel will notify the bot that the user has left the conversation.
回答2:
I have explored preserving the conversation transcript for the exact same reason - to hand the conversation off to a human agent. The only difference is that my code uses the node.js SDK. See if you can port it to C#:
http://www.pveller.com/smarter-conversations-part-4-transcript/
来源:https://stackoverflow.com/questions/43602478/storing-conversation-of-a-specific-user-temporarily