/// <summary> /// Mark To Do task completed step. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> MarkToDoTaskCompleted(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.OneNotePageId)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.SettingUpOneNoteMessage)); } var service = await this.toDoService.Init(state.MsGraphToken, state.OneNotePageId); var page = await service.GetDefaultToDoPage(); BotResponse botResponse; string taskToBeMarked = null; if (state.MarkOrDeleteAllTasksFlag) { await service.MarkAllToDoItemsCompleted(state.ToDoTaskAllActivities, page.ContentUrl); botResponse = ToDoBotResponses.AfterAllToDoTasksCompleted; } else { await service.MarkToDoItemCompleted(state.ToDoTaskActivities[state.ToDoTaskIndex], page.ContentUrl); botResponse = ToDoBotResponses.AfterToDoTaskCompleted; taskToBeMarked = state.ToDoTaskActivities[state.ToDoTaskIndex].Topic; } var todosAndPageIdTuple = await service.GetMyToDoList(); state.OneNotePageId = todosAndPageIdTuple.Item2; state.ToDoTaskAllActivities = todosAndPageIdTuple.Item1; var allTasksCount = state.ToDoTaskAllActivities.Count; var currentTaskIndex = state.ShowToDoPageIndex * state.PageSize; state.ToDoTaskActivities = state.ToDoTaskAllActivities.GetRange(currentTaskIndex, Math.Min(state.PageSize, allTasksCount - currentTaskIndex)); var markToDoAttachment = ToDoHelper.ToAdaptiveCardAttachmentForOtherFlows( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, taskToBeMarked, botResponse, ToDoBotResponses.ShowToDoTasks); var markToDoReply = sc.Context.Activity.CreateReply(); markToDoReply.Attachments.Add(markToDoAttachment); await sc.Context.SendActivityAsync(markToDoReply); return(await sc.EndDialogAsync(true)); } catch (Exception ex) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ex.Message)); await this.accessors.ToDoSkillState.SetAsync(sc.Context, new ToDoSkillState()); return(await sc.CancelAllDialogsAsync()); } }
/// <summary> /// Check if To Do task index is valid. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> AfterAskToDoTaskIndex(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.ToDoTaskContent) && !state.MarkOrDeleteAllTasksFlag && (state.ToDoTaskIndexes.Count == 0 || state.ToDoTaskIndexes[0] < 0 || state.ToDoTaskIndexes[0] >= state.ToDoTaskActivities.Count)) { var luisResult = await this.toDoSkillServices.LuisRecognizer.RecognizeAsync <ToDo>(sc.Context, cancellationToken); ToDoHelper.DigestLuisResult(luisResult, sc.Context.Activity.Text, ref state); } var matchedIndexes = Enumerable.Range(0, state.ToDoTaskAllActivities.Count) .Where(i => state.ToDoTaskAllActivities[i].Topic.Equals(state.ToDoTaskContent, StringComparison.OrdinalIgnoreCase)) .ToList(); if (matchedIndexes?.Count > 0) { state.ToDoTaskIndexes = matchedIndexes; return(await sc.EndDialogAsync(true)); } else { var userInput = sc.Context.Activity.Text; matchedIndexes = Enumerable.Range(0, state.ToDoTaskAllActivities.Count) .Where(i => state.ToDoTaskAllActivities[i].Topic.Equals(userInput, StringComparison.OrdinalIgnoreCase)) .ToList(); if (matchedIndexes?.Count > 0) { state.ToDoTaskIndexes = matchedIndexes; return(await sc.EndDialogAsync(true)); } } if (state.MarkOrDeleteAllTasksFlag) { return(await sc.EndDialogAsync(true)); } if (state.ToDoTaskIndexes.Count == 1 && state.ToDoTaskIndexes[0] >= 0 && state.ToDoTaskIndexes[0] < state.ToDoTaskActivities.Count) { state.ToDoTaskIndexes[0] = (state.PageSize * state.ShowToDoPageIndex) + state.ToDoTaskIndexes[0]; return(await sc.EndDialogAsync(true)); } else { state.ToDoTaskContent = null; return(await sc.BeginDialogAsync(Action.CollectToDoTaskIndex)); } }
/// <summary> /// Add To Do task step. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> AddToDoTask(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.OneNotePageId)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.SettingUpOneNoteMessage)); } var service = await this.toDoService.Init(state.MsGraphToken, state.OneNotePageId); var page = await service.GetDefaultToDoPage(); state.OneNotePageId = page.Id; await service.AddToDoToOneNote(state.ToDoTaskContent, page.ContentUrl); var todosAndPageIdTuple = await service.GetMyToDoList(); state.OneNotePageId = todosAndPageIdTuple.Item2; state.ToDoTaskAllActivities = todosAndPageIdTuple.Item1; state.ShowToDoPageIndex = 0; var rangeCount = Math.Min(state.PageSize, state.ToDoTaskAllActivities.Count); state.ToDoTaskActivities = state.ToDoTaskAllActivities.GetRange(0, rangeCount); var toDoListAttachment = ToDoHelper.ToAdaptiveCardAttachmentForOtherFlows( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, state.ToDoTaskContent, ToDoBotResponses.AfterToDoTaskAdded, ToDoBotResponses.ShowToDoTasks); var toDoListReply = sc.Context.Activity.CreateReply(); toDoListReply.Attachments.Add(toDoListAttachment); await sc.Context.SendActivityAsync(toDoListReply); return(await sc.EndDialogAsync(true)); } catch (Exception ex) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ex.Message)); await this.accessors.ToDoSkillState.SetAsync(sc.Context, new ToDoSkillState()); return(await sc.CancelAllDialogsAsync()); } }
/// <summary> /// Ask if confirm to delete the To Do task sub step. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> AskDeletionConfirmation(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (state.MarkOrDeleteAllTasksFlag) { var prompt = sc.Context.Activity.CreateReply(ToDoBotResponses.AskDeletionAllConfirmation); return(await sc.PromptAsync(Action.Prompt, new PromptOptions() { Prompt = prompt })); } else { var toDoTask = state.ToDoTaskAllActivities[state.ToDoTaskIndexes[0]].Topic; var token = new StringDictionary() { { "toDoTask", toDoTask } }; var response = ToDoHelper.GenerateResponseWithTokens(ToDoBotResponses.AskDeletionConfirmation, token); var prompt = sc.Context.Activity.CreateReply(response); prompt.Speak = response; return(await sc.PromptAsync(Action.Prompt, new PromptOptions() { Prompt = prompt })); } } catch (Exception ex) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ex.Message)); await this.accessors.ToDoSkillState.SetAsync(sc.Context, new ToDoSkillState()); return(await sc.CancelAllDialogsAsync()); } }
/// <summary> /// Check if To Do task index is valid. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> AfterAskToDoTaskIndex(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (!state.MarkOrDeleteAllTasksFlag && (state.ToDoTaskIndex < 0 || state.ToDoTaskIndex >= state.ToDoTaskActivities.Count)) { var luisResult = await this.toDoSkillServices.LuisRecognizer.RecognizeAsync <ToDo>(sc.Context, cancellationToken); ToDoHelper.DigestLuisResult(luisResult, sc.Context.Activity.Text, ref state); } if (state.MarkOrDeleteAllTasksFlag || (state.ToDoTaskIndex >= 0 && state.ToDoTaskIndex < state.ToDoTaskActivities.Count)) { return(await sc.EndDialogAsync(true)); } else { return(await sc.BeginDialogAsync(Action.CollectToDoTaskIndex)); } }
/// <summary> /// Determine if clear the context. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> ClearContext(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); var topIntent = ((ToDo)state.LuisResult)?.TopIntent().intent; if (topIntent == ToDo.Intent.ShowToDo) { state.ShowToDoPageIndex = 0; state.ToDoTaskActivities = new List <ToDoTaskActivityModel>(); state.ToDoTaskAllActivities = new List <ToDoTaskActivityModel>(); } else if (topIntent == ToDo.Intent.Next) { if ((state.ShowToDoPageIndex + 1) * state.PageSize < state.ToDoTaskAllActivities.Count) { state.ShowToDoPageIndex++; } } else if (topIntent == ToDo.Intent.Previous && state.ShowToDoPageIndex > 0) { state.ShowToDoPageIndex--; } else if (topIntent == ToDo.Intent.AddToDo) { state.ToDoTaskContent = null; await ToDoHelper.DigestLuisResultAsync(sc.Context, this.accessors); } else if (topIntent == ToDo.Intent.MarkToDo || topIntent == ToDo.Intent.DeleteToDo) { state.ToDoTaskIndexes = new List <int>(); state.MarkOrDeleteAllTasksFlag = false; state.ToDoTaskContent = null; await ToDoHelper.DigestLuisResultAsync(sc.Context, this.accessors); } return(await sc.NextAsync()); }
/// <summary> /// Delete To Do task step. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> DeleteToDoTask(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (state.DeleteTaskConfirmation) { if (string.IsNullOrEmpty(state.OneNotePageId)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.SettingUpOneNoteMessage)); } var service = await this.toDoService.Init(state.MsGraphToken, state.OneNotePageId); var page = await service.GetDefaultToDoPage(); string taskTopicToBeDeleted = null; if (state.MarkOrDeleteAllTasksFlag) { await service.DeleteAllToDos(state.ToDoTaskAllActivities, page.ContentUrl); state.ToDoTaskAllActivities = new List <ToDoTaskActivityModel>(); state.ToDoTaskActivities = new List <ToDoTaskActivityModel>(); state.ShowToDoPageIndex = 0; state.ToDoTaskIndexes = new List <int>(); } else { taskTopicToBeDeleted = state.ToDoTaskAllActivities[state.ToDoTaskIndexes[0]].Topic; var tasksToBeDeleted = new List <ToDoTaskActivityModel>(); state.ToDoTaskIndexes.ForEach(i => tasksToBeDeleted.Add(state.ToDoTaskAllActivities[i])); await service.DeleteToDos(tasksToBeDeleted, page.ContentUrl); var todosAndPageIdTuple = await service.GetMyToDoList(); state.OneNotePageId = todosAndPageIdTuple.Item2; state.ToDoTaskAllActivities = todosAndPageIdTuple.Item1; var allTasksCount = state.ToDoTaskAllActivities.Count; var currentTaskIndex = state.ShowToDoPageIndex * state.PageSize; while (currentTaskIndex >= allTasksCount && currentTaskIndex >= state.PageSize) { currentTaskIndex -= state.PageSize; state.ShowToDoPageIndex--; } state.ToDoTaskActivities = state.ToDoTaskAllActivities.GetRange(currentTaskIndex, Math.Min(state.PageSize, allTasksCount - currentTaskIndex)); } if (state.MarkOrDeleteAllTasksFlag) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.AfterAllTasksDeleted)); } else { if (state.ToDoTaskActivities.Count > 0) { var deletedToDoListAttachment = ToDoHelper.ToAdaptiveCardAttachmentForOtherFlows( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, taskTopicToBeDeleted, ToDoBotResponses.AfterTaskDeleted, ToDoBotResponses.ShowToDoTasks); var deletedToDoListReply = sc.Context.Activity.CreateReply(); deletedToDoListReply.Attachments.Add(deletedToDoListAttachment); await sc.Context.SendActivityAsync(deletedToDoListReply); } else { var token1 = new StringDictionary() { { "taskContent", taskTopicToBeDeleted } }; var response1 = ToDoHelper.GenerateResponseWithTokens(ToDoBotResponses.AfterTaskDeleted, token1); var token2 = new StringDictionary() { { "taskCount", "0" } }; var response2 = ToDoHelper.GenerateResponseWithTokens(ToDoBotResponses.ShowToDoTasks, token2); var response = response1 + " " + response2.Remove(response2.Length - 1) + "."; var botResponse = sc.Context.Activity.CreateReply(response); botResponse.Speak = response; await sc.Context.SendActivityAsync(botResponse); } } } else { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.AnythingElseCanDo)); } return(await sc.EndDialogAsync(true)); } catch (Exception ex) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ex.Message)); await this.accessors.ToDoSkillState.SetAsync(sc.Context, new ToDoSkillState()); return(await sc.CancelAllDialogsAsync()); } }
/// <summary> /// Show To Do tasks step. /// </summary> /// <param name="sc">current step context.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>Task completion.</returns> public async Task <DialogTurnResult> ShowToDoTasks(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await this.accessors.ToDoSkillState.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.OneNotePageId)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.SettingUpOneNoteMessage)); } var topIntent = ((ToDo)state.LuisResult)?.TopIntent().intent; if (topIntent == ToDo.Intent.ShowToDo || topIntent == ToDo.Intent.None) { var service = await this.toDoService.Init(state.MsGraphToken, state.OneNotePageId); var todosAndPageIdTuple = await service.GetMyToDoList(); state.OneNotePageId = todosAndPageIdTuple.Item2; state.ToDoTaskAllActivities = todosAndPageIdTuple.Item1; } var allTasksCount = state.ToDoTaskAllActivities.Count; var currentTaskIndex = state.ShowToDoPageIndex * state.PageSize; state.ToDoTaskActivities = state.ToDoTaskAllActivities.GetRange(currentTaskIndex, Math.Min(state.PageSize, allTasksCount - currentTaskIndex)); if (state.ToDoTaskActivities.Count <= 0) { return(await sc.NextAsync()); } else { Attachment toDoListAttachment = null; if (topIntent == ToDo.Intent.ShowToDo || topIntent == ToDo.Intent.None) { toDoListAttachment = ToDoHelper.ToAdaptiveCardAttachmentForShowToDos( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, ToDoBotResponses.ShowToDoTasks, ToDoBotResponses.ReadToDoTasks); } else if (topIntent == ToDo.Intent.Next) { toDoListAttachment = ToDoHelper.ToAdaptiveCardAttachmentForShowToDos( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, ToDoBotResponses.ShowNextToDoTasks, null); } else if (topIntent == ToDo.Intent.Previous) { toDoListAttachment = ToDoHelper.ToAdaptiveCardAttachmentForShowToDos( state.ToDoTaskActivities, state.ToDoTaskAllActivities.Count, ToDoBotResponses.ShowPreviousToDoTasks, null); } var toDoListReply = sc.Context.Activity.CreateReply(); toDoListReply.Attachments.Add(toDoListAttachment); await sc.Context.SendActivityAsync(toDoListReply); if ((topIntent == ToDo.Intent.ShowToDo || topIntent == ToDo.Intent.None) && allTasksCount > (state.ShowToDoPageIndex + 1) * state.PageSize) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ToDoBotResponses.ShowingMoreTasks)); } return(await sc.EndDialogAsync(true)); } } catch (Exception ex) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(ex.Message)); await this.accessors.ToDoSkillState.SetAsync(sc.Context, new ToDoSkillState()); return(await sc.CancelAllDialogsAsync()); } }