public async Task <DialogTurnResult> CollectContent(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                bool?isTitleSkipByDefault = false;
                isTitleSkipByDefault = Settings.DefaultValue?.CreateMeeting?.First(item => item.Name == "EventTitle")?.IsSkipByDefault;

                bool?isContentSkipByDefault = false;
                isContentSkipByDefault = Settings.DefaultValue?.CreateMeeting?.First(item => item.Name == "EventContent")?.IsSkipByDefault;

                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (sc.Result != null || (state.CreateHasDetail && isTitleSkipByDefault.GetValueOrDefault()) || state.RecreateState == RecreateEventState.Subject)
                {
                    if (string.IsNullOrEmpty(state.Title))
                    {
                        if (state.CreateHasDetail && isTitleSkipByDefault.GetValueOrDefault() && state.RecreateState != RecreateEventState.Subject)
                        {
                            state.Title = CreateEventWhiteList.GetDefaultTitle();
                        }
                        else
                        {
                            sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                            var title = content != null?content.ToString() : sc.Context.Activity.Text;

                            if (CreateEventWhiteList.IsSkip(title))
                            {
                                state.Title = CreateEventWhiteList.GetDefaultTitle();
                            }
                            else
                            {
                                state.Title = title;
                            }
                        }
                    }
                }

                if (string.IsNullOrEmpty(state.Content) && (!(state.CreateHasDetail && isContentSkipByDefault.GetValueOrDefault()) || state.RecreateState == RecreateEventState.Content))
                {
                    return(await sc.PromptAsync(Actions.Prompt, new PromptOptions { Prompt = ResponseManager.GetResponse(CreateEventResponses.NoContent) }, cancellationToken));
                }
                else
                {
                    return(await sc.NextAsync(cancellationToken : cancellationToken));
                }
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #2
0
        private IList <DateTimeResolution> GetTimeFromMessage(string message, string culture)
        {
            if (CreateEventWhiteList.IsSkip(message))
            {
                // Can not skip
                IsSkip = true;
                return(new List <DateTimeResolution>());
            }

            IList <DateTimeResolution> results = RecognizeDateTime(message, culture);

            return(results);
        }
예제 #3
0
        private IList <DateTimeResolution> GetDateFromMessage(string message, string culture)
        {
            if (CreateEventWhiteList.IsSkip(message))
            {
                message = CalendarCommonStrings.TodayLower;

                // log is this one skip. may change logic in future.
                // no use for now
                IsSkip = true;
            }

            IList <DateTimeResolution> results = RecognizeDateTime(message, culture);

            return(results);
        }
예제 #4
0
        private IList <DateTimeResolution> GetDurationFromMessage(string message, string culture)
        {
            if (CreateEventWhiteList.IsSkip(message))
            {
                message = "half an hour";

                // log is this one skip. may change logic in future.
                // no use for now
                IsSkip = true;
            }

            IList <DateTimeResolution> results = RecognizeDateTime(message, culture);

            return(results);
        }
예제 #5
0
        public async Task <DialogTurnResult> AfterUpdateAddress(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (state.AttendeesNameList.Any())
                {
                    state.FirstEnterFindContact = true;
                    return(await sc.BeginDialogAsync(nameof(FindContactDialog), options : sc.Options, cancellationToken : cancellationToken));
                }

                if (sc.Result != null)
                {
                    sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                    var userInput = content != null?content.ToString() : sc.Context.Activity.Text;

                    if (state.EventSource != EventSource.Other)
                    {
                        if (userInput != null)
                        {
                            var nameList = userInput.Split(CreateEventWhiteList.GetContactNameSeparator(), StringSplitOptions.None)
                                           .Select(x => x.Trim())
                                           .Where(x => !string.IsNullOrWhiteSpace(x))
                                           .ToList();
                            state.AttendeesNameList = nameList;
                        }

                        state.FirstEnterFindContact = true;
                        return(await sc.BeginDialogAsync(nameof(FindContactDialog), options : sc.Options, cancellationToken : cancellationToken));
                    }
                    else
                    {
                        return(await sc.BeginDialogAsync(Actions.UpdateAddress, new UpdateAddressDialogOptions(UpdateAddressDialogOptions.UpdateReason.NotAnAddress), cancellationToken));
                    }
                }
                else
                {
                    return(await sc.NextAsync(cancellationToken : cancellationToken));
                }
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #6
0
        private async Task <DialogTurnResult> AfterCollectLocationPromptAsync(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                bool?isLocationSkipByDefault = false;
                isLocationSkipByDefault = Settings.DefaultValue?.CreateMeeting?.First(item => item.Name == "EventLocation")?.IsSkipByDefault;

                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (state.MeetingInfo.Location == null && sc.Result != null && (!(state.MeetingInfo.CreateHasDetail && isLocationSkipByDefault.GetValueOrDefault()) || state.MeetingInfo.RecreateState == RecreateEventState.Location))
                {
                    sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                    var luisResult = sc.Context.TurnState.Get <CalendarLuis>(StateProperties.CalendarLuisResultKey);

                    var userInput = content != null?content.ToString() : sc.Context.Activity.Text;

                    var topIntent = luisResult?.TopIntent().intent.ToString();

                    var promptRecognizerResult = ConfirmRecognizerHelper.ConfirmYesOrNo(userInput, sc.Context.Activity.Locale);

                    // Enable the user to skip providing the location if they say something matching the Cancel intent, say something matching the ConfirmNo recognizer or something matching the NoLocation intent
                    if (CreateEventWhiteList.IsSkip(userInput))
                    {
                        state.MeetingInfo.Location = string.Empty;
                    }
                    else
                    {
                        state.MeetingInfo.Location = userInput;
                    }
                }
                else if (state.MeetingInfo.CreateHasDetail && isLocationSkipByDefault.GetValueOrDefault())
                {
                    state.MeetingInfo.Location = CalendarCommonStrings.DefaultLocation;
                }

                return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptionsAsync(sc, ex, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
        public async Task <DialogTurnResult> CollectStartDate(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                bool?isContentSkipByDefault = false;
                isContentSkipByDefault = Settings.DefaultValue?.CreateMeeting?.First(item => item.Name == "EventContent")?.IsSkipByDefault;

                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (sc.Result != null && (!(state.CreateHasDetail && isContentSkipByDefault.GetValueOrDefault()) || state.RecreateState == RecreateEventState.Content))
                {
                    if (string.IsNullOrEmpty(state.Content))
                    {
                        sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                        var merged_content = content != null?content.ToString() : sc.Context.Activity.Text;

                        if (!CreateEventWhiteList.IsSkip(merged_content))
                        {
                            state.Content = merged_content;
                        }
                    }
                }
                else if (state.CreateHasDetail && isContentSkipByDefault.GetValueOrDefault())
                {
                    state.Content = CalendarCommonStrings.DefaultContent;
                }

                if (!state.StartDate.Any())
                {
                    return(await sc.BeginDialogAsync(Actions.UpdateStartDateForCreate, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotFound), cancellationToken));
                }
                else
                {
                    return(await sc.NextAsync(cancellationToken : cancellationToken));
                }
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #8
0
        private async Task <DialogTurnResult> AfterCollectContentPromptAsync(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                bool?isContentSkipByDefault = false;
                isContentSkipByDefault = Settings.DefaultValue?.CreateMeeting?.First(item => item.Name == "EventContent")?.IsSkipByDefault;

                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (sc.Result != null && (!(state.MeetingInfo.CreateHasDetail && isContentSkipByDefault.GetValueOrDefault()) || state.MeetingInfo.RecreateState == RecreateEventState.Content))
                {
                    if (string.IsNullOrEmpty(state.MeetingInfo.Content))
                    {
                        sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                        var merged_content = content != null?content.ToString() : sc.Context.Activity.Text;

                        if (!CreateEventWhiteList.IsSkip(merged_content))
                        {
                            state.MeetingInfo.Content = merged_content;
                        }
                    }
                }
                else if (state.MeetingInfo.CreateHasDetail && isContentSkipByDefault.GetValueOrDefault())
                {
                    state.MeetingInfo.Content = CalendarCommonStrings.DefaultContent;
                }

                return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptionsAsync(sc, ex, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #9
0
        public async Task <DialogTurnResult> ConfirmBeforeCreate(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                if (state.Location == null && sc.Result != null && (!state.CreateHasDetail || state.RecreateState == RecreateEventState.Location))
                {
                    sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                    var luisResult = state.LuisResult;

                    var userInput = content != null?content.ToString() : sc.Context.Activity.Text;

                    var topIntent = luisResult?.TopIntent().intent.ToString();

                    var promptRecognizerResult = ConfirmRecognizerHelper.ConfirmYesOrNo(userInput, sc.Context.Activity.Locale);

                    // Enable the user to skip providing the location if they say something matching the Cancel intent, say something matching the ConfirmNo recognizer or something matching the NoLocation intent
                    if (CreateEventWhiteList.IsSkip(userInput))
                    {
                        state.Location = string.Empty;
                    }
                    else
                    {
                        state.Location = userInput;
                    }
                }

                var source   = state.EventSource;
                var newEvent = new EventModel(source)
                {
                    Title          = state.Title,
                    Content        = state.Content,
                    Attendees      = state.Attendees,
                    StartTime      = state.StartDateTime.Value,
                    EndTime        = state.EndDateTime.Value,
                    TimeZone       = TimeZoneInfo.Utc,
                    Location       = state.Location,
                    ContentPreview = state.Content
                };

                var attendeeConfirmString = string.Empty;
                if (state.Attendees.Count > 0)
                {
                    var attendeeConfirmResponse = ResponseManager.GetResponse(CreateEventResponses.ConfirmCreateAttendees, new StringDictionary()
                    {
                        { "Attendees", state.Attendees.ToSpeechString(CommonStrings.And, li => li.DisplayName ?? li.Address) }
                    });
                    attendeeConfirmString = attendeeConfirmResponse.Text;
                }

                var subjectConfirmString = string.Empty;
                if (!string.IsNullOrEmpty(state.Title))
                {
                    var subjectConfirmResponse = ResponseManager.GetResponse(CreateEventResponses.ConfirmCreateSubject, new StringDictionary()
                    {
                        { "Subject", string.IsNullOrEmpty(state.Title) ? CalendarCommonStrings.Empty : state.Title }
                    });
                    subjectConfirmString = subjectConfirmResponse.Text;
                }

                var locationConfirmString = string.Empty;
                if (!string.IsNullOrEmpty(state.Location))
                {
                    var subjectConfirmResponse = ResponseManager.GetResponse(CreateEventResponses.ConfirmCreateLocation, new StringDictionary()
                    {
                        { "Location", string.IsNullOrEmpty(state.Location) ? CalendarCommonStrings.Empty : state.Location },
                    });
                    locationConfirmString = subjectConfirmResponse.Text;
                }

                var contentConfirmString = string.Empty;
                if (!string.IsNullOrEmpty(state.Content))
                {
                    var contentConfirmResponse = ResponseManager.GetResponse(CreateEventResponses.ConfirmCreateContent, new StringDictionary()
                    {
                        { "Content", string.IsNullOrEmpty(state.Content) ? CalendarCommonStrings.Empty : state.Content },
                    });
                    contentConfirmString = contentConfirmResponse.Text;
                }

                var startDateTimeInUserTimeZone = TimeConverter.ConvertUtcToUserTime(state.StartDateTime.Value, state.GetUserTimeZone());
                var endDateTimeInUserTimeZone   = TimeConverter.ConvertUtcToUserTime(state.EndDateTime.Value, state.GetUserTimeZone());
                var tokens = new StringDictionary
                {
                    { "AttendeesConfirm", attendeeConfirmString },
                    { "Date", startDateTimeInUserTimeZone.ToSpeechDateString(false) },
                    { "Time", startDateTimeInUserTimeZone.ToSpeechTimeString(false) },
                    { "EndTime", endDateTimeInUserTimeZone.ToSpeechTimeString(false) },
                    { "SubjectConfirm", subjectConfirmString },
                    { "LocationConfirm", locationConfirmString },
                    { "ContentConfirm", contentConfirmString },
                };

                var prompt = await GetDetailMeetingResponseAsync(sc, newEvent, CreateEventResponses.ConfirmCreate, tokens);

                var retryPrompt = ResponseManager.GetResponse(CreateEventResponses.ConfirmCreateFailed, tokens);
                return(await sc.PromptAsync(Actions.TakeFurtherAction, new PromptOptions { Prompt = prompt, RetryPrompt = retryPrompt }, cancellationToken));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #10
0
        public async Task <DialogTurnResult> AfterUpdateUserName(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var userInput = sc.Result as string;
                var state     = await Accessor.GetAsync(sc.Context);

                var options = (UpdateUserNameDialogOptions)sc.Options;

                if (string.IsNullOrEmpty(userInput) && options.Reason != UpdateUserNameDialogOptions.UpdateReason.Initialize)
                {
                    await sc.Context.SendActivityAsync(ResponseManager.GetResponse(FindContactResponses.UserNotFoundAgain, new StringDictionary()
                    {
                        { "source", state.EventSource == EventSource.Microsoft ? "Outlook Calendar" : "Google Calendar" }
                    }));

                    return(await sc.EndDialogAsync());
                }

                string currentRecipientName = string.IsNullOrEmpty(userInput) ? state.CurrentAttendeeName : userInput;
                state.CurrentAttendeeName = currentRecipientName;

                // if it's an email, add to attendee and kepp the state.ConfirmedPerson null
                if (!string.IsNullOrEmpty(currentRecipientName) && IsEmail(currentRecipientName))
                {
                    var attendee = new EventModel.Attendee
                    {
                        DisplayName = currentRecipientName,
                        Address     = currentRecipientName
                    };
                    if (state.Attendees.All(r => r.Address != attendee.Address))
                    {
                        state.Attendees.Add(attendee);
                    }

                    state.CurrentAttendeeName = string.Empty;
                    state.ConfirmedPerson     = null;
                    return(await sc.EndDialogAsync());
                }

                List <CustomizedPerson> unionList = new List <CustomizedPerson>();

                if (CreateEventWhiteList.GetMyself(currentRecipientName))
                {
                    var me = await GetMe(sc);

                    unionList.Add(new CustomizedPerson(me));
                }
                else
                {
                    var originPersonList = await GetPeopleWorkWithAsync(sc, currentRecipientName);

                    var originContactList = await GetContactsAsync(sc, currentRecipientName);

                    originPersonList.AddRange(originContactList);

                    var originUserList = new List <PersonModel>();
                    try
                    {
                        originUserList = await GetUserAsync(sc, currentRecipientName);
                    }
                    catch
                    {
                        // do nothing when get user failed. because can not use token to ensure user use a work account.
                    }

                    (var personList, var userList) = FormatRecipientList(originPersonList, originUserList);

                    // people you work with has the distinct email address has the highest priority
                    if (personList.Count == 1 && personList.First().Emails.Any() && personList.First().Emails.First() != null)
                    {
                        unionList.Add(new CustomizedPerson(personList.First()));
                    }
                    else
                    {
                        personList.AddRange(userList);

                        foreach (var person in personList)
                        {
                            if (unionList.Find(p => p.DisplayName == person.DisplayName) == null)
                            {
                                var personWithSameName = personList.FindAll(p => p.DisplayName == person.DisplayName);
                                if (personWithSameName.Count == 1)
                                {
                                    unionList.Add(new CustomizedPerson(personWithSameName.First()));
                                }
                                else
                                {
                                    var unionPerson  = new CustomizedPerson(personWithSameName.FirstOrDefault());
                                    var curEmailList = new List <ScoredEmailAddress>();
                                    foreach (var sameNamePerson in personWithSameName)
                                    {
                                        sameNamePerson.Emails.ToList().ForEach(e =>
                                        {
                                            if (!string.IsNullOrEmpty(e))
                                            {
                                                curEmailList.Add(new ScoredEmailAddress {
                                                    Address = e
                                                });
                                            }
                                        });
                                    }

                                    unionPerson.Emails = curEmailList;
                                    unionList.Add(unionPerson);
                                }
                            }
                        }
                    }
                }

                unionList.RemoveAll(person => !person.Emails.Exists(email => email.Address != null));
                unionList.RemoveAll(person => !person.Emails.Any());

                state.UnconfirmedPerson = unionList;

                if (unionList.Count == 0)
                {
                    return(await sc.ReplaceDialogAsync(Actions.UpdateName, new UpdateUserNameDialogOptions(UpdateUserNameDialogOptions.UpdateReason.NotFound)));
                }
                else
                if (unionList.Count == 1)
                {
                    state.ConfirmedPerson = unionList.First();
                    return(await sc.EndDialogAsync());
                }
                else
                {
                    return(await sc.ReplaceDialogAsync(Actions.SelectPerson, sc.Options, cancellationToken));
                }
            }
            catch (SkillException skillEx)
            {
                await HandleDialogExceptions(sc, skillEx);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #11
0
        public async Task <DialogTurnResult> AfterConfirmNameList(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context);

                // get name list from sc.result
                if (sc.Result != null)
                {
                    sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                    var userInput = content != null?content.ToString() : sc.Context.Activity.Text;

                    // if is skip. set the name list to be myself only.
                    if (CreateEventWhiteList.IsSkip(userInput))
                    {
                        state.AttendeesNameList = new List <string>
                        {
                            CalendarCommonStrings.MyselfConst
                        };
                    }
                    else
                    if (state.EventSource != EventSource.Other)
                    {
                        if (userInput != null)
                        {
                            var nameList = userInput.Split(CreateEventWhiteList.GetContactNameSeparator(), StringSplitOptions.None)
                                           .Select(x => x.Trim())
                                           .Where(x => !string.IsNullOrWhiteSpace(x))
                                           .ToList();
                            state.AttendeesNameList = nameList;
                        }
                    }
                }

                if (state.AttendeesNameList.Any())
                {
                    if (state.AttendeesNameList.Count > 1)
                    {
                        var nameString = await GetReadyToSendNameListStringAsync(sc);

                        await sc.Context.SendActivityAsync(ResponseManager.GetResponse(FindContactResponses.BeforeSendingMessage, new StringDictionary()
                        {
                            { "NameList", nameString }
                        }));
                    }

                    // go to loop to go through all the names
                    state.ConfirmAttendeesNameIndex = 0;
                    return(await sc.ReplaceDialogAsync(Actions.LoopNameList, sc.Options, cancellationToken));
                }

                state.AttendeesNameList         = new List <string>();
                state.CurrentAttendeeName       = string.Empty;
                state.ConfirmAttendeesNameIndex = 0;
                return(await sc.EndDialogAsync());
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
        private async Task <DialogTurnResult> GetUserFromUserNameAsync(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                var options = (FindContactDialogOptions)sc.Options;
                var currentRecipientName = state.MeetingInfo.ContactInfor.CurrentContactName;

                // if it's an email
                if (!string.IsNullOrEmpty(currentRecipientName) && IsEmail(currentRecipientName))
                {
                    state.MeetingInfo.ContactInfor.CurrentContactName = string.Empty;
                    state.MeetingInfo.ContactInfor.ConfirmedContact   = new CustomizedPerson()
                    {
                        DisplayName = currentRecipientName,
                        Emails      = new List <ScoredEmailAddress>()
                        {
                            new ScoredEmailAddress()
                            {
                                Address = currentRecipientName
                            }
                        }
                    };
                    return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
                }

                var unionList = new List <CustomizedPerson>();

                if (CreateEventWhiteList.GetMyself(currentRecipientName))
                {
                    var me = await GetMeAsync(sc.Context, cancellationToken);

                    unionList.Add(new CustomizedPerson(me));
                }
                else if (!string.IsNullOrEmpty(currentRecipientName) && state.MeetingInfo.ContactInfor.RelatedEntityInfoDict.ContainsKey(currentRecipientName))
                {
                    string pronounType  = state.MeetingInfo.ContactInfor.RelatedEntityInfoDict[currentRecipientName].PronounType;
                    string relationship = state.MeetingInfo.ContactInfor.RelatedEntityInfoDict[currentRecipientName].RelationshipName;
                    var    personList   = new List <PersonModel>();
                    if (pronounType == PronounType.FirstPerson)
                    {
                        if (Regex.IsMatch(relationship, CalendarCommonStrings.Manager, RegexOptions.IgnoreCase))
                        {
                            var person = await GetMyManagerAsync(sc, cancellationToken);

                            if (person != null)
                            {
                                personList.Add(person);
                            }
                        }
                    }
                    else if (pronounType == PronounType.ThirdPerson && state.MeetingInfo.ContactInfor.Contacts.Count > 0)
                    {
                        int    count   = state.MeetingInfo.ContactInfor.Contacts.Count;
                        string prename = state.MeetingInfo.ContactInfor.Contacts[count - 1].UserPrincipalName;
                        if (Regex.IsMatch(relationship, CalendarCommonStrings.Manager, RegexOptions.IgnoreCase))
                        {
                            var person = await GetManagerAsync(sc, prename, cancellationToken);

                            if (person != null)
                            {
                                personList.Add(person);
                            }
                        }
                    }

                    foreach (var person in personList)
                    {
                        unionList.Add(new CustomizedPerson(person));
                    }
                }
                else
                {
                    var originPersonList = await GetPeopleWorkWithAsync(sc, currentRecipientName, cancellationToken);

                    var originContactList = await GetContactsAsync(sc, currentRecipientName, cancellationToken);

                    originPersonList.AddRange(originContactList);

                    var originUserList = new List <PersonModel>();
                    try
                    {
                        originUserList = await GetUserAsync(sc, currentRecipientName, cancellationToken);
                    }
                    catch
                    {
                        // do nothing when get user failed. because can not use token to ensure user use a work account.
                    }

                    (var personList, var userList) = FormatRecipientList(originPersonList, originUserList);

                    // people you work with has the distinct email address has the highest priority
                    if (personList.Count == 1 && personList.First().Emails.Any() && personList.First().Emails.First() != null)
                    {
                        unionList.Add(new CustomizedPerson(personList.First()));
                    }
                    else
                    {
                        personList.AddRange(userList);

                        foreach (var person in personList)
                        {
                            if (unionList.Find(p => p.DisplayName == person.DisplayName) == null)
                            {
                                var personWithSameName = personList.FindAll(p => p.DisplayName == person.DisplayName);
                                if (personWithSameName.Count == 1)
                                {
                                    unionList.Add(new CustomizedPerson(personWithSameName.First()));
                                }
                                else
                                {
                                    var unionPerson  = new CustomizedPerson(personWithSameName.FirstOrDefault());
                                    var curEmailList = new List <ScoredEmailAddress>();
                                    foreach (var sameNamePerson in personWithSameName)
                                    {
                                        sameNamePerson.Emails.ToList().ForEach(e =>
                                        {
                                            if (!string.IsNullOrEmpty(e))
                                            {
                                                curEmailList.Add(new ScoredEmailAddress {
                                                    Address = e
                                                });
                                            }
                                        });
                                    }

                                    unionPerson.Emails = curEmailList;
                                    unionList.Add(unionPerson);
                                }
                            }
                        }
                    }
                }

                unionList.RemoveAll(person => !person.Emails.Exists(email => email.Address != null));
                unionList.RemoveAll(person => !person.Emails.Any());

                state.MeetingInfo.ContactInfor.UnconfirmedContact = unionList;

                if (unionList.Count == 0)
                {
                    if (!(options.UpdateUserNameReason == FindContactDialogOptions.UpdateUserNameReasonType.Initialize))
                    {
                        options.FirstRetry = false;
                    }

                    options.UpdateUserNameReason = FindContactDialogOptions.UpdateUserNameReasonType.NotFound;
                    return(await sc.ReplaceDialogAsync(Actions.UpdateName, options, cancellationToken));
                }

                return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
            }
            catch (SkillException skillEx)
            {
                await HandleDialogExceptionsAsync(sc, skillEx, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptionsAsync(sc, ex, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
        private async Task <DialogTurnResult> AfterConfirmNameListAsync(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

                var options = sc.Options as FindContactDialogOptions;

                // get name list from sc.result
                if (sc.Result != null)
                {
                    sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);
                    var userInput = content != null?content.ToString() : sc.Context.Activity.Text;

                    // if is skip. set the name list to be myself only.
                    if (CreateEventWhiteList.IsSkip(userInput))
                    {
                        state.MeetingInfo.ContactInfor.ContactsNameList = new List <string>
                        {
                            CalendarCommonStrings.MyselfConst
                        };
                    }
                    else
                    if (state.EventSource != EventSource.Other)
                    {
                        if (userInput != null)
                        {
                            var nameList = userInput.Split(CreateEventWhiteList.GetContactNameSeparator(), StringSplitOptions.None)
                                           .Select(x => x.Trim())
                                           .Where(x => !string.IsNullOrWhiteSpace(x))
                                           .ToList();
                            state.MeetingInfo.ContactInfor.ContactsNameList = nameList;
                        }
                    }
                }

                if (state.MeetingInfo.ContactInfor.ContactsNameList.Any())
                {
                    if (state.MeetingInfo.ContactInfor.ContactsNameList.Count > 1 && !(state.InitialIntent == CalendarLuis.Intent.CheckAvailability))
                    {
                        var nameString = await GetReadyToSendNameListStringAsync(sc, cancellationToken);

                        var activity = TemplateManager.GenerateActivityForLocale(FindContactResponses.BeforeSendingMessage, new
                        {
                            NameList = nameString
                        });
                        await sc.Context.SendActivityAsync(activity, cancellationToken);
                    }

                    // go to loop to go through all the names
                    state.MeetingInfo.ContactInfor.ConfirmContactsNameIndex = 0;
                    return(await sc.ReplaceDialogAsync(Actions.LoopNameList, sc.Options, cancellationToken));
                }

                // todo:
                state.MeetingInfo.ContactInfor.ContactsNameList         = new List <string>();
                state.MeetingInfo.ContactInfor.CurrentContactName       = string.Empty;
                state.MeetingInfo.ContactInfor.ConfirmContactsNameIndex = 0;
                return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptionsAsync(sc, ex, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
예제 #14
0
        public async Task <DialogTurnResult> ConfirmName(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context);

                if ((state.AttendeesNameList == null) || (state.AttendeesNameList.Count == 0))
                {
                    return(await sc.BeginDialogAsync(Actions.UpdateName, new UpdateUserNameDialogOptions(UpdateUserNameDialogOptions.UpdateReason.NotFound)));
                }

                var unionList = new List <CustomizedPerson>();
                var emailList = new List <string>();

                if (state.FirstEnterFindContact)
                {
                    state.FirstEnterFindContact = false;
                    foreach (var name in state.AttendeesNameList)
                    {
                        if (IsEmail(name))
                        {
                            emailList.Add(name);
                        }
                    }

                    if (state.AttendeesNameList.Count > 1)
                    {
                        var nameString = await GetReadyToSendNameListStringAsync(sc);

                        await sc.Context.SendActivityAsync(sc.Context.Activity.CreateReply(FindContactResponses.BeforeSendingMessage, null, new StringDictionary()
                        {
                            { "NameList", nameString }
                        }));
                    }
                }

                if (emailList.Count > 0)
                {
                    foreach (var email in emailList)
                    {
                        var attendee = new EventModel.Attendee
                        {
                            DisplayName = email,
                            Address     = email
                        };
                        if (state.Attendees.All(r => r.Address != attendee.Address))
                        {
                            state.Attendees.Add(attendee);
                        }
                    }

                    state.AttendeesNameList.RemoveAll(n => IsEmail(n));

                    if (state.AttendeesNameList.Count > 0)
                    {
                        return(await sc.ReplaceDialogAsync(Actions.ConfirmName, options : sc.Options, cancellationToken : cancellationToken));
                    }
                    else
                    {
                        return(await sc.EndDialogAsync());
                    }
                }

                if (state.ConfirmAttendeesNameIndex < state.AttendeesNameList.Count)
                {
                    var currentRecipientName = state.AttendeesNameList[state.ConfirmAttendeesNameIndex];

                    if (CreateEventWhiteList.GetMyself().Contains(currentRecipientName))
                    {
                        var me = await GetMe(sc);

                        unionList.Add(new CustomizedPerson(me));
                    }
                    else
                    {
                        var originPersonList = await GetPeopleWorkWithAsync(sc, currentRecipientName);

                        var originContactList = await GetContactsAsync(sc, currentRecipientName);

                        originPersonList.AddRange(originContactList);

                        var originUserList = new List <PersonModel>();
                        try
                        {
                            originUserList = await GetUserAsync(sc, currentRecipientName);
                        }
                        catch
                        {
                            // do nothing when get user failed. because can not use token to ensure user use a work account.
                        }

                        (var personList, var userList) = FormatRecipientList(originPersonList, originUserList);

                        // people you work with has the distinct email address has the highest priority
                        if (personList.Count == 1 && personList.First().Emails.Count == 1)
                        {
                            state.ConfirmedPerson = new CustomizedPerson(personList.First());
                            var highestPriorityPerson = new CustomizedPerson(personList.First());
                            return(await sc.ReplaceDialogAsync(Actions.ConfirmEmail, highestPriorityPerson));
                        }

                        personList.AddRange(userList);

                        foreach (var person in personList)
                        {
                            if (unionList.Find(p => p.DisplayName == person.DisplayName) == null)
                            {
                                var personWithSameName = personList.FindAll(p => p.DisplayName == person.DisplayName);
                                if (personWithSameName.Count == 1)
                                {
                                    unionList.Add(new CustomizedPerson(personWithSameName.First()));
                                }
                                else
                                {
                                    var unionPerson  = new CustomizedPerson(personWithSameName.FirstOrDefault());
                                    var curEmailList = new List <ScoredEmailAddress>();
                                    foreach (var sameNamePerson in personWithSameName)
                                    {
                                        sameNamePerson.Emails.ToList().ForEach(e => curEmailList.Add(new ScoredEmailAddress {
                                            Address = e
                                        }));
                                    }

                                    unionPerson.Emails = curEmailList;
                                    unionList.Add(unionPerson);
                                }
                            }
                        }
                    }
                }
                else
                {
                    return(await sc.EndDialogAsync());
                }

                state.UnconfirmedPerson = unionList;

                if (unionList.Count == 0)
                {
                    return(await sc.BeginDialogAsync(Actions.UpdateName, new UpdateUserNameDialogOptions(UpdateUserNameDialogOptions.UpdateReason.NotFound)));
                }
                else if (unionList.Count == 1)
                {
                    state.ConfirmedPerson = unionList.First();
                    return(await sc.ReplaceDialogAsync(Actions.ConfirmEmail, unionList.First()));
                }
                else
                {
                    var nameString = string.Empty;
                    if (unionList.Count <= ConfigData.GetInstance().MaxDisplaySize)
                    {
                        return(await sc.PromptAsync(Actions.Choice, await GenerateOptionsForName(sc, unionList, sc.Context, true)));
                    }
                    else
                    {
                        return(await sc.PromptAsync(Actions.Choice, await GenerateOptionsForName(sc, unionList, sc.Context, false)));
                    }
                }
            }
            catch (SkillException skillEx)
            {
                await HandleDialogExceptions(sc, skillEx);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }