public async Task <MeetingTimeSuggestionsResult> FindMeetingSuggestion(FindRoomRequest request) { List <Attendee> attendees = new List <Attendee>(); // Adding placeholder user to be able to remove the // Required flag on the user looking for available rooms. // An empty collection causes findMeetingTimes to look for free time slots for only the organizer. if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["PlaceholderAttendeeEmail"])) { attendees = new List <Attendee>() { new Attendee() { EmailAddress = new EmailAddress() { Address = WebConfigurationManager.AppSettings["PlaceholderAttendeeEmail"] } } }; } var locationConstraint = new LocationConstraint() { IsRequired = true, SuggestLocation = true, }; var timeConstraint = new TimeConstraint() { ActivityDomain = ActivityDomain.Unrestricted, Timeslots = new List <TimeSlot>() { new TimeSlot() { Start = new DateTimeTimeZone() { DateTime = request.From.ToString(), TimeZone = "UTC" }, End = new DateTimeTimeZone() { DateTime = request.To.ToString(), TimeZone = "UTC" } } } }; return(await _graphClient.Me.FindMeetingTimes(attendees, TimeConstraint : timeConstraint, MeetingDuration : new Duration(request.Duration), IsOrganizerOptional : attendees.Any(), LocationConstraint : locationConstraint) .Request() .PostAsync()); }
public async Task GetAvailableRooms(IDialogContext context, LuisResult result) { var entityInput = "The next hour"; var request = new FindRoomRequest(); var entity = result.Entities.FirstOrDefault(); if (entity != null && entity.Resolution.Any()) { entityInput = entity.Entity; Dictionary <string, object> val; if (((List <object>)entity.Resolution["values"]).Count > 1) { val = ((List <object>)entity.Resolution["values"])[1] as Dictionary <string, object>; } else { val = ((List <object>)entity.Resolution["values"]).FirstOrDefault() as Dictionary <string, object>; } switch (entity.Type) { case EntityDatetimeDuration: if (val != null && ((string)val["type"]) == "duration") { var seconds = ((string)val["value"]); request.From = DateTimeHelper.Floor(DateTime.Now, new TimeSpan(0, 30, 0)); request.To = request.From; request.Duration = new TimeSpan(0, 0, int.Parse(seconds)); } break; case EntityDateTimeRange: if (val != null && ((string)val["type"]) == "datetimerange") { var start = ((string)val["start"]); var end = ((string)val["end"]); request.From = DateTime.Parse(start).ConvertToUniversalTime(context.GetUserTimeZoneName()); request.To = DateTime.Parse(end).ConvertToUniversalTime(context.GetUserTimeZoneName()); request.Duration = request.To - request.From; } break; case EntityTimeRange: if (val != null && ((string)val["type"]) == "timerange") { var start = ((string)val["start"]); var end = ((string)val["end"]); var serverDate = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Unspecified); var from = serverDate.Add(TimeSpan.Parse(start, CultureInfo.InvariantCulture)).ConvertToUniversalTime(context.GetUserTimeZoneName()); var to = serverDate.Add(TimeSpan.Parse(end, CultureInfo.InvariantCulture)).ConvertToUniversalTime(context.GetUserTimeZoneName()); if (from < DateTime.Now) { from = from.AddDays(1); to = to.AddDays(1); } request.From = from; request.To = to; var diff = to - from; if (diff.TotalMinutes < 60) { request.Duration = new TimeSpan(0, 30, 0); } } break; case EntityDate: if (val != null && ((string)val["type"]) == "datetime") { var value = ((string)val["value"]); request.From = DateTimeHelper.Floor(DateTime.Parse(value), new TimeSpan(0, 30, 0)).ConvertToUniversalTime(context.GetUserTimeZoneName()); request.To = request.From; } break; case EntityTime: if (val != null && ((string)val["type"]) == "time") { var value = ((string)val["value"]); var localTime = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Unspecified); var date = localTime.Add(TimeSpan.Parse(value, CultureInfo.InvariantCulture)).ConvertToUniversalTime(context.GetUserTimeZoneName()); if (date < DateTime.Now) { date = date.AddDays(1); } request.From = date; request.To = date; request.Duration = new TimeSpan(0, 30, 0); } break; default: var now = DateTimeHelper.Floor(DateTime.Now, new TimeSpan(0, 30, 0)).ConvertToUniversalTime(context.GetUserTimeZoneName()); request.From = now; request.To = now.AddHours(1); request.Duration = new TimeSpan(0, 30, 0); break; } } else { var now = DateTimeHelper.Floor(DateTime.Now, new TimeSpan(0, 30, 0)); request.From = now; request.To = now.AddHours(1); request.Duration = new TimeSpan(0, 30, 0); } var graphClient = GraphHelper.GetAuthenticadedClient(await context.GetAccessToken(AuthSettings.Scopes), context.GetUserTimeZoneName()); var calendarService = new CalendarService(graphClient); var response = await calendarService.FindMeetingSuggestion(request); var messageContent = string.Empty; if (response.MeetingTimeSuggestions.Any()) { var sb = new StringBuilder(); sb.Append($"{entityInput}, the following rooms are available: \n\n"); foreach (var mSuggestion in response.MeetingTimeSuggestions) { var start = DateTime.Parse(mSuggestion.MeetingTimeSlot.Start.DateTime).ToShortTimeString(); var end = DateTime.Parse(mSuggestion.MeetingTimeSlot.End.DateTime).ToShortTimeString(); var filteredRooms = mSuggestion.Locations.Where(l => !string.IsNullOrEmpty(l.LocationEmailAddress)); sb.Append($"**{start} - {end}** \n\n"); if (filteredRooms.Any()) { foreach (var location in filteredRooms) { sb.Append($"* {location.DisplayName}\n\n"); } } else { sb.Append("No meeting rooms available\n\n"); } } messageContent = sb.ToString(); } else { messageContent = "I'm unable to find any available meeting rooms."; } var message = context.MakeMessage(); message.TextFormat = "markdown"; message.Text = messageContent; await context.PostAsync(message); context.Wait(this.MessageReceived); }