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); } }
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); }
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); } }
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); } }
async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token) { await botData.LoadAsync(token); try { await this.inner.PostAsync(activity, token); } finally { await botData.FlushAsync(token); } }
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)); }
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); }