【问题标题】:how to detect bot Idleness on Bot Framework如何在 Bot Framework 上检测 bot Idleness
【发布时间】:2019-07-04 22:37:24
【问题描述】:

我正在使用带有 C# 的 bot 框架 V3。 我需要确定我的机器人何时空闲超过 5 分钟。 我尝试通过 MessageController 处理机器人空闲,但我的尝试似乎没有成功。

switch (activity.Type)
            {
                case ActivityTypes.Message:
            await Task.Delay(5000).ContinueWith(async (t) =>
                   {
                        var reply = activity.CreateReply();                        
                            var myMessage = "Bot time out. Bye";
                            reply.Text = myMessage;
                            await connector.Conversations.ReplyToActivityAsync(reply);                     

                       });
            await Task.Factory.StartNew(() => Conversation.SendAsync(activity, () => new Dialogs.RootDialog(luisService).DefaultIfException()));
                }
                break;
}

可能出了什么问题? 请问有什么样品可以分享吗? 提前谢谢!

【问题讨论】:

  • 只是为了清楚;您希望能够确定用户和机器人之间的对话(可能是由于用户不作为)是否已闲置超过 5 分钟?然后通知用户他们已经处于非活动状态并向他们发送消息“超时”。
  • 另外,如果您正在创建一个 new 机器人,我建议您使用 V4,因为 V3 正在逐步淘汰。
  • 谢谢达娜。是的,这正是我需要的。恐怕我现在无法将解决方案迁移到 V4。不过,它正在筹备下半年。现在我需要找到一种方法在 V3.Thx 上完成它

标签: c# botframework


【解决方案1】:

首先,您只是延迟了 5 秒(5000 毫秒),而不是 5 分钟。

无论如何,您可以尝试以下方法。添加这个类:

public static class TimeoutConversations
    {
        const int TimeoutLength = 10;
        private static Timer _timer;
        private static TimeSpan _timeoutLength;

        static TimeoutConversations()
        {
            _timeoutLength = TimeSpan.FromSeconds(TimeoutLength);
            _timer = new Timer(CheckConversations, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
        }

        static ConcurrentDictionary<string, UserInfo> Conversations = new ConcurrentDictionary<string, UserInfo>();

        static async void CheckConversations(object state)
        {
            foreach (var userInfo in Conversations.Values)
            {
                if (DateTime.UtcNow - userInfo.LastMessageReceived >= _timeoutLength)
                {
                    UserInfo removeUserInfo = null;
                    Conversations.TryRemove(userInfo.ConversationReference.User.Id, out removeUserInfo);

                    var activity = userInfo.ConversationReference.GetPostToBotMessage();
                    //clear the dialog stack and conversation state for this user
                    using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
                    {
                        var botData = scope.Resolve<IBotData>();
                        await botData.LoadAsync(CancellationToken.None);

                        var stack = scope.Resolve<IDialogStack>();
                        stack.Reset();

                        //botData.UserData.Clear();
                        botData.ConversationData.Clear();
                        botData.PrivateConversationData.Clear();
                        await botData.FlushAsync(CancellationToken.None);
                    }

                    MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);
                    var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), ConfigurationManager.AppSettings["MicrosoftAppId"], ConfigurationManager.AppSettings["MicrosoftAppPassword"]);
                    var reply = activity.CreateReply("I haven't heard from you in awhile.  Let me know when you want to talk.");
                    connectorClient.Conversations.SendToConversation(reply);

                    //await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
                }
            }
        }

        public static void MessageReceived(Activity activity)
        {
            UserInfo userInfo = null;
            if (Conversations.TryGetValue(activity.From.Id, out userInfo))
            {
                userInfo.LastMessageReceived = DateTime.UtcNow;
            }
            else
            {
                Conversations.TryAdd(activity.From.Id, new UserInfo()
                {
                    ConversationReference = activity.ToConversationReference(),
                    LastMessageReceived = DateTime.UtcNow
                });
            }
        }
    }
    public class UserInfo
    {
        public ConversationReference ConversationReference { get; set; }
        public DateTime LastMessageReceived { get; set; }
    }

然后在消息控制器中调用:

TimeoutConversations.MessageReceived(activity);

在本例中,它执行 10 秒超时,每 5 秒检查一次。这是一个基本的(有点草率的)计时器,用于超时对话。您可能会遇到错误,但您可以对其进行调整,直到它适合您的需要。使用 azure queue 之类的可能会更好。

这是用于实现此基本功能的 v4 的 DCR: https://github.com/microsoft/botframework-sdk/issues/5237

【讨论】:

  • 对于迟到的回复 Dana 表示歉意。它工作得很好。非常感谢您的帮助!
猜你喜欢
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多