临时存储特定用户的对话
Storing conversation of a specific user temporarily
我尝试使用 IActivityLogger 来捕获用户的对话,有没有办法将用户和机器人的对话编译成变量或会话之类的临时持有者?我需要将它临时存储在某个地方,只有当用户想要与真人而不是机器人交谈时才可以随时使用。将发送一封包含用户和机器人先前对话的电子邮件。我不想将它保存到数据库中,因为有些用户不会选择这样做。
查看使用的代码。
记录器 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");
}
}
全球 Asax:
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterType<Logger>().AsImplementedInterfaces().InstancePerDependency();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
出于完全相同的原因,我探索过保留对话记录 - 将对话交给人工代理。唯一的区别是我的代码使用 node.js SDK。查看是否可以将其移植到 C#:
http://www.pveller.com/smarter-conversations-part-4-transcript/
正如 Ezequiel 在评论中所建议的那样,您可以将活动存储在字典中。类似于:
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);
}
}
稍后发送给用户:
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;
您有时还需要从列表中删除对话。您可能需要某种过期策略,因为并非每个频道都会通知机器人用户已离开对话。
我尝试使用 IActivityLogger 来捕获用户的对话,有没有办法将用户和机器人的对话编译成变量或会话之类的临时持有者?我需要将它临时存储在某个地方,只有当用户想要与真人而不是机器人交谈时才可以随时使用。将发送一封包含用户和机器人先前对话的电子邮件。我不想将它保存到数据库中,因为有些用户不会选择这样做。
查看使用的代码。 记录器 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");
}
}
全球 Asax:
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterType<Logger>().AsImplementedInterfaces().InstancePerDependency();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
出于完全相同的原因,我探索过保留对话记录 - 将对话交给人工代理。唯一的区别是我的代码使用 node.js SDK。查看是否可以将其移植到 C#:
http://www.pveller.com/smarter-conversations-part-4-transcript/
正如 Ezequiel 在评论中所建议的那样,您可以将活动存储在字典中。类似于:
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);
}
}
稍后发送给用户:
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;
您有时还需要从列表中删除对话。您可能需要某种过期策略,因为并非每个频道都会通知机器人用户已离开对话。