예제 #1
0
        async Task IPostToBot.PostAsync <T>(T item, CancellationToken token)
        {
            await botData.LoadAsync();

            try
            {
                await this.inner.Value.PostAsync <T>(item, token);
            }
            catch
            {
                await botData.FlushAsync();
                await PersistBotData(token : token);

                throw;
            }

            await botData.FlushAsync();

            // if botToUser is SendLastInline_BotToUser, we don't need to persist.
            // Inline reply will set the data
            bool inline = botToUser is SendLastInline_BotToUser || botToUser is BotToUserTextWriter;

            if (!inline)
            {
                await PersistBotData(token : token);
            }
        }
예제 #2
0
        private async Task <Activity> HandleSystemMessage(Activity message)
        {
            if (message.Type == ActivityTypes.DeleteUserData)
            {
                // Implement user deletion here
                // If we handle user deletion, return a real message
            }
            else if (message.Type == ActivityTypes.ConversationUpdate)
            {
                Trace.TraceInformation("Conversation update");
                ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl));

                using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    IBotData botData = scope.Resolve <IBotData>();

                    await botData.LoadAsync(CancellationToken.None);

                    if (!botData.ConversationData.GetValueOrDefault <bool>("init"))
                    {
                        botData.ConversationData.SetValue("init", true);

                        var reply = message.CreateReply("Hi!I'll post some random question every morning.");
                        await client.Conversations.SendToConversationAsync(reply);

                        var reply2 = message.CreateReply("Commands: " + Environment.NewLine +
                                                         "\t\t  - type `tours` to get a list of tours;" + Environment.NewLine +
                                                         "\t\t  - type `new` to get a new question;" + Environment.NewLine +
                                                         "\t\t  - type `answer` to get an answer to the current question;" + Environment.NewLine +
                                                         "\t\t  - type `level` to select a complexity level");
                        await client.Conversations.SendToConversationAsync(reply2);

                        var reply3 = message.CreateReply("*All questions are taken from* " + "https://db.chgk.info/" +
                                                         Environment.NewLine + "Copyright: " + "https://db.chgk.info/copyright");
                        await client.Conversations.SendToConversationAsync(reply3);

                        var reply4 = message.CreateReply("Good luck! ;-)");
                        await client.Conversations.SendToConversationAsync(reply4);
                    }
                }
                // Handle conversation state changes, like members being added and removed
                // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
                // Not available in all channels
            }
            else if (message.Type == ActivityTypes.ContactRelationUpdate)
            {
                // Handle add/remove from contact lists
                // Activity.From + Activity.Action represent what happened
            }
            else if (message.Type == ActivityTypes.Typing)
            {
                // Handle knowing tha the user is typing
            }
            else if (message.Type == ActivityTypes.Ping)
            {
            }

            return(null);
        }
예제 #3
0
        public static async Task Resume(ConversationHistory history)
        {
            Activity message = null;

            Trace.TraceInformation($"Resuming  {history.PartitionKey} {history.PartitionKey}");
            try
            {
                message = JsonConvert.DeserializeObject <ConversationReference>(history.Conversation).GetPostToBotMessage();
                ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl));

                using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    IBotData botData = scope.Resolve <IBotData>();

                    await botData.LoadAsync(CancellationToken.None);

                    string todayDate = DateTime.UtcNow.ToShortDateString();
                    if (botData.ConversationData.GetValueOrDefault <string>("today") != todayDate)
                    {
                        botData.ConversationData.SetValue("today", todayDate);
                        await botData.FlushAsync(CancellationToken.None);

                        await botData.LoadAsync(CancellationToken.None);

                        IMessageActivity temp = message.CreateReply().AsMessageActivity();

                        IMessageActivity reply = await RootDialog.PostNewQuestion(botData.ConversationData, temp);

                        if (reply != null)
                        {
                            await client.Conversations.SendToConversationAsync((Activity)reply);
                        }

                        //flush dialog stack
                        await botData.FlushAsync(CancellationToken.None);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError($"Exception when resuming conversation {message.Conversation?.Id}", ex);
            }
        }
예제 #4
0
        async Task IPostToBot.PostAsync <T>(T item, CancellationToken token)
        {
            await botData.LoadAsync(token);

            try
            {
                await this.inner.Value.PostAsync <T>(item, token);
            }
            finally
            {
                await botData.FlushAsync(token);
            }
        }
예제 #5
0
        async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
        {
            await botData.LoadAsync(token);

            try
            {
                await this.inner.PostAsync(activity, token);
            }
            finally
            {
                await botData.FlushAsync(token);
            }
        }
예제 #6
0
        async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
        {
            await botData.LoadAsync(token);

            try
            {
                this.queue.Post(activity);
                var loop = this.inner.Value;
                await loop.PollAsync(token);
            }
            finally
            {
                await botData.FlushAsync(token);
            }
        }
        /// <summary>
        /// POST: api/Messages
        /// Receive a message from a user and reply to it
        /// </summary>
        public async Task <HttpResponseMessage> Post([FromBody] Activity activity)
        {
            switch (activity.GetActivityType())
            {
            // all messages pass through one dialog for now
            case ActivityTypes.Message:
                LuisModelAttribute attr    = new LuisModelAttribute(ConfigurationManager.AppSettings[Constants.LuisModelIdKey], ConfigurationManager.AppSettings[Constants.LuisSubscriptionKey]);
                LuisService        luisSvc = new LuisService(attr);
                await Conversation.SendAsync(activity, () => new GitHubLuisDialog(luisSvc));

                break;

            // send a "hello" to someone who just joined the conversation (not all channels support this)
            case ActivityTypes.ConversationUpdate:
                IConversationUpdateActivity update = activity;
                using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
                {
                    IConnectorClient client = scope.Resolve <IConnectorClient>();
                    if (update.MembersAdded.Any())
                    {
                        Activity reply = activity.CreateReply();
                        IEnumerable <ChannelAccount> newMembers = update.MembersAdded?.Where(t => t.Id != activity.Recipient.Id);
                        foreach (var newMember in newMembers)
                        {
                            reply.Text = Constants.DemoText + $"Welcome {newMember.Name}! I can help you with getting information about your GitHub repos.";

                            IBotData data = scope.Resolve <IBotData>();
                            await data.LoadAsync(CancellationToken.None);

                            if (data.UserData.ContainsKey(Constants.AuthTokenKey))
                            {
                                reply.Text += " It looks like you're already logged in, so what can I help you with?";
                            }
                            else
                            {
                                reply.Text += " To get started, type **login** to authorize me to talk to GitHub on your behalf, or type **help** to get more information.";
                            }

                            await client.Conversations.ReplyToActivityAsync(reply);
                        }
                    }
                }
                break;
            }

            return(new HttpResponseMessage(HttpStatusCode.Accepted));
        }
예제 #8
0
        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result)
        {
            IMessageActivity activity = await result;

            ConversationStarter.SaveConversation(activity);

            string text = activity.Text.ToLower().Trim();

            context.ConversationData.SetValue(TIMER, false);//cancel timer

            //string text2 = activity.RemoveRecipientMention();

            if (text.EndsWith("answer"))
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: answer case.");

                QuestionItem q = context.ConversationData.GetValueOrDefault <QuestionItem>(KEY);

                if (q != null)
                {
                    IMessageActivity reply = context.MakeMessage();

                    reply.ReplyToId = q.Id.ToString();

                    CardAction questionAction = new CardAction
                    {
                        Title = "New question",
                        Type  = "imBack",
                        Value = "new"
                    };

                    reply.Text = $"**Question:**<br/>{q.Question}<br/>**Answer:**<br/>{q.Answer}";

                    if (!string.IsNullOrWhiteSpace(q.Rating))
                    {
                        reply.Text += $"<br/><br/>**Rating: **{q.Rating}";
                    }
                    if (q.Complexity.HasValue)
                    {
                        reply.Text += $"<br/>**Level:** {q.Complexity}";
                    }

                    if (!string.IsNullOrWhiteSpace(q.Comments))
                    {
                        reply.Text += $"<br/>**Comments:**<br/>{q.Comments}";
                    }
                    if (!string.IsNullOrWhiteSpace(q.Sources))
                    {
                        reply.Text += $"<br/>**Source:**<br/>{q.Sources}";
                    }

                    reply.Attachments = q.AnswerImageUrls.Select(ToAttachement).ToList();

                    reply.SuggestedActions = new SuggestedActions
                    {
                        Actions = new List <CardAction> {
                            questionAction
                        }
                    };

                    if (IsTimerFeatureEnabled())
                    {
                        reply.SuggestedActions.Actions.Add(new CardAction
                        {
                            Title = "New question with 1 min timer",
                            Type  = "imBack",
                            Value = "new 1 min"
                        });

                        reply.SuggestedActions.Actions.Add(new CardAction
                        {
                            Title = "New question with 2 min timer",
                            Type  = "imBack",
                            Value = "new 2 min"
                        });
                    }

                    await context.PostAsync(reply);
                }
                else
                {
                    await context.SayAsync("Sorry, I can't find the question to answer.");
                }
            }
            else if (text.Contains("new"))
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: new case.");
                var newQuestion = await PostNewQuestion(context.ConversationData, context.MakeMessage());

                if (newQuestion != null)
                {
                    await context.PostAsync(newQuestion);
                }
                else
                {
                    Trace.TraceError("NULL in PostNewQuestion");
                    await context.SayAsync("I'm sorry - something wrong has happened.");
                }

                if (IsTimerFeatureEnabled())
                {
                    Match match = Regex.Match(text, "new(\\s)+([1-5])(\\s)?min");
                    if (match.Success)
                    {
                        string value   = match.Groups[2].Value;
                        int    minutes = int.Parse(value);
                        context.ConversationData.SetValue(TIMER, true);

                        Task timerTask = Task.Run(async() =>
                        {
                            await Task.Delay(TimeSpan.FromMinutes(minutes));

                            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
                            {
                                IBotData botData = scope.Resolve <IBotData>();
                                await botData.LoadAsync(CancellationToken.None);

                                if (botData.ConversationData.GetValueOrDefault <bool>(TIMER))
                                {
                                    context.ConversationData.SetValue(TIMER, false);
                                    await context.PostAsync("The time is over. (time)");
                                    await botData.FlushAsync(CancellationToken.None);
                                }
                            }
                        });

                        await context.SayAsync("(time)");
                    }
                }
            }
            else if (text.Contains("level"))
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: level case.");

                var match = Regex.Match(text, "level(\\s)+([0-5])");
                if (match.Success)
                {
                    string value = match.Groups[2].Value;
                    context.ConversationData.SetValue(KEY_LEVEL, byte.Parse(value));

                    await context.PostAsync("Level is set up to " + value);
                }
                else
                {
                    IMessageActivity          reply   = context.MakeMessage();
                    Dictionary <byte, string> options = Enumerable.Range(0, 6).ToDictionary(x => (byte)x, x => x == 0 ? "Random" : x.ToString());
                    PromptDialog.Choice(context, ResumeAfterSelectLevel, options.Keys, "Please select a level", descriptions: options.Values);
                    return;
                };
            }
            else if (text.Contains("clear conversation data"))
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: clear conversation data case.");
                context.ConversationData.Clear();
            }
            else if (text.Contains("help"))
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: help case.");
                await context.PostAsync("HELP");
            }
            else if (text.Contains("tours"))
            {
                await context.Forward(new TourDialog(), ResumeAfterNewOrderDialog, activity, CancellationToken.None);

                return;
            }
            else
            {
                Trace.TraceInformation("RootDialog.MessageReceivedAsync: other case.");
                if (context.ConversationData.GetValueOrDefault <bool>("init2"))//must not be executed on the first run
                {
                    await context.PostAsync("Sorry, I did not get it." + NL + NL + "HELP");
                }
                else
                {
                    context.ConversationData.SetValue("init2", true);
                }
            }

            context.Wait(MessageReceivedAsync);
        }