private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     return(await stepContext.EndDialogAsync(null, cancellationToken));
 }
Esempio n. 2
0
 private async Task <DialogTurnResult> SignInStepAsync(WaterfallStepContext context, CancellationToken cancellationToken)
 {
     // This prompt won't show if the user is signed in to the root using SSO.
     return(await context.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken));
 }
Esempio n. 3
0
 /// <summary>
 /// Prompts the user for intput by sending a <see cref="ChoicePrompt"/> so the user may select their
 /// choice from a list of options.
 /// </summary>
 /// <param name="step">A <see cref="WaterfallStepContext"/> provides context for the current waterfall step.</param>
 /// <param name="cancellationToken" >(Optional) A <see cref="CancellationToken"/> that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A <see cref="DialogTurnResult"/> to communicate some flow control back to the containing WaterfallDialog.</returns>
 private static async Task <DialogTurnResult> ChoiceCardStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
 {
     return(await step.PromptAsync("cardPrompt", GenerateOptions(step.Context.Activity), cancellationToken));
 }
Esempio n. 4
0
        private async Task <DialogTurnResult> PromptForSlotStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            var state = await _stateAccessor.GetAsync(step.Context, cancellationToken : cancellationToken);

            if (state.StartDate == null && step.Result is IList <DateTimeResolution> resolution)
            {
                var timex = new TimexProperty(resolution[0].Timex);
                state.Timex = timex;
                var hour = timex.Hour ?? 0;
                state.StartDate = new DateTime(
                    timex.Year.Value,
                    timex.Month.Value,
                    timex.DayOfMonth.Value,
                    hour,
                    0,
                    0);
                await _stateAccessor.SetAsync(step.Context, state, cancellationToken);
            }

            var reservationCapacity = new List <CarwashService.ReservationCapacity>();

            try
            {
                var api = new CarwashService(step, _telemetryClient, cancellationToken);

                reservationCapacity = (List <CarwashService.ReservationCapacity>) await api.GetReservationCapacityAsync(state.StartDate.Value, cancellationToken);
            }
            catch (AuthenticationException)
            {
                await step.Context.SendActivityAsync(AuthDialog.NotAuthenticatedMessage, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }
            catch (Exception e)
            {
                _telemetryClient.TrackException(e);
                await step.Context.SendActivityAsync(e.Message, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }

            // Check whether we already know the slot.
            if (Slots.Any(s => s.StartTime == state.StartDate?.Hour))
            {
                // Check if slot is available.
                if (!reservationCapacity.Any(c => c.StartTime == state.StartDate && c.FreeCapacity > 0))
                {
                    await step.Context.SendActivityAsync("Sorry, this slot is already full.", cancellationToken : cancellationToken);
                }
                else
                {
                    return(await step.NextAsync(cancellationToken : cancellationToken));
                }
            }
            else if (!string.IsNullOrEmpty(state.Timex?.PartOfDay))
            {
                // Check whether we can find out the slot from timex.
                Slot slot = null;
                switch (state.Timex.PartOfDay)
                {
                case "MO":
                    slot = Slots[0];
                    break;

                case "AF":
                    slot = Slots[1];
                    break;

                case "EV":
                    slot = Slots[2];
                    break;
                }

                if (slot != null)
                {
                    state.StartDate = new DateTime(
                        state.StartDate.Value.Year,
                        state.StartDate.Value.Month,
                        state.StartDate.Value.Day,
                        slot.StartTime,
                        0,
                        0);

                    await _stateAccessor.SetAsync(step.Context, state, cancellationToken);

                    return(await step.NextAsync(cancellationToken : cancellationToken));
                }
            }

            var choices = new List <Choice>();

            state.SlotChoices = new List <DateTime>();
            foreach (var slot in reservationCapacity)
            {
                if (slot.FreeCapacity < 1)
                {
                    continue;
                }

                choices.Add(new Choice($"{slot.StartTime.ToNaturalLanguage()} ({slot.StartTime.Hour}-{Slots.Single(s => s.StartTime == slot.StartTime.Hour).EndTime})"));

                // Save recommendations to state
                state.SlotChoices.Add(slot.StartTime);
            }

            await _stateAccessor.SetAsync(step.Context, state, cancellationToken);

            return(await step.PromptAsync(
                       SlotPromptName,
                       new PromptOptions
            {
                Prompt = MessageFactory.Text("Please choose one of these slots:"),
                Choices = choices,
            },
                       cancellationToken));
        }
Esempio n. 5
0
        private async Task <DialogTurnResult> DisplayReservationStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            var state = await _stateAccessor.GetAsync(step.Context, cancellationToken : cancellationToken);

            if (string.IsNullOrWhiteSpace(state.Comment) && step.Result is string comment && !new[] { "skip", "nope", "thanks, no", "no" }.Contains(comment.ToLower()))
            {
                state.Comment = comment;
                await _stateAccessor.SetAsync(step.Context, state, cancellationToken);
            }

            Reservation reservation = new Reservation
            {
                VehiclePlateNumber = state.VehiclePlateNumber,
                Services           = state.Services,
                Private            = state.Private,
                StartDate          = state.StartDate.Value,
                Comment            = state.Comment,
            };

            try
            {
                var api = new CarwashService(step, _telemetryClient, cancellationToken);

                // Submit reservation
                reservation = await api.SubmitReservationAsync(reservation, cancellationToken);
            }
            catch (AuthenticationException)
            {
                await step.Context.SendActivityAsync(AuthDialog.NotAuthenticatedMessage, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }
            catch (Exception e)
            {
                _telemetryClient.TrackException(e);
                await step.Context.SendActivityAsync(e.Message, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }

            await step.Context.SendActivityAsync($"OK, I have reserved a car wash for {reservation.StartDate.ToNaturalLanguage()}.", cancellationToken : cancellationToken);

            await step.Context.SendActivityAsync("🚗", cancellationToken : cancellationToken);

            await step.Context.SendActivityAsync("Here is the current state of your reservation. I'll let you know when you will need to drop off the keys.", cancellationToken : cancellationToken);

            var response = step.Context.Activity.CreateReply();

            response.Attachments = new ReservationCard(reservation).ToAttachmentList();

            await step.Context.SendActivityAsync(response, cancellationToken).ConfigureAwait(false);

            _telemetryClient.TrackEvent(
                "New reservation from chat bot.",
                new Dictionary <string, string>
            {
                { "Reservation ID", reservation.Id },
            },
                new Dictionary <string, double>
            {
                { "New reservation", 1 },
            });

            return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
        }
Esempio n. 6
0
        private static async Task <DialogTurnResult> CheckValidUserAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {//0
            var username = (string)stepContext.Result;

            try
            {
                SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

                builder.ConnectionString = "Server=tcp:team02-server.database.windows.net,1433;Initial Catalog=healtheeDB;Persist Security Info=False;User ID=chatbot02;Password=chatee17!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";

                using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
                {
                    connection.Open();

                    StringBuilder sb = new StringBuilder();
                    sb.Append("SELECT COUNT(*) FROM [dbo].[UserInfo] WHERE UserName='******'"); //유저가 입력한 이름으로 DB에서 사용자 찾기
                    String sql = sb.ToString();

                    int count = 0;

                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                count = reader.GetInt32(0);
                            }
                        }
                    }

                    sb = new StringBuilder();
                    sb.Append("SELECT COUNT(*) FROM [dbo].[UserInfo] ");
                    sql = sb.ToString();

                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                PrimaryNumber = reader.GetInt32(0) + 1;
                            }
                        }
                    }

                    if (count == 0) //DB에 기록이 없을 때, tutorial Async 실행시켜야 함
                    {
                        connection.Close();
                        ModeManager.mode = (int)ModeManager.Modes.Tutorial;
                        return(await stepContext.BeginDialogAsync(nameof(TutorialDialog), null, cancellationToken));
                    }
                    else //DB에 기록이 있으면 기능 보여주기로 넘어감
                    {
                        sb = new StringBuilder();
                        sb.Append("SELECT * FROM [dbo].[UserInfo] WHERE UserName='******'");
                        sql = sb.ToString();

                        using (SqlCommand command = new SqlCommand(sql, connection))
                        {
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    UserInfoManager.keyNum            = (int)reader.GetValue(0);
                                    UserInfoManager.UserName          = (string)reader.GetValue(1);
                                    UserInfoManager.PreWeight         = (int)reader.GetValue(2);
                                    UserInfoManager.PostWeight        = (int)reader.GetValue(3);
                                    UserInfoManager.SkillLevel        = (string)reader.GetValue(4);
                                    UserInfoManager.Area              = (string)reader.GetValue(5);
                                    UserInfoManager.Category          = (string)reader.GetValue(6);
                                    UserInfoManager.ConversationCount = (int)reader.GetValue(7);
                                    break;
                                }
                            }
                        }

                        connection.Close();
                        ModeManager.mode = (int)ModeManager.Modes.ShowFunction;
                        return(await stepContext.BeginDialogAsync(nameof(ShowFunctionsDialog), null, cancellationToken));
                    }
                }
            }
            catch (SqlException e)
            {
                await stepContext.Context.SendActivityAsync(MessageFactory.Text("DB 연결에 문제가 있습니다."), cancellationToken);

                Console.WriteLine(e.ToString());
                return(await stepContext.NextAsync());
            }
        }
Esempio n. 7
0
 private async Task <DialogTurnResult> EndGameAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     return(await stepContext.EndDialogAsync("optional", cancellationToken));
 }
 private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     // Restart the main dialog with a different message the second time around
     return(await stepContext.ReplaceDialogAsync(InitialDialogId, _templateEngine.GenerateActivityForLocale("CompletedMessage"), cancellationToken));
 }
Esempio n. 9
0
        private async Task <DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            if (stepContext.Context.Activity.Value != null)
            {
                await HandleSpecialActivity(stepContext, cancellationToken);
            }
            else
            {
                // Checks to see if the activity is an adaptive card update or a bot action respose
                var card     = ((FoundChoice)stepContext.Result).Value.ToLowerInvariant();
                var cardType = ParseEnum <CardOptions>(card);

                if (ChannelSupportedCards.IsCardSupported(stepContext.Context.Activity.ChannelId, cardType))
                {
                    switch (cardType)
                    {
                    case CardOptions.AdaptiveCardBotAction:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeAdaptiveCard("botaction").ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.AdaptiveCardTeamsTaskModule:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeAdaptiveCard("taskmodule").ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.AdaptiveCardSubmitAction:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeAdaptiveCard("submitaction").ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.Hero:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(CardSampleHelper.CreateHeroCard().ToAttachment()), cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.Thumbnail:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(CardSampleHelper.CreateThumbnailCard().ToAttachment()), cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.Receipt:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(CardSampleHelper.CreateReceiptCard().ToAttachment()), cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.Signin:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(CardSampleHelper.CreateSigninCard().ToAttachment()), cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.Carousel:
                        // NOTE: if cards are NOT the same height in a carousel, Teams will instead display as AttachmentLayoutTypes.List
                        await stepContext.Context.SendActivityAsync(
                            MessageFactory.Carousel(new[]
                        {
                            CardSampleHelper.CreateHeroCard().ToAttachment(),
                            CardSampleHelper.CreateHeroCard().ToAttachment(),
                            CardSampleHelper.CreateHeroCard().ToAttachment()
                        }),
                            cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.List:
                        // NOTE: MessageFactory.Attachment with multiple attachments will default to AttachmentLayoutTypes.List
                        await stepContext.Context.SendActivityAsync(
                            MessageFactory.Attachment(new[]
                        {
                            CardSampleHelper.CreateHeroCard().ToAttachment(),
                            CardSampleHelper.CreateHeroCard().ToAttachment(),
                            CardSampleHelper.CreateHeroCard().ToAttachment()
                        }),
                            cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.O365:

                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeO365CardAttachmentAsync()), cancellationToken).ConfigureAwait(false);

                        break;

                    case CardOptions.TeamsFileConsent:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeTeamsFileConsentCard()), cancellationToken);

                        break;

                    case CardOptions.Animation:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeAnimationCard().ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.Audio:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeAudioCard().ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.Video:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeVideoCard().ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.AdaptiveUpdate:
                        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(MakeUpdateAdaptiveCard().ToAttachment()), cancellationToken);

                        break;

                    case CardOptions.End:
                        return(new DialogTurnResult(DialogTurnStatus.Complete));
                    }
                }
                else
                {
                    await stepContext.Context.SendActivityAsync(MessageFactory.Text($"{cardType} cards are not supported in the {stepContext.Context.Activity.ChannelId} channel."), cancellationToken);
                }
            }

            return(await stepContext.ReplaceDialogAsync(InitialDialogId, "What card would you want?", cancellationToken));
        }
Esempio n. 10
0
        public async Task <DialogTurnResult> AfterUpdateStartTime(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context);

                if (sc.Result != null)
                {
                    state.Events = sc.Result as List <EventModel>;
                }

                if (state.Events.Count == 0)
                {
                    // should not doto this part. add log here for safe
                    await HandleDialogExceptions(sc, new Exception("Unexpect zero events count"));

                    return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
                }
                else
                if (state.Events.Count > 1)
                {
                    var options = new PromptOptions()
                    {
                        Choices = new List <Choice>(),
                    };

                    for (var i = 0; i < state.Events.Count; i++)
                    {
                        var item   = state.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 state.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 (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));
            }
        }
        /// <summary>
        /// Defines the second step of the main dialog, which is to process the user's input, and
        /// repeat or exit as appropriate.
        /// </summary>
        /// <param name="stepContext">The current waterfall step context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task to perform.</returns>
        private async Task <DialogTurnResult> ProcessInputAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // Get the order cart from dialog state.
            Order order = stepContext.Values[OrderCartId] as Order;

            // Get the user's choice from the previous prompt.
            string response = (stepContext.Result as FoundChoice).Value;

            if (response.Equals("process order", StringComparison.InvariantCultureIgnoreCase))
            {
                order.ReadyToProcess = true;

                await stepContext.Context.SendActivityAsync(
                    "Your order is on it's way!",
                    cancellationToken : cancellationToken);

                // In production, you may want to store something more helpful.
                // "Process" the order and exit.
                order.OrderProcessed = true;
                return(await stepContext.EndDialogAsync(null, cancellationToken));
            }
            else if (response.Equals("cancel", StringComparison.InvariantCultureIgnoreCase))
            {
                // Cancel the order.
                await stepContext.Context.SendActivityAsync(
                    "Your order has been canceled",
                    cancellationToken : cancellationToken);

                // Exit without processing the order.
                return(await stepContext.EndDialogAsync(null, cancellationToken));
            }
            else if (response.Equals("more info", StringComparison.InvariantCultureIgnoreCase))
            {
                // Send more information about the options.
                string message = "More info: <br/>" +
                                 "Potato Salad: contains 330 calories per serving. Cost: 5.99 <br/>"
                                 + "Tuna Sandwich: contains 700 calories per serving. Cost: 6.89 <br/>"
                                 + "Clam Chowder: contains 650 calories per serving. Cost: 4.50";
                await stepContext.Context.SendActivityAsync(
                    message,
                    cancellationToken : cancellationToken);

                // Continue the ordering process, passing in the current order cart.
                return(await stepContext.ReplaceDialogAsync(MainDialogId, order, cancellationToken));
            }
            else if (response.Equals("help", StringComparison.InvariantCultureIgnoreCase))
            {
                // Provide help information.
                string message = "To make an order, add as many items to your cart as " +
                                 "you like. Choose the `Process order` to check out. " +
                                 "Choose `Cancel` to cancel your order and exit.";
                await stepContext.Context.SendActivityAsync(
                    message,
                    cancellationToken : cancellationToken);

                // Continue the ordering process, passing in the current order cart.
                return(await stepContext.ReplaceDialogAsync(MainDialogId, order, cancellationToken));
            }

            // We've checked for expected interruptions. Check for a valid item choice.
            if (!DinnerMenu.MenuItems.ContainsKey(response))
            {
                await stepContext.Context.SendActivityAsync("Sorry, that is not a valid item. " +
                                                            "Please pick one from the menu.");

                // Continue the ordering process, passing in the current order cart.
                return(await stepContext.ReplaceDialogAsync(MainDialogId, order, cancellationToken));
            }
            else
            {
                // Add the item to cart.
                DinnerItem item = DinnerMenu.MenuItems[response];

                order.Items.Add(item);
                order.Total += item.Price;

                // Acknowledge the input.
                await stepContext.Context.SendActivityAsync(
                    $"Added `{response}` to your order; your total is ${order.Total:0.00}.",
                    cancellationToken : cancellationToken);

                // Continue the ordering process, passing in the current order cart.
                return(await stepContext.ReplaceDialogAsync(MainDialogId, order, cancellationToken));
            }
        }
Esempio n. 12
0
        public async Task <DialogTurnResult> AfterGetNewEventTime(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                var state = await Accessor.GetAsync(sc.Context);

                if (state.NewStartDate.Any() || state.NewStartTime.Any() || state.MoveTimeSpan != 0)
                {
                    var originalEvent         = state.Events[0];
                    var originalStartDateTime = TimeConverter.ConvertUtcToUserTime(originalEvent.StartTime, state.GetUserTimeZone());
                    var userNow = TimeConverter.ConvertUtcToUserTime(DateTime.UtcNow, state.GetUserTimeZone());

                    if (state.NewStartDate.Any() || state.NewStartTime.Any())
                    {
                        var newStartDate = state.NewStartDate.Any() ?
                                           state.NewStartDate.Last() :
                                           originalStartDateTime;

                        var newStartTime = new List <DateTime>();
                        if (state.NewStartTime.Any())
                        {
                            foreach (var time in state.NewStartTime)
                            {
                                var newStartDateTime = new DateTime(
                                    newStartDate.Year,
                                    newStartDate.Month,
                                    newStartDate.Day,
                                    time.Hour,
                                    time.Minute,
                                    time.Second);

                                if (state.NewStartDateTime == null)
                                {
                                    state.NewStartDateTime = newStartDateTime;
                                }

                                if (newStartDateTime >= userNow)
                                {
                                    state.NewStartDateTime = newStartDateTime;
                                    break;
                                }
                            }
                        }
                    }
                    else if (state.MoveTimeSpan != 0)
                    {
                        state.NewStartDateTime = originalStartDateTime.AddSeconds(state.MoveTimeSpan);
                    }
                    else
                    {
                        return(await sc.BeginDialogAsync(Actions.UpdateNewStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotFound)));
                    }

                    state.NewStartDateTime = TimeZoneInfo.ConvertTimeToUtc(state.NewStartDateTime.Value, state.GetUserTimeZone());

                    return(await sc.ContinueDialogAsync());
                }
                else if (sc.Result != null)
                {
                    IList <DateTimeResolution> dateTimeResolutions = sc.Result as List <DateTimeResolution>;

                    DateTime?newStartTime = null;

                    foreach (var resolution in dateTimeResolutions)
                    {
                        var utcNow = DateTime.UtcNow;
                        var dateTimeConvertTypeString = resolution.Timex;
                        var dateTimeConvertType       = new TimexProperty(dateTimeConvertTypeString);
                        var dateTimeValue             = DateTime.Parse(resolution.Value);
                        if (dateTimeValue == null)
                        {
                            continue;
                        }

                        var isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, resolution.Value, dateTimeConvertTypeString);
                        if (isRelativeTime)
                        {
                            dateTimeValue = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Local);
                        }

                        dateTimeValue = isRelativeTime ? TimeZoneInfo.ConvertTime(dateTimeValue, TimeZoneInfo.Local, state.GetUserTimeZone()) : dateTimeValue;
                        var originalStartDateTime = TimeConverter.ConvertUtcToUserTime(state.Events[0].StartTime, state.GetUserTimeZone());
                        if (dateTimeConvertType.Types.Contains(Constants.TimexTypes.Date) && !dateTimeConvertType.Types.Contains(Constants.TimexTypes.DateTime))
                        {
                            dateTimeValue = new DateTime(
                                dateTimeValue.Year,
                                dateTimeValue.Month,
                                dateTimeValue.Day,
                                originalStartDateTime.Hour,
                                originalStartDateTime.Minute,
                                originalStartDateTime.Second);
                        }
                        else if (dateTimeConvertType.Types.Contains(Constants.TimexTypes.Time) && !dateTimeConvertType.Types.Contains(Constants.TimexTypes.DateTime))
                        {
                            dateTimeValue = new DateTime(
                                originalStartDateTime.Year,
                                originalStartDateTime.Month,
                                originalStartDateTime.Day,
                                dateTimeValue.Hour,
                                dateTimeValue.Minute,
                                dateTimeValue.Second);
                        }

                        dateTimeValue = TimeZoneInfo.ConvertTimeToUtc(dateTimeValue, state.GetUserTimeZone());

                        if (newStartTime == null)
                        {
                            newStartTime = dateTimeValue;
                        }

                        if (dateTimeValue >= utcNow)
                        {
                            newStartTime = dateTimeValue;
                            break;
                        }
                    }

                    if (newStartTime != null)
                    {
                        state.NewStartDateTime = newStartTime;

                        return(await sc.ContinueDialogAsync());
                    }
                    else
                    {
                        return(await sc.BeginDialogAsync(Actions.UpdateNewStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotADateTime)));
                    }
                }
                else
                {
                    return(await sc.BeginDialogAsync(Actions.UpdateNewStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotADateTime)));
                }
            }
            catch (Exception ex)
            {
                await HandleDialogExceptions(sc, ex);

                return(new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs));
            }
        }
 private async Task <DialogTurnResult> PromptToLogin(WaterfallStepContext sc, CancellationToken cancellationToken)
 {
     return(await sc.PromptAsync(AuthenticationResponses.ResponseIds.LoginPrompt, new PromptOptions()));
 }
 private Task <DialogTurnResult> EndAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     return(stepContext.EndDialogAsync(cancellationToken: cancellationToken));
 }
Esempio n. 15
0
        private async Task <DialogTurnResult> GetQRNGSourceStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            //_logger.LogInformation($"MainDialog.GetQRNGSourceStepAsync[{((FoundChoice)stepContext.Result)?.Value}]");

            var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(stepContext.Context, () => new UserProfileTemporary());

            // Get the number of bytes we need from the camera's entropy
            int numDots   = getOptimizedDots(userProfileTemporary.Radius);
            int bytesSize = requiredEnthropyBytes(numDots);

            switch (((FoundChoice)stepContext.Result)?.Value)
            {
            case "Camera":
                stepContext.Values["qrng_source"]           = "Camera";
                stepContext.Values["qrng_source_query_str"] = "";     // generated later in QRNG class

                var promptOptions = new PromptOptions
                {
                    Prompt      = MessageFactory.Text("Your smartphone's camera will now load to generate some local entropy to send to me."),
                    RetryPrompt = MessageFactory.Text("That is not a valid entropy source."),
                };

                // Send an EventActivity to for the webbot's JavaScript callback handler to pickup
                // and then pass onto the app layer to load the camera
                var requestEntropyActivity = Activity.CreateEventActivity();
                requestEntropyActivity.ChannelData = $"camrng,{bytesSize}";
                await stepContext.Context.SendActivityAsync(requestEntropyActivity);

                return(await stepContext.PromptAsync("GetQRNGSourceChoicePrompt", promptOptions, cancellationToken));

            case "ANU Leftovers":
                stepContext.Values["qrng_source"] = "Pool";

                // Chose a random entropy GID from the list of GIDs in the pool (pseudo randomly selecting quantum randomness?! there's a joke in there somewhere :)
#if RELEASE_PROD
                var jsonStr = new WebClient().DownloadString($"https://api.randonauts.com/getpools");
#else
                var jsonStr = new WebClient().DownloadString($"https://devapi.randonauts.com/getpools");
#endif
                var pools = Newtonsoft.Json.JsonConvert.DeserializeObject <dynamic>(jsonStr);
                var r     = new Random();
                var idx   = r.Next(pools.Count);
                var pool  = pools[idx];
                var time  = DateTime.Parse(pool.time.ToString());

                await stepContext.Context.SendActivityAsync($"Enjoy some residual ANU pool entropy from around {time.ToString("yyyy-MM-dd")}");

                stepContext.Values["qrng_source_query_str"] = $"pool=true&gid={pool.pool.ToString().Replace(".pool", "")}&raw=true";
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            case "GCP Retro":
                stepContext.Values["qrng_source"]           = "GCPRetro";
                stepContext.Values["qrng_source_query_str"] = $"gcp=true&size={bytesSize * 2}";

                // Until the libwrapper supports proper paging spanning over multiple days restrict the amount of entropy we ask for to within 5km
                if (userProfileTemporary.Radius > 5000)
                {
                    userProfileTemporary.Radius = 5000;
                    await _userProfileTemporaryAccessor.SetAsync(stepContext.Context, userProfileTemporary);
                }

                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            default:
            case "ANU":
                stepContext.Values["qrng_source"]           = "ANU";
                stepContext.Values["qrng_source_query_str"] = "";     // generated later in QRNG class
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));
            }
        }
Esempio n. 16
0
        // This step routes the user to different dialogs
        // In this case, there's only one other dialog, so it is more simple,
        // but in more complex scenarios you can go off to other dialogs in a similar
        public async Task <DialogTurnResult> MainMenuAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // Check if we are currently processing a user's search
            var state = await _accessors.PictureState.GetAsync(stepContext.Context);

            // If Regex picks up on anything, store it
            var recognizedIntents = stepContext.Context.TurnState.Get <IRecognizedIntents>();

            // Based on the recognized intent, direct the conversation
            switch (recognizedIntents.TopIntent?.Name)
            {
            case "search":
                // switch to the search dialog
                return(await stepContext.BeginDialogAsync("searchDialog", null, cancellationToken));

            case "share":
                // respond that you're sharing the photo
                await MainResponses.ReplyWithShareConfirmation(stepContext.Context);

                return(await stepContext.EndDialogAsync());

            case "order":
                // respond that you're ordering
                await MainResponses.ReplyWithOrderConfirmation(stepContext.Context);

                return(await stepContext.EndDialogAsync());

            case "help":
                // show help
                await MainResponses.ReplyWithHelp(stepContext.Context);

                return(await stepContext.EndDialogAsync());

            default:
            {
                // Call LUIS recognizer
                var result = await _recognizer.RecognizeAsync(stepContext.Context, cancellationToken);

                // Get the top intent from the results
                var topIntent = result?.GetTopScoringIntent();
                // Based on the intent, switch the conversation, similar concept as with Regex above
                switch ((topIntent != null) ? topIntent.Value.intent : null)
                {
                case null:
                    // Add app logic when there is no result.
                    await MainResponses.ReplyWithConfused(stepContext.Context);

                    break;

                case "None":
                    await MainResponses.ReplyWithConfused(stepContext.Context);

                    // with each statement, we're adding the LuisScore, purely to test, so we know whether LUIS was called or not
                    await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score);

                    break;

                case "Greeting":
                    await MainResponses.ReplyWithGreeting(stepContext.Context);

                    await MainResponses.ReplyWithHelp(stepContext.Context);

                    await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score);

                    break;

                case "OrderPic":
                    await MainResponses.ReplyWithOrderConfirmation(stepContext.Context);

                    await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score);

                    break;

                case "SharePic":
                    await MainResponses.ReplyWithShareConfirmation(stepContext.Context);

                    await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score);

                    break;

                case "SearchPic":
                    await MainResponses.ReplyWithSearchConfirmation(stepContext.Context);

                    await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score);

                    break;

                default:
                    await MainResponses.ReplyWithConfused(stepContext.Context);

                    break;
                }
                return(await stepContext.EndDialogAsync());
            }
            }
        }
Esempio n. 17
0
 private static async Task <DialogTurnResult> EndCheckUserAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {//1
     return(await stepContext.EndDialogAsync());
 }
 private async Task <DialogTurnResult> NoUndeliveredOrderStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     return(await stepContext.PromptAsync(nameof(NoUndeliveredOrderStepAsync), Utils.CreateMessagePrompt(Resource.No_Undelivered_Order, Utils.GetYesNoOptions())));
 }
        protected async Task <string> TryGetEntityValueAsync(WaterfallStepContext stepContext, string key)
        {
            var entityState = await GetEntityStateAsync(stepContext);

            return(entityState.TryGet(key));
        }
Esempio n. 20
0
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var timex = ((List <DateTimeResolution>)stepContext.Result)[0].Timex;

            return(await stepContext.EndDialogAsync(timex, cancellationToken));
        }
Esempio n. 21
0
        private async Task <DialogTurnResult> RecommendSlotsStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            var state = await _stateAccessor.GetAsync(step.Context, cancellationToken : cancellationToken);

            if (state.Services.Count == 0)
            {
                state.Services = ParseServiceSelectionCardResponse(step.Context.Activity);
                await _stateAccessor.SetAsync(step.Context, state, cancellationToken);
            }

            // Check whether we already know something about the date.
            if (state.StartDate != null)
            {
                return(await step.NextAsync(cancellationToken : cancellationToken));
            }

            List <DateTime> recommendedSlots;

            try
            {
                var api = new CarwashService(step, _telemetryClient, cancellationToken);

                var notAvailable = await api.GetNotAvailableDatesAndTimesAsync(cancellationToken);

                recommendedSlots = GetRecommendedSlots(notAvailable);
            }
            catch (AuthenticationException)
            {
                await step.Context.SendActivityAsync(AuthDialog.NotAuthenticatedMessage, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }
            catch (Exception e)
            {
                _telemetryClient.TrackException(e);
                await step.Context.SendActivityAsync(e.Message, cancellationToken : cancellationToken);

                return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
            }

            // Save recommendations to state
            state.RecommendedSlots = recommendedSlots;
            await _stateAccessor.SetAsync(step.Context, state, cancellationToken);

            var choices = new List <Choice>();

            foreach (var slot in recommendedSlots)
            {
                var timex = TimexProperty.FromDateTime(slot);
                choices.Add(new Choice(timex.ToNaturalLanguage(DateTime.Now)));
            }

            return(await step.PromptAsync(
                       RecommendedSlotsPromptName,
                       new PromptOptions
            {
                Prompt = MessageFactory.Text("Can I recommend you one of these slots? If you want to choose something else, just type skip."),
                Choices = choices,
            },
                       cancellationToken));
        }
Esempio n. 22
0
        private async Task <DialogTurnResult> ProcessQuestionDialog(WaterfallStepContext step, CancellationToken cancellationToken = default(CancellationToken))
        {
            var question = (string)step.Result;

            step.ActiveDialog.State["question"] = question;

            if (question == "/start")
            {
                await step.EndDialogAsync();

                return(Dialog.EndOfTurn);
            }

            var recognizerResult = await accessors.LuisServices[Settings.LuisName01].RecognizeAsync(step.Context, cancellationToken);
            var topIntent        = recognizerResult?.GetTopScoringIntent();

            if (topIntent != null && topIntent.HasValue && topIntent.Value.score >= .80 && topIntent.Value.intent != "None")
            {
                step.Context.Activity.Text = topIntent.Value.intent;

                var response = await accessors.QnAServices[Settings.QnAName01].GetAnswersAsync(step.Context);
                if (response != null && response.Length > 0)
                {
                    string responseType = string.Empty;
                    responseType = FindResponseTypeMetadata(response[0].Metadata);
                    await step.Context.SendCustomResponseAsync(response[0].Answer, responseType);

                    if (!string.IsNullOrEmpty(responseType))
                    {
                        if (!topIntent.Value.intent.EndsWith("_Sample"))
                        {
                            List <Choice> choices = new List <Choice>();
                            choices.Add(new Choice {
                                Value = $"Yes"
                            });
                            choices.Add(new Choice {
                                Value = $"No"
                            });

                            var message = $"Would you like to see an example?";
                            await step.Context.SendCustomResponseAsync(message);

                            PromptOptions options = new PromptOptions {
                                Choices = choices
                            };
                            return(await step.PromptAsync("AskForExampleValidator", options, cancellationToken : cancellationToken));
                        }
                    }
                }
                else
                {
                    await accessors.AskForExamplePreference.SetAsync(step.Context, false);

                    await accessors.ConversationState.SaveChangesAsync(step.Context, false, cancellationToken);

                    var message = $"I did not find information to show you";
                    await step.Context.SendCustomResponseAsync(message);
                }
            }
            else
            {
                await accessors.AskForExamplePreference.SetAsync(step.Context, false);

                await accessors.ConversationState.SaveChangesAsync(step.Context, false, cancellationToken);

                var message = $"I did not find information to show you";
                await step.Context.SendCustomResponseAsync(message);
            }

            return(await step.NextAsync());
        }
Esempio n. 23
0
        private async Task <DialogTurnResult> PromptForVehiclePlateNumberConfirmationStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            var state = await _stateAccessor.GetAsync(step.Context, cancellationToken : cancellationToken);

            if (!Slots.Any(s => s.StartTime == state.StartDate?.Hour) && step.Result is FoundChoice choice)
            {
                state.StartDate = state.SlotChoices[choice.Index];
                await _stateAccessor.SetAsync(step.Context, state, cancellationToken);
            }

            // Check last settings
            if (string.IsNullOrEmpty(state.VehiclePlateNumber) &&
                !string.IsNullOrEmpty(state.LastSettings?.VehiclePlateNumber))
            {
                state.VehiclePlateNumber = state.LastSettings.VehiclePlateNumber;
            }

            // Check whether we don't know the vehicle plate number.
            if (string.IsNullOrEmpty(state.VehiclePlateNumber))
            {
                return(await step.NextAsync(cancellationToken : cancellationToken));
            }

            return(await step.PromptAsync(
                       VehiclePlateNumberConfirmationPromptName,
                       new PromptOptions
            {
                Prompt = MessageFactory.Text($"I have {state.VehiclePlateNumber} as your plate number, is that correct?"),
            },
                       cancellationToken));
        }
Esempio n. 24
0
        private async Task <DialogTurnResult> ChoiceActionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            if (Helpers.IsRandoLobby(stepContext.Context))
            {
                // Don't spam Randonauts Telegram Lobby with dialog menus as they get sent to everyone
                return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken));
            }

            // Shortcut to trip report dialog testing
            //return await stepContext.ReplaceDialogAsync(nameof(TripReportDialog), new CallbackOptions(), cancellationToken);

            var userProfilePersistent = await _userProfilePersistentAccessor.GetAsync(stepContext.Context, () => new UserProfilePersistent());

            var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(stepContext.Context, () => new UserProfileTemporary());

            // Must agree to Privacy Policy and Terms of Service before using
            if (!userProfilePersistent.HasAgreedToToS)
            {
                await stepContext.EndDialogAsync(cancellationToken : cancellationToken);

                return(await stepContext.BeginDialogAsync(nameof(PrivacyAndTermsDialog), this, cancellationToken));
            }

            if (stepContext.Options != null)
            {
                // Callback options passed after resuming dialog after long-running background threads etc have finished
                // and resume dialog via the Adapter class's callback method.
                var callbackOptions = (CallbackOptions)stepContext.Options;

                if (callbackOptions.ResetFlag)
                {
                    userProfileTemporary.IsScanning = false;
                    await _userProfileTemporaryAccessor.SetAsync(stepContext.Context, userProfileTemporary, cancellationToken);

                    await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken);
                }

                if (callbackOptions.StartTripReportDialog)
                {
                    return(await stepContext.ReplaceDialogAsync(nameof(TripReportDialog), callbackOptions, cancellationToken));
                }

                if (callbackOptions.UpdateIntentSuggestions)
                {
                    userProfileTemporary.IntentSuggestions        = callbackOptions.IntentSuggestions;
                    userProfileTemporary.TimeIntentSuggestionsSet = callbackOptions.TimeIntentSuggestionsSet;
                    await _userProfileTemporaryAccessor.SetAsync(stepContext.Context, userProfileTemporary, cancellationToken);

                    await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken);
                }

                if (callbackOptions.UpdateSettings)
                {
                    userProfilePersistent.IsIncludeWaterPoints      = userProfileTemporary.IsIncludeWaterPoints;
                    userProfilePersistent.IsDisplayGoogleThumbnails = userProfileTemporary.IsDisplayGoogleThumbnails;
                    await _userProfilePersistentAccessor.SetAsync(stepContext.Context, userProfilePersistent, cancellationToken);

                    await _userPersistentState.SaveChangesAsync(stepContext.Context, false, cancellationToken);
                }
            }

            // Make sure the persistent settings are in synch with the temporary ones
            bool doSync = false;

            if (userProfileTemporary.IsIncludeWaterPoints != userProfilePersistent.IsIncludeWaterPoints)
            {
                userProfileTemporary.IsIncludeWaterPoints = userProfilePersistent.IsIncludeWaterPoints;
                doSync = true;
            }
            if (userProfileTemporary.IsDisplayGoogleThumbnails != userProfilePersistent.IsDisplayGoogleThumbnails)
            {
                userProfileTemporary.IsDisplayGoogleThumbnails = userProfilePersistent.IsDisplayGoogleThumbnails;
                doSync = true;
            }
            if (doSync)
            {
                await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken);
            }

            //_logger.LogInformation("MainDialog.ChoiceActionStepAsync");

            var options = new PromptOptions()
            {
                Prompt      = MessageFactory.Text("What would you like to get?"),
                RetryPrompt = MessageFactory.Text("That is not a valid action. What would you like to get?"),
                Choices     = GetActionChoices(stepContext.Context),
            };

            return(await stepContext.PromptAsync(nameof(ChoicePrompt), options, cancellationToken));
        }
Esempio n. 25
0
        private async Task <DialogTurnResult> InitializeStateStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            var state = await _stateAccessor.GetAsync(step.Context, () => null, cancellationToken);

            if (state == null)
            {
                if (step.Options is NewReservationState o)
                {
                    state = o;
                }
                else
                {
                    state = new NewReservationState();
                }

                await _stateAccessor.SetAsync(step.Context, state, cancellationToken);
            }

            // Load LUIS entities
            var options = step.Options as NewReservationDialogOptions ?? new NewReservationDialogOptions();

            foreach (var entity in options.LuisEntities)
            {
                switch (entity.Type)
                {
                case LuisEntityType.Service:
                    var service = (ServiceModel)entity;
                    state.Services.Add(service.Service);
                    break;

                case LuisEntityType.DateTime:
                    var dateTime = (DateTimeModel)entity;
                    state.Timex = dateTime.Timex;

                    if (dateTime.Timex.Year != null &&
                        dateTime.Timex.Month != null &&
                        dateTime.Timex.DayOfMonth != null)
                    {
                        var hour = dateTime.Timex.Hour ?? 0;
                        state.StartDate = new DateTime(
                            dateTime.Timex.Year.Value,
                            dateTime.Timex.Month.Value,
                            dateTime.Timex.DayOfMonth.Value,
                            hour,
                            0,
                            0);
                    }

                    break;

                case LuisEntityType.Comment:
                    state.Comment = entity.Text;
                    break;

                case LuisEntityType.Private:
                    state.Private = true;
                    break;

                case LuisEntityType.VehiclePlateNumber:
                    state.VehiclePlateNumber = entity.Text;
                    break;
                }
            }

            // Load last reservation settings
            if (string.IsNullOrWhiteSpace(state.VehiclePlateNumber))
            {
                try
                {
                    var api = new CarwashService(step, _telemetryClient, cancellationToken);

                    state.LastSettings = await api.GetLastSettingsAsync(cancellationToken);
                }
                catch (AuthenticationException)
                {
                    await step.Context.SendActivityAsync(AuthDialog.NotAuthenticatedMessage, cancellationToken : cancellationToken);

                    return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
                }
                catch (Exception e)
                {
                    _telemetryClient.TrackException(e);
                    await step.Context.SendActivityAsync(e.Message, cancellationToken : cancellationToken);

                    return(await step.ClearStateAndEndDialogAsync(_stateAccessor, cancellationToken : cancellationToken));
                }
            }

            await _stateAccessor.SetAsync(step.Context, state, cancellationToken);

            return(await step.NextAsync(cancellationToken : cancellationToken));
        }
Esempio n. 26
0
        private async Task <DialogTurnResult> PerformActionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            //_logger.LogInformation($"MainDialog.PerformActionStepAsync[{((FoundChoice)stepContext.Result)?.Value}]");

            var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(stepContext.Context, () => new UserProfileTemporary());

            var actionHandler     = new ActionHandler();
            var repromptThisRound = false;

            switch (((FoundChoice)stepContext.Result)?.Value)
            {
            // Hack coz Facebook Messenge stopped showing "Send Location" button
            case "Set Location":
                repromptThisRound = true;
                await stepContext.Context.SendActivityAsync(CardFactory.CreateGetLocationFromGoogleMapsReply());

                break;

            case "Attractor":
                stepContext.Values["PointType"] = "Attractor";
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            case "Void":
                stepContext.Values["PointType"] = "Void";
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            case "Anomaly":
                stepContext.Values["PointType"] = "Anomaly";
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            case "Intent Suggestions":
                await actionHandler.IntentSuggestionActionAsync(stepContext.Context, userProfileTemporary, cancellationToken, this);

                break;

            case "Pair":
                stepContext.Values["PointType"] = "Pair";
                return(await stepContext.NextAsync(cancellationToken : cancellationToken));

            case "Blind Spots & More":
                await stepContext.EndDialogAsync(cancellationToken : cancellationToken);

                return(await stepContext.BeginDialogAsync(nameof(MoreStuffDialog), this, cancellationToken));

            case "Scan":
                await stepContext.EndDialogAsync(cancellationToken : cancellationToken);

                return(await stepContext.BeginDialogAsync(nameof(ScanDialog), this, cancellationToken));

            case "My Location":
                repromptThisRound = true;
                await actionHandler.LocationActionAsync(stepContext.Context, userProfileTemporary, cancellationToken);

                break;

            case "Settings":
                await stepContext.EndDialogAsync(cancellationToken : cancellationToken);

                return(await stepContext.BeginDialogAsync(nameof(SettingsDialog), this, cancellationToken));
            }

            if (repromptThisRound)
            {
                return(await stepContext.ReplaceDialogAsync(nameof(MainDialog), cancellationToken : cancellationToken));
            }
            else
            {
                // Long-running tasks like /getattractors etc will make use of ContinueDialog to re-prompt users
                return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken));
            }
        }
Esempio n. 27
0
 private async Task <DialogTurnResult> DisplayTokenAsync(WaterfallStepContext context, CancellationToken cancellationToken)
 {
     if (!(context.Result is TokenResponse result))
     {
         await context.Context.SendActivityAsync("No token was provided for the skill.", cancellationToken : cancellationToken);
     }
Esempio n. 28
0
        private async Task <DialogTurnResult> SelectQRNGSourceStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            //_logger.LogInformation($"MainDialog.SelectQRNGSourceStepAsync[{((FoundChoice)stepContext.Result)?.Value}]");

            // Number of IDAs to look for from previous step
            if (stepContext.Result == null)
            {
                stepContext.Values["idacou"] = int.Parse(stepContext.Context.Activity.Text); // manually inputted a number
            }
            else
            {
                stepContext.Values["idacou"] = int.Parse(((FoundChoice)stepContext.Result)?.Value);
            }

            var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(stepContext.Context, () => new UserProfileTemporary());

            if (userProfileTemporary.BotSrc == Enums.WebSrc.ios || userProfileTemporary.BotSrc == Enums.WebSrc.android)
            {
                var options = new PromptOptions()
                {
                    Prompt      = MessageFactory.Text("Chose your entropy source for the quantum random number generator (choose ANU if unsure):"),
                    RetryPrompt = MessageFactory.Text("That is not a valid QRNG source."),
                    Choices     = new List <Choice>()
                    {
                        new Choice()
                        {
                            Value = "Camera"
                        },
                        new Choice()
                        {
                            Value = "ANU"
                        },
                        new Choice()
                        {
                            Value = "ANU Leftovers"
                        },
                        new Choice()
                        {
                            Value = "GCP Retro"
                        },
                    }
                };

                return(await stepContext.PromptAsync(nameof(ChoicePrompt), options, cancellationToken));
            }
            else
            {
                var options = new PromptOptions()
                {
                    Prompt      = MessageFactory.Text("Chose your entropy source for the quantum random number generator (choose ANU if unsure):"),
                    RetryPrompt = MessageFactory.Text("That is not a valid entropy source."),
                    Choices     = new List <Choice>()
                    {
                        //new Choice() { Value = "Camera" },
                        new Choice()
                        {
                            Value = "ANU"
                        },
                        new Choice()
                        {
                            Value = "ANU Leftovers"
                        },
                        new Choice()
                        {
                            Value = "GCP Retro"
                        },
                    }
                };

                return(await stepContext.PromptAsync(nameof(ChoicePrompt), options, cancellationToken));
            }
        }
Esempio n. 29
0
        /// <summary>
        /// This method uses the text of the activity to decide which type
        /// of card to resond with and reply with that card to the user.
        /// </summary>
        /// <param name="step">A <see cref="WaterfallStepContext"/> provides context for the current waterfall step.</param>
        /// <param name="cancellationToken" >(Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="DialogTurnResult"/> indicating the turn has ended.</returns>
        /// <remarks>Related types <see cref="Attachment"/> and <see cref="AttachmentLayoutTypes"/>.</remarks>
        private static async Task <DialogTurnResult> ShowCardStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            // Get the text from the activity to use to show the correct card
            var text = step.Context.Activity.Text.ToLowerInvariant().Split(' ')[0];

            // Replay to the activity we received with an activity.
            var reply = step.Context.Activity.CreateReply();

            // Cards are sent as Attackments in the Bot Framework.
            // So we need to create a list of attachments on the activity.
            reply.Attachments = new List <Attachment>();

            // Decide which type of card(s) we are going to show the user
            if (text.StartsWith("hero"))
            {
                // Display a HeroCard.
                reply.Attachments.Add(GetHeroCard().ToAttachment());
            }
            else if (text.StartsWith("thumb"))
            {
                // Display a ThumbnailCard.
                reply.Attachments.Add(GetThumbnailCard().ToAttachment());
            }
            else if (text.StartsWith("receipt"))
            {
                // Display a ReceiptCard.
                reply.Attachments.Add(GetReceiptCard().ToAttachment());
            }
            else if (text.StartsWith("sign"))
            {
                // Display a SignInCard.
                reply.Attachments.Add(GetSigninCard().ToAttachment());
            }
            else if (text.StartsWith("animation"))
            {
                // Display an AnimationCard.
                reply.Attachments.Add(GetAnimationCard().ToAttachment());
            }
            else if (text.StartsWith("video"))
            {
                // Display a VideoCard
                reply.Attachments.Add(GetVideoCard().ToAttachment());
            }
            else if (text.StartsWith("audio"))
            {
                // Display an AudioCard
                reply.Attachments.Add(GetAudioCard().ToAttachment());
            }
            else if (text.StartsWith("adaptive"))
            {
                reply.Attachments.Add(CreateAdaptiveCardAttachment());
            }
            else
            {
                // Display a carousel of all the rich card types.
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
                reply.Attachments.Add(CreateAdaptiveCardAttachment());
                reply.Attachments.Add(GetHeroCard().ToAttachment());
                reply.Attachments.Add(GetThumbnailCard().ToAttachment());
                reply.Attachments.Add(GetReceiptCard().ToAttachment());
                reply.Attachments.Add(GetSigninCard().ToAttachment());
                reply.Attachments.Add(GetAnimationCard().ToAttachment());
                reply.Attachments.Add(GetVideoCard().ToAttachment());
                reply.Attachments.Add(GetAudioCard().ToAttachment());
            }

            // Send the card(s) to the user as an attachment to the activity
            await step.Context.SendActivityAsync(reply, cancellationToken);

            // Give the user instructions about what to do next
            await step.Context.SendActivityAsync("Type anything to see another card.", cancellationToken : cancellationToken);

            return(await step.EndDialogAsync(cancellationToken : cancellationToken));
        }
Esempio n. 30
0
 private Task <DialogTurnResult> DescriptionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }