/// <summary> /// This step shows how a simple text prompts works /// </summary> /// <remarks> /// To see sample code for other prompt types: https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-compositcontrol?view=azure-bot-service-4.0&tabs=csharp /// </remarks> public async Task <DialogTurnResult> AskForName(WaterfallStepContext sc, CancellationToken cancellationToken) { // Get converation state so we can check to see if name has already been provided _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); await sc.Context.SendActivityAsync("I can help you get a library card!"); // If first name has already been provided if (!string.IsNullOrEmpty(_state.Name)) { // Skip this step and pass first name to next step return(await sc.NextAsync(_state.Name)); } else { return(await sc.PromptAsync(DialogIds.NamePrompt, new PromptOptions { Prompt = MessageFactory.Text("What's your name?") })); // To localize a multilingual bot, use the approach below instead of the one above //return await sc.PromptAsync(DialogIds.NamePrompt, new PromptOptions() //{ // Prompt = await _responder.RenderTemplate(sc.Context, sc.Context.Activity.Locale, OnboardingResponses.ResponseIds.NamePrompt), //}); } }
/// <summary> /// This step shows how bot can creatively tie into existing business process (email in this case) /// </summary> /// <remarks> /// This step shows how a bot might integrate with an existing business process /// that is email based to verify a code that is sent to the bot user. It's /// another example of leveraging custom validation. /// </remarks> public async Task <DialogTurnResult> GetVerificationCode(WaterfallStepContext sc, CancellationToken cancellationToken) { // Get conversation state so we can have access to email that was provided previously _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); return(await sc.PromptAsync(DialogIds.VerificationPrompt, new PromptOptions { Prompt = MessageFactory.Text($"We've sent a verification email to {_state.Email}. Please enter the verification code"), // Provide retry prompt for custom verification code validation for TextPrompt RetryPrompt = MessageFactory.Text("Sorry, that is an invalid verification code. Please check code and try again.") })); }
/// <summary> /// The last step sums up the conversation /// </summary> /// <remarks> /// The last step in a dialog generally sums up the conversation and /// performs an action that achieves the goal of the conversation which /// in this example would be to call a back end service to create a /// library membership for the user and send them a confirmation email. /// </remarks> public async Task <DialogTurnResult> FinishGetLibraryCardDialog(WaterfallStepContext sc, CancellationToken cancellationToken) { _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); // Save the answer from the previous step in conversation state string verificationCode = (string)sc.Result; // Provide summary of conversation for this dialog await sc.Context.SendActivityAsync($"We're all set {_state.Name}! A confirmation will all your membership details will be emailed to {_state.Email}"); // ToDo Phase 2 - Step 01: Perform goal of conversation here (call membership service in this case) // libraryService.CreateMembership(_state); return(await sc.EndDialogAsync()); }
/// <summary> /// Silent branching step to decide what direction the conversation should go /// </summary> /// <remarks> /// This step shows another example of how to manage conversation flow. /// It's also interesting in that its a step without an associatede dialog /// prompt so its sole job is deciding how to proceed given the current /// context/state of the conversation (i.e. end dialog or continue to /// next step) /// /// To test the "end dialog" branch, enter "already@member" when asked for /// email. /// </remarks> public async Task <DialogTurnResult> CheckIfAlreadyMember(WaterfallStepContext sc, CancellationToken cancellationToken) { _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); // Save the answer from the previous step in conversation state _state.Email = (string)sc.Result; await _accessor.SetAsync(sc.Context, _state, cancellationToken); if (_state.Email == "already@member") { await sc.Context.SendActivityAsync($"Looks like you already have a library card. We'll send your membership information to {_state.Email}"); return(await sc.EndDialogAsync()); } else { // We can safely move to next next step return(await sc.NextAsync()); } }
/// <summary> /// This step shows how to provide a custom retry prompt for custom validation /// </summary> /// <remarks> /// Other than providing the custom retry prompt, this step is just another /// example of a simple prompt /// </remarks> public async Task <DialogTurnResult> AskForEmail(WaterfallStepContext sc, CancellationToken cancellationToken) { _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); // Save the answer from the previous step in conversation state _state.Age = (int)sc.Result; await _accessor.SetAsync(sc.Context, _state, cancellationToken); if (!string.IsNullOrEmpty(_state.Email)) { // Skip this step and pass email to next step return(await sc.NextAsync(_state.Email)); } else { return(await sc.PromptAsync(DialogIds.EmailPrompt, new PromptOptions { Prompt = MessageFactory.Text("What is your email?"), // Provide retry prompt for custom email validation on a TextPrompt RetryPrompt = MessageFactory.Text("That's not a valid email address, please try again") })); } }
/// <summary> /// This step shows how to code a numeric prompt which shows an example of /// the framework's built-in validation /// </summary> /// <remarks> /// The built-in validation for a NumberPrompt<int> will only accept an integer /// so you can enter any non-integer value to see the built-in validation in action /// </remarks> public async Task <DialogTurnResult> AskForAge(WaterfallStepContext sc, CancellationToken cancellationToken) { _state = await _accessor.GetAsync(sc.Context, () => new MembershipState()); // Save the answer from the previous step in conversation state _state.Name = (string)sc.Result; await _accessor.SetAsync(sc.Context, _state, cancellationToken); // If age has already been provided if (_state.Age != 0) { // Skip this step and pass age to next step return(await sc.NextAsync(_state.Age)); } else { return(await sc.PromptAsync(DialogIds.AgePrompt, new PromptOptions { Prompt = MessageFactory.Text("How old are you?"), // Override the built-in integer retry prompt with a scenario-friendly one RetryPrompt = MessageFactory.Text("Please enter age as an integer") })); } }