how to detect bot Idleness on Bot Framework

时光怂恿深爱的人放手 提交于 2021-01-16 03:52:52

问题


I'm using bot framework V3 with C#. I need to identify when my bot is idle for more than 5 minutes. I've tried to handle bot idleness via the MessageController but my attempt seems not to work out.

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;
}

What could be wrong? Any sample could you could share please? Thx in advance!


回答1:


First, you're only delaying for 5 seconds (5000 miliseconds) and not 5 minutes.

Anyhow, you can try the following approach. Add this class:

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; }
    }

And then in messages controller, call:

TimeoutConversations.MessageReceived(activity);

In this example, it is doing a 10 second timeout, checking every 5 seconds. This is a basic (somewhat sloppy) timer to time out conversations. You'll probably run into bugs, but you can tweak it until it fits your needs. Using an azure queue or something might be better.

Here is a DCR for v4 to implement this basic functionality: https://github.com/microsoft/botframework-sdk/issues/5237



来源:https://stackoverflow.com/questions/56894802/how-to-detect-bot-idleness-on-bot-framework

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