public async Task <DialogTurnResult> ShowEventsSummary(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var tokenResponse = sc.Result as TokenResponse; var state = await Accessor.GetAsync(sc.Context); if (state.SummaryEvents == null) { // this will lead to error when test if (string.IsNullOrEmpty(state.APIToken)) { state.Clear(); return(await sc.EndDialogAsync(true)); } var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource); var searchDate = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, state.GetUserTimeZone()); if (state.StartDate.Any()) { searchDate = state.StartDate.Last(); } var results = await GetEventsByTime(new List <DateTime>() { searchDate }, state.StartTime, state.EndDate, state.EndTime, state.GetUserTimeZone(), calendarService); var searchedEvents = new List <EventModel>(); bool searchTodayMeeting = state.StartDate.Any() && !state.StartTime.Any() && !state.EndDate.Any() && !state.EndTime.Any() && EventModel.IsSameDate(searchDate, TimeConverter.ConvertUtcToUserTime(DateTime.UtcNow, state.GetUserTimeZone())); foreach (var item in results) { if (!searchTodayMeeting || item.StartTime >= DateTime.UtcNow) { searchedEvents.Add(item); } } if (searchedEvents.Count == 0) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowNoMeetingMessage)); state.Clear(); return(await sc.EndDialogAsync(true)); } else { var responseParams = new StringDictionary() { { "Count", searchedEvents.Count.ToString() }, { "EventName1", searchedEvents[0].Title }, { "EventDuration", searchedEvents[0].ToDurationString() }, }; if (searchedEvents.Count == 1) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowOneMeetingSummaryMessage, ResponseBuilder, responseParams)); } else { responseParams.Add("EventName2", searchedEvents[searchedEvents.Count - 1].Title); responseParams.Add("EventTime", SpeakHelper.ToSpeechMeetingTime(TimeConverter.ConvertUtcToUserTime(searchedEvents[searchedEvents.Count - 1].StartTime, state.GetUserTimeZone()), searchedEvents[searchedEvents.Count - 1].IsAllDay == true)); await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowMultipleMeetingSummaryMessage, ResponseBuilder, responseParams)); } } await ShowMeetingList(sc, searchedEvents.GetRange(0, Math.Min(CalendarSkillState.PageSize, searchedEvents.Count)), false); state.Clear(); state.SummaryEvents = searchedEvents; } else { await ShowMeetingList(sc, state.SummaryEvents.GetRange(state.ShowEventIndex *CalendarSkillState.PageSize, Math.Min(CalendarSkillState.PageSize, state.SummaryEvents.Count - (state.ShowEventIndex *CalendarSkillState.PageSize))), false); } return(await sc.NextAsync()); } catch (SkillException ex) { await HandleDialogExceptions(sc, ex); return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs)); } catch (Exception ex) { await HandleDialogExceptions(sc, ex); return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs)); } }
public async Task <DialogTurnResult> ShowNextEvent(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); AskParameterModel askParameter = new AskParameterModel(state.AskParameterContent); if (string.IsNullOrEmpty(state.APIToken)) { return(await sc.EndDialogAsync(true)); } var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource); var eventList = await calendarService.GetUpcomingEvents(); var nextEventList = new List <EventModel>(); foreach (var item in eventList) { if (item.IsCancelled != true && (nextEventList.Count == 0 || nextEventList[0].StartTime == item.StartTime)) { nextEventList.Add(item); } } if (nextEventList.Count == 0) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowNoMeetingMessage)); } else { if (nextEventList.Count == 1) { // if user asked for specific details if (askParameter.NeedDetail) { var responseParams = new StringDictionary() { { "EventName", nextEventList[0].Title }, { "EventStartTime", TimeConverter.ConvertUtcToUserTime(nextEventList[0].StartTime, state.GetUserTimeZone()).ToString("h:mm tt") }, { "EventEndTime", TimeConverter.ConvertUtcToUserTime(nextEventList[0].EndTime, state.GetUserTimeZone()).ToString("h:mm tt") }, { "EventDuration", nextEventList[0].ToDurationString() }, { "EventLocation", nextEventList[0].Location }, }; await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.BeforeShowEventDetails, ResponseBuilder, responseParams)); if (askParameter.NeedTime) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ReadTime, ResponseBuilder, responseParams)); } if (askParameter.NeedDuration) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ReadDuration, ResponseBuilder, responseParams)); } if (askParameter.NeedLocation) { // for some event there might be no localtion. if (string.IsNullOrEmpty(responseParams["EventLocation"])) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ReadNoLocation)); } else { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ReadLocation, ResponseBuilder, responseParams)); } } } var speakParams = new StringDictionary() { { "EventName", nextEventList[0].Title }, { "PeopleCount", nextEventList[0].Attendees.Count.ToString() }, }; speakParams.Add("EventTime", SpeakHelper.ToSpeechMeetingTime(TimeConverter.ConvertUtcToUserTime(nextEventList[0].StartTime, state.GetUserTimeZone()), nextEventList[0].IsAllDay == true)); if (string.IsNullOrEmpty(nextEventList[0].Location)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowNextMeetingNoLocationMessage, ResponseBuilder, speakParams)); } else { speakParams.Add("Location", nextEventList[0].Location); await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowNextMeetingMessage, ResponseBuilder, speakParams)); } } else { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(SummaryResponses.ShowMultipleNextMeetingMessage)); } await ShowMeetingList(sc, nextEventList, true); } state.Clear(); return(await sc.EndDialogAsync(true)); } catch (SkillException ex) { await HandleDialogExceptions(sc, ex); return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs)); } catch (Exception ex) { await HandleDialogExceptions(sc, ex); return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs)); } }
public async Task <DialogTurnResult> AfterUpdateStartTime(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); var events = new List <EventModel>(); var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource); var searchByEntities = state.OriginalStartDate.Any() || state.OriginalStartTime.Any() || state.Title != null; if (state.OriginalStartDate.Any() || state.OriginalStartTime.Any()) { events = await GetEventsByTime(state.OriginalStartDate, state.OriginalStartTime, state.OriginalEndDate, state.OriginalEndTime, state.GetUserTimeZone(), calendarService); state.OriginalStartDate = new List <DateTime>(); state.OriginalStartTime = new List <DateTime>(); state.OriginalEndDate = new List <DateTime>(); state.OriginalStartTime = new List <DateTime>(); } else if (state.Title != null) { events = await calendarService.GetEventsByTitle(state.Title); state.Title = null; } else { sc.Context.Activity.Properties.TryGetValue("OriginText", out var content); var userInput = content != null?content.ToString() : sc.Context.Activity.Text; try { IList <DateTimeResolution> dateTimeResolutions = sc.Result as List <DateTimeResolution>; if (dateTimeResolutions.Count > 0) { foreach (var resolution in dateTimeResolutions) { if (resolution.Value == null) { continue; } var startTimeValue = DateTime.Parse(resolution.Value); if (startTimeValue == null) { continue; } var dateTimeConvertType = resolution.Timex; bool isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, dateTimeResolutions.First().Value, dateTimeResolutions.First().Timex); startTimeValue = isRelativeTime ? TimeZoneInfo.ConvertTime(startTimeValue, TimeZoneInfo.Local, state.GetUserTimeZone()) : startTimeValue; startTimeValue = TimeConverter.ConvertLuisLocalToUtc(startTimeValue, state.GetUserTimeZone()); events = await calendarService.GetEventsByStartTime(startTimeValue); if (events != null && events.Count > 0) { break; } } } } catch { } if (events == null || events.Count <= 0) { state.Title = userInput; events = await calendarService.GetEventsByTitle(userInput); } } state.Events = events; if (events.Count <= 0) { if (searchByEntities) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(UpdateEventResponses.EventWithStartTimeNotFound)); state.Clear(); return(await sc.CancelAllDialogsAsync()); } else { return(await sc.BeginDialogAsync(Actions.UpdateStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NoEvent))); } } else if (events.Count > 1) { var options = new PromptOptions() { Choices = new List <Choice>(), }; for (var i = 0; i < events.Count; i++) { var item = events[i]; var choice = new Choice() { Value = string.Empty, Synonyms = new List <string> { (i + 1).ToString(), item.Title }, }; options.Choices.Add(choice); } var replyToConversation = sc.Context.Activity.CreateReply(UpdateEventResponses.MultipleEventsStartAtSameTime); replyToConversation.AttachmentLayout = AttachmentLayoutTypes.Carousel; replyToConversation.Attachments = new List <Microsoft.Bot.Schema.Attachment>(); var cardsData = new List <CalendarCardData>(); foreach (var item in events) { var meetingCard = item.ToAdaptiveCardData(state.GetUserTimeZone()); var replyTemp = sc.Context.Activity.CreateAdaptiveCardReply(CalendarMainResponses.GreetingMessage, item.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", meetingCard); replyToConversation.Attachments.Add(replyTemp.Attachments[0]); } options.Prompt = replyToConversation; return(await sc.PromptAsync(Actions.EventChoice, options)); } else { return(await sc.EndDialogAsync(true)); } } catch { await HandleDialogExceptions(sc); throw; } }
public async Task <DialogTurnResult> ShowNextEvent(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.APIToken)) { return(await sc.EndDialogAsync(true)); } var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource); var eventList = await calendarService.GetUpcomingEvents(); var nextEventList = new List <EventModel>(); foreach (var item in eventList) { if (item.IsCancelled != true && (nextEventList.Count == 0 || nextEventList[0].StartTime == item.StartTime)) { nextEventList.Add(item); } } if (nextEventList.Count == 0) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(NextMeetingResponses.ShowNoMeetingMessage)); } else { if (nextEventList.Count == 1) { var speakParams = new StringDictionary() { { "EventName", nextEventList[0].Title }, { "PeopleCount", nextEventList[0].Attendees.Count.ToString() }, }; if (nextEventList[0].IsAllDay == true) { speakParams.Add("EventTime", TimeConverter.ConvertUtcToUserTime(nextEventList[0].StartTime, state.GetUserTimeZone()).ToString("MMMM dd all day")); } else { speakParams.Add("EventTime", TimeConverter.ConvertUtcToUserTime(nextEventList[0].StartTime, state.GetUserTimeZone()).ToString("h:mm tt")); } if (string.IsNullOrEmpty(nextEventList[0].Location)) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(NextMeetingResponses.ShowNextMeetingNoLocationMessage, ResponseBuilder, speakParams)); } else { speakParams.Add("Location", nextEventList[0].Location); await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(NextMeetingResponses.ShowNextMeetingMessage, ResponseBuilder, speakParams)); } } else { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(NextMeetingResponses.ShowMultipleNextMeetingMessage)); } await ShowMeetingList(sc, nextEventList, true); } state.Clear(); return(await sc.EndDialogAsync(true)); } catch { await HandleDialogExceptions(sc); throw; } }
public async Task <DialogTurnResult> FromTokenToStartTime(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.APIToken)) { return(await sc.EndDialogAsync(true)); } var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient()); var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource); return(await sc.BeginDialogAsync(Actions.UpdateStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotFound))); } catch { await HandleDialogExceptions(sc); throw; } }
public async Task <DialogTurnResult> UpdateEventTime(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); var confirmResult = (bool)sc.Result; if (confirmResult) { var newStartTime = (DateTime)state.NewStartDateTime; var origin = state.Events[0]; var updateEvent = new EventModel(origin.Source); var last = origin.EndTime - origin.StartTime; updateEvent.StartTime = newStartTime; updateEvent.EndTime = (newStartTime + last).AddSeconds(1); updateEvent.TimeZone = TimeZoneInfo.Utc; updateEvent.Id = origin.Id; var calendarAPI = GraphClientHelper.GetCalendarService(state.APIToken, state.EventSource, ServiceManager.GetGoogleClient()); var calendarService = ServiceManager.InitCalendarService(calendarAPI, state.EventSource); var newEvent = await calendarService.UpdateEventById(updateEvent); var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(UpdateEventResponses.EventUpdated, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData(state.GetUserTimeZone())); await sc.Context.SendActivityAsync(replyMessage); } else { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(CalendarSharedResponses.ActionEnded)); } state.Clear(); return(await sc.EndDialogAsync(true)); } catch { await HandleDialogExceptions(sc); throw; } }
public async Task <DialogTurnResult> CheckTimeRemain(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) { try { var state = await Accessor.GetAsync(sc.Context); if (string.IsNullOrEmpty(state.APIToken)) { return(await sc.EndDialogAsync(true)); } var calendarService = ServiceManager.InitCalendarService(state.APIToken, state.EventSource); var eventList = await calendarService.GetUpcomingEvents(); var nextEventList = new List <EventModel>(); foreach (var item in eventList) { var itemUserTimeZoneTime = TimeZoneInfo.ConvertTime(item.StartTime, TimeZoneInfo.Utc, state.GetUserTimeZone()); if (item.IsCancelled != true && nextEventList.Count == 0) { if (state.OrderReference == "next") { nextEventList.Add(item); } else if (state.StartDate.Any() && itemUserTimeZoneTime.DayOfYear == state.StartDate[0].DayOfYear) { nextEventList.Add(item); } else if (state.StartTime.Any() && itemUserTimeZoneTime == state.StartTime[0]) { nextEventList.Add(item); } else if (state.Title != null && item.Title.Equals(state.Title, StringComparison.CurrentCultureIgnoreCase)) { nextEventList.Add(item); } } } if (nextEventList.Count == 0) { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(TimeRemainResponses.ShowNoMeetingMessage)); } else { var userTimeZone = state.GetUserTimeZone(); var timeNow = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local, userTimeZone); var timeDiff = TimeZoneInfo.ConvertTime(nextEventList[0].StartTime, TimeZoneInfo.Utc, userTimeZone) - timeNow; var timeDiffMinutes = (int)timeDiff.TotalMinutes % 60; var timeDiffHours = (int)timeDiff.TotalMinutes / 60; var timeDiffDays = timeDiff.Days; var tokens = new StringDictionary() { { "RemainingTime", string.Empty }, { "Title", string.Empty }, { "Time", string.Empty }, { "TimeSpeak", string.Empty } }; var remainingMinutes = string.Empty; var remainingHours = string.Empty; var remainingDays = string.Empty; if (timeDiffMinutes > 0) { if (timeDiffMinutes > 1) { remainingMinutes = string.Format(CommonStrings.TimeFormatMinutes, timeDiffMinutes) + " "; } else { remainingMinutes = string.Format(CommonStrings.TimeFormatMinute, timeDiffMinutes) + " "; } } if (timeDiffHours > 0) { if (timeDiffHours > 1) { remainingHours = string.Format(CommonStrings.TimeFormatHours, timeDiffHours) + " "; } else { remainingHours = string.Format(CommonStrings.TimeFormatHour, timeDiffHours) + " "; } } if (timeDiffDays > 0) { if (timeDiffDays > 1) { remainingDays = string.Format(CommonStrings.TimeFormatDays, timeDiffDays) + " "; } else { remainingDays = string.Format(CommonStrings.TimeFormatDay, timeDiffDays) + " "; } } var remainingTime = $"{remainingDays}{remainingHours}{remainingMinutes}"; tokens["RemainingTime"] = remainingTime; if (state.OrderReference == "next") { await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(TimeRemainResponses.ShowNextMeetingTimeRemainingMessage, ResponseBuilder, tokens)); } else { var timeToken = string.Empty; var timeSpeakToken = string.Empty; if (state.StartDate.Any()) { timeSpeakToken += $"{state.StartDate[0].ToSpeechDateString()} "; timeToken += $"{state.StartDate[0].ToShortDateString()} "; } if (state.StartTime.Any()) { timeSpeakToken += $"{state.StartTime[0].ToSpeechTimeString()}"; timeToken += $"{state.StartTime[0].ToShortTimeString()}"; } if (timeSpeakToken.Length > 0) { tokens["TimeSpeak"] = CommonStrings.SpokenTimePrefix_One + " " + timeSpeakToken; } if (timeToken.Length > 0) { tokens["Time"] = CommonStrings.SpokenTimePrefix_One + " " + timeToken; } if (state.Title != null) { tokens["Title"] = string.Format(CalendarCommonStrings.WithTheSubject, state.Title); } await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(TimeRemainResponses.ShowTimeRemainingMessage, ResponseBuilder, tokens)); } } state.Clear(); return(await sc.EndDialogAsync(true)); } catch { await HandleDialogExceptions(sc); throw; } }