简体   繁体   中英

how to detect bot Idleness on Bot Framework

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!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM