public DialogueBotWithAccessor(DialogueBotConversationStateAccessor accessors) { _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors)); _dialogSet = new DialogSet(_accessors.ConversationDialogState); _dialogSet.Add(new TextPrompt("name")); }
public async Task WaterfallCosmos() { var convoState = new ConversationState(_storage); var adapter = new TestAdapter(TestAdapter.CreateConversation(nameof(WaterfallCosmos))) .Use(new AutoSaveStateMiddleware(convoState)); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var dialogs = new DialogSet(dialogState); dialogs.Add(new TextPrompt(nameof(TextPrompt), async(promptContext, cancellationToken) => { var result = promptContext.Recognized.Value; if (result.Length > 3) { var succeededMessage = MessageFactory.Text($"You got it at the {promptContext.AttemptCount}th try!"); await promptContext.Context.SendActivityAsync(succeededMessage, cancellationToken); return(true); } var reply = MessageFactory.Text($"Please send a name that is longer than 3 characters. {promptContext.AttemptCount}"); await promptContext.Context.SendActivityAsync(reply, cancellationToken); return(false); })); var steps = new WaterfallStep[] { async(stepContext, ct) => { Assert.Equal(typeof(int), stepContext.ActiveDialog.State["stepIndex"].GetType()); await stepContext.Context.SendActivityAsync("step1"); return(Dialog.EndOfTurn); }, async(stepContext, ct) => { Assert.Equal(typeof(int), stepContext.ActiveDialog.State["stepIndex"].GetType()); return(await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please type your name.") }, ct)); }, async(stepContext, ct) => { Assert.Equal(typeof(int), stepContext.ActiveDialog.State["stepIndex"].GetType()); await stepContext.Context.SendActivityAsync("step3"); return(Dialog.EndOfTurn); }, }; dialogs.Add(new WaterfallDialog(nameof(WaterfallDialog), steps)); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext); await dc.ContinueDialogAsync(); if (!turnContext.Responded) { await dc.BeginDialogAsync(nameof(WaterfallDialog)); } }) .Send("hello") .AssertReply("step1") .Send("hello") .AssertReply("Please type your name.") .Send("hi") .AssertReply("Please send a name that is longer than 3 characters. 1") .Send("hi") .AssertReply("Please send a name that is longer than 3 characters. 2") .Send("hi") .AssertReply("Please send a name that is longer than 3 characters. 3") .Send("Kyle") .AssertReply("You got it at the 4th try!") .AssertReply("step3") .StartTestAsync(); }
/// <summary> /// Initializes a new instance of the <see cref="PromptValidationsBot"/> class. /// </summary> /// <param name="accessors">The state accessors this instance will be needing at runtime.</param> public PromptValidationsBot(BotAccessors accessors) { _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors)); _dialogs = new DialogSet(accessors.ConversationDialogState); _dialogs.Add(new TextPrompt("name", CustomPromptValidatorAsync)); }
public async Task ShouldSendPromptUsingAppendedHeroCard() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(convoState)); var dialogs = new DialogSet(dialogState); var listPrompt = new ChoicePrompt("ChoicePrompt", defaultLocale: Culture.English) { Style = ListStyle.HeroCard, }; dialogs.Add(listPrompt); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { // Create mock attachment for testing. var attachment = new Attachment { Content = "some content", ContentType = "text/plain" }; await dc.PromptAsync( "ChoicePrompt", new PromptOptions { Prompt = new Activity { Type = ActivityTypes.Message, Text = "favorite color?", Attachments = new List <Attachment> { attachment } }, Choices = _colorChoices, }, cancellationToken); } }) .Send("hello") .AssertReply(HeroCardValidator( new HeroCard { Text = "favorite color?", Buttons = new List <CardAction> { new CardAction { Type = "imBack", Value = "red", Title = "red" }, new CardAction { Type = "imBack", Value = "green", Title = "green" }, new CardAction { Type = "imBack", Value = "blue", Title = "blue" }, }, }, 1)) .StartTestAsync(); }
public WelcomeMessageWithAccessorBot(DialogBotConversationStateAndUserStateAccessor accessor) { _dialogBotConversationStateAndUserStateAccessor = accessor ?? throw new ArgumentNullException(nameof(accessor)); _dialogSet = new DialogSet(_dialogBotConversationStateAndUserStateAccessor.ConversationDialogState); _dialogSet.Add(new TextPrompt("name")); }
public MovieRecommendationBot() { dialogs = new DialogSet(); // Define our dialog dialogs.Add("movieRecommendation", new WaterfallStep[] { async(dc, args, next) => { await dc.Context.SendActivity("Welcome to the movie recommendation service."); await dc.Prompt("movieTypePrompt", "What type of movie are you looking for?"); }, async(dc, args, next) => { movieType = args["Text"].ToString().ToLowerInvariant(); // Ask for next info await dc.Prompt("favoriteActorPrompt", "Who is your favorite actor?"); }, async(dc, args, next) => { favoriteActor = args["Text"].ToString().ToLowerInvariant(); // Ask for next info await dc.Prompt("ratingPrompt", "What is the least number of stars you would want in this movie?"); }, async(dc, args, next) => { Movie movieMatch; movieMatch = movies.MovieList.Where(movie => (movie.Genre.ToLowerInvariant().Equals(movieType) && movie.Actors.Contains(favoriteActor.ToLowerInvariant())) && movie.Rating > (int)args["Value"] ).FirstOrDefault(); if (movieMatch == null) { movieMatch = movies.MovieList.Where(movie => (movie.Genre.ToLowerInvariant().Equals(movieType) || movie.Actors.Contains(favoriteActor.ToLowerInvariant())) && movie.Rating > (int)args["Value"] ).FirstOrDefault(); } if (movieMatch != null) { string msg = "I found a movie that you might want to check out. " + $"\nMovie Name: {movieMatch.MovieName.ToString()} " + $"\nRelease Year: {movieMatch.ReleaseYear.ToString()} " + $"\nGenre: {movieMatch.Genre.ToString()} " + $"\nRating: {movieMatch.Rating} " + $"\nActors: {string.Join(", ", movieMatch.Actors.ToArray())}"; await dc.Context.SendActivity(msg); await dc.End(); } else { Movie goodMovie = movies.MovieList.Where(movie => movie.Rating >= (int)args["Value"]).First(); if (goodMovie == null) { Random rnd = new Random(); int index = rnd.Next(0, movies.MovieList.Count() - 1); //Random movie becomes good movie when you don't have a match goodMovie = movies.MovieList.ElementAt(index); } string msg = "I couldn't find an exact match for you but may I recommend the following: " + $"\nMovie Name: {goodMovie.MovieName.ToString()} " + $"\nRelease Year: {goodMovie.ReleaseYear.ToString()} " + $"\nGenre: {goodMovie.Genre.ToString()} " + $"\nRating: {goodMovie.Rating}" + $"\nActors: {string.Join(",", goodMovie.Actors.ToArray())}"; await dc.Context.SendActivity(msg); await dc.End(); } } }); // Add a prompt for the movie type dialogs.Add("movieTypePrompt", new Microsoft.Bot.Builder.Dialogs.TextPrompt()); // Add a prompt for a favorite actor dialogs.Add("favoriteActorPrompt", new Microsoft.Bot.Builder.Dialogs.TextPrompt()); // Add a prompt for a movie's rating dialogs.Add("ratingPrompt", new Microsoft.Bot.Builder.Dialogs.NumberPrompt <int>(Culture.English)); }
public async Task CallDialogDefinedInParentComponent() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(convoState)); var options = new Dictionary <string, string> { { "value", "test" } }; var childComponent = new ComponentDialog("childComponent"); var childActions = new WaterfallStep[] { async(step, ct) => { await step.Context.SendActivityAsync("Child started."); return(await step.BeginDialogAsync("parentDialog", options)); }, async(step, ct) => { Assert.Equal("test", (string)step.Result); await step.Context.SendActivityAsync("Child finished."); return(await step.EndDialogAsync()); }, }; childComponent.AddDialog(new WaterfallDialog( "childDialog", childActions)); var parentComponent = new ComponentDialog("parentComponent"); parentComponent.AddDialog(childComponent); var parentActions = new WaterfallStep[] { async(step, dc) => { var stepOptions = step.Options as IDictionary <string, string>; Assert.NotNull(stepOptions); Assert.True(stepOptions.ContainsKey("value")); await step.Context.SendActivityAsync($"Parent called with: {stepOptions["value"]}"); return(await step.EndDialogAsync(stepOptions["value"])); }, }; parentComponent.AddDialog(new WaterfallDialog( "parentDialog", parentActions)); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dialogs = new DialogSet(dialogState); dialogs.Add(parentComponent); var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.BeginDialogAsync("parentComponent", null, cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { var value = (int)results.Result; await turnContext.SendActivityAsync(MessageFactory.Text("Done"), cancellationToken); } }) .Send("Hi") .AssertReply("Child started.") .AssertReply("Parent called with: test") .AssertReply("Child finished.") .StartTestAsync(); }
public async Task ConfirmPromptChoiceOptionsMultipleAttempts() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); var dialogs = new DialogSet(dialogState); var prompt = new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English); // Set options prompt.ChoiceOptions = new Choices.ChoiceFactoryOptions { IncludeNumbers = true }; prompt.Style = Choices.ListStyle.Inline; dialogs.Add(prompt); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { var options = new PromptOptions { Prompt = new Activity { Type = ActivityTypes.Message, Text = "Please confirm.", }, RetryPrompt = new Activity { Type = ActivityTypes.Message, Text = "Please confirm, say 'yes' or 'no' or something like that.", }, }; await dc.PromptAsync("ConfirmPrompt", options, cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { if ((bool)results.Result) { await turnContext.SendActivityAsync(MessageFactory.Text("Confirmed."), cancellationToken); } else { await turnContext.SendActivityAsync(MessageFactory.Text("Not confirmed."), cancellationToken); } } }) .Send("hello") .AssertReply("Please confirm. (1) Yes or (2) No") .Send("lala") .AssertReply("Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No") .Send("what") .AssertReply("Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No") .Send("2") .AssertReply("Not confirmed.") .StartTestAsync(); }
public BotControllerBase(BotAccessors accessors) { this.Accessors = accessors; Dialogs = new DialogSet(accessors.DialogData); }
public async void SendValidImageTest() { var storage = new MemoryStorage(); var userState = new UserState(storage); var conversationState = new ConversationState(storage); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(conversationState)); var accessors = new BotAccessors(new LoggerFactory(), conversationState, userState, new Dictionary <string, LuisRecognizer>(), new Dictionary <string, QnAMaker>()) { ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"), AskForExamplePreference = conversationState.CreateProperty <bool>("AskForExamplePreference"), DetectedFaceIdPreference = conversationState.CreateProperty <string>("DetectedFaceIdPreference"), ImageUriPreference = conversationState.CreateProperty <string>("ImageUriPreference"), HashPreference = conversationState.CreateProperty <string>("HashPreference"), IsNewPreference = conversationState.CreateProperty <bool>("IsNewPreference"), FullnamePreference = userState.CreateProperty <string>("FullnamePreference"), NamePreference = userState.CreateProperty <string>("NamePreference"), LastnamePreference = userState.CreateProperty <string>("LastnamePreference"), IsAuthenticatedPreference = userState.CreateProperty <bool>("IsAuthenticatedPreference") }; var attachment = new Attachment { ContentUrl = "https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260", ContentType = "image/jpeg" }; Activity activity = new Activity { Type = ActivityTypes.Message, Attachments = new List <Attachment> { attachment } }; await new TestFlow(adapter, async(turnContext, cancellationToken) => { var state = await accessors.ConversationDialogState.GetAsync(turnContext, () => new DialogState()); var dialogs = new DialogSet(accessors.ConversationDialogState); dialogs.Add(new AskForFaceImageDialog(accessors)); var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.BeginDialogAsync(AskForFaceImageDialog.dialogId, null, cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { string detectedFaceIdPreference = await accessors.DetectedFaceIdPreference.GetAsync(turnContext, () => { return(string.Empty); }); string imageUriPreference = await accessors.ImageUriPreference.GetAsync(turnContext, () => { return(string.Empty); }); string hashPreference = await accessors.HashPreference.GetAsync(turnContext, () => { return(string.Empty); }); //delete file from storage await StorageHelper.DeleteFileAsync($"{hashPreference}.jpg", "uploads", Settings.AzureWebJobsStorage); Assert.True(detectedFaceIdPreference.Length > 0); Assert.True(imageUriPreference.Length > 0); Assert.True(hashPreference.Length > 0); } }) .Send("") .AssertReply("Let's go to identify you, send me a picture of you") .Send(activity) .StartTestAsync(); }
public async void SendTxtFileTest() { var storage = new MemoryStorage(); var userState = new UserState(storage); var conversationState = new ConversationState(storage); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(conversationState)); var accessors = new BotAccessors(new LoggerFactory(), conversationState, userState, new Dictionary <string, LuisRecognizer>(), new Dictionary <string, QnAMaker>()) { ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"), AskForExamplePreference = conversationState.CreateProperty <bool>("AskForExamplePreference"), DetectedFaceIdPreference = conversationState.CreateProperty <string>("DetectedFaceIdPreference"), ImageUriPreference = conversationState.CreateProperty <string>("ImageUriPreference"), HashPreference = conversationState.CreateProperty <string>("HashPreference"), IsNewPreference = conversationState.CreateProperty <bool>("IsNewPreference"), FullnamePreference = userState.CreateProperty <string>("FullnamePreference"), NamePreference = userState.CreateProperty <string>("NamePreference"), LastnamePreference = userState.CreateProperty <string>("LastnamePreference"), IsAuthenticatedPreference = userState.CreateProperty <bool>("IsAuthenticatedPreference") }; var attachment = new Attachment { Content = "my txt file", ContentType = "text/plain" }; Activity activity = new Activity { Type = ActivityTypes.Message, Attachments = new List <Attachment> { attachment } }; await new TestFlow(adapter, async(turnContext, cancellationToken) => { var state = await accessors.ConversationDialogState.GetAsync(turnContext, () => new DialogState()); var dialogs = new DialogSet(accessors.ConversationDialogState); dialogs.Add(new AskForFaceImageDialog(accessors)); var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.BeginDialogAsync(AskForFaceImageDialog.dialogId, null, cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { //no additional send activities. } }) .Send("") .AssertReply("Let's go to identify you, send me a picture of you") .Send(activity) .AssertReply("Sorry, I just can understand jpeg files, try again with other picture") .StartTestAsync(); }
/// <summary> /// Initializes a new instance of the <see cref="SimplePromptBot"/> class. /// </summary> /// <param name="accessors">The state accessors this instance will be needing at runtime.</param> public SimplePromptBot(SimplePromptBotAccessors accessors) { _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors)); _dialogs = new DialogSet(accessors.ConversationDialogState); _dialogs.Add(new TextPrompt("name")); }
public SequenceContext(DialogSet dialogs, DialogContext dc, DialogState state, List <ActionState> actions, string changeKey, DialogSet actionDialogs) : base(dialogs, dc, state) { this.Actions = actions; this.changeKey = changeKey; this.actionDialogs = actionDialogs; }
public new void Initialize() { var builder = new ContainerBuilder(); ConversationState = new ConversationState(new MemoryStorage()); DialogState = ConversationState.CreateProperty <DialogState>(nameof(DialogState)); UserState = new UserState(new MemoryStorage()); ProactiveState = new ProactiveState(new MemoryStorage()); TelemetryClient = new NullBotTelemetryClient(); BackgroundTaskQueue = new BackgroundTaskQueue(); EndpointService = new EndpointService(); SkillConfigurations = new Dictionary <string, SkillConfigurationBase>(); // Add the LUIS model fakes used by the Skill Services = new MockSkillConfiguration(); Services.LocaleConfigurations.Add("en", new LocaleConfiguration() { Locale = "en-us", LuisServices = new Dictionary <string, ITelemetryLuisRecognizer> { { "general", GeneralTestUtil.CreateRecognizer() }, { "FakeSkill", FakeSkillTestUtil.CreateRecognizer() } } }); Services.LocaleConfigurations.Add("es", new LocaleConfiguration() { Locale = "es-mx", LuisServices = new Dictionary <string, ITelemetryLuisRecognizer> { { "general", GeneralTestUtil.CreateRecognizer() }, { "FakeSkill", FakeSkillTestUtil.CreateRecognizer() } } }); // Dummy Authentication connection for Auth testing Services.AuthenticationConnections = new Dictionary <string, string> { { "DummyAuth", "DummyAuthConnection" } }; builder.RegisterInstance(new BotStateSet(UserState, ConversationState)); Container = builder.Build(); Dialogs = new DialogSet(DialogState); var locales = new string[] { "en-us", "de-de", "es-es", "fr-fr", "it-it", "zh-cn" }; ResponseManager = new ResponseManager( locales, new SampleAuthResponses(), new MainResponses(), new SharedResponses(), new SampleResponses()); // Manually mange the conversation metadata when we need finer grained control ConversationReference = new ConversationReference { ChannelId = "test", ServiceUrl = "https://test.com", }; ConversationReference.User = new ChannelAccount("user1", "User1"); ConversationReference.Bot = new ChannelAccount("bot", "Bot"); ConversationReference.Conversation = new ConversationAccount(false, "convo1", "Conversation1"); }
private async Task PromptTimeoutEndsDialogTest(IActivity oauthPromptActivity) { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(convoState)); var connectionName = "myConnection"; var exchangeToken = "exch123"; var magicCode = "888999"; var token = "abc123"; // Create new DialogSet. var dialogs = new DialogSet(dialogState); // Set timeout to zero, so the prompt will end immediately. dialogs.Add(new OAuthPrompt("OAuthPrompt", new OAuthPromptSettings() { Text = "Please sign in", ConnectionName = connectionName, Title = "Sign in", Timeout = 0 })); BotCallbackHandler botCallbackHandler = async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.PromptAsync("OAuthPrompt", new PromptOptions(), cancellationToken : cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { // If the TokenResponse comes back, the timeout did not occur. if (results.Result is TokenResponse) { await turnContext.SendActivityAsync("failed", cancellationToken : cancellationToken); } else { await turnContext.SendActivityAsync("ended", cancellationToken : cancellationToken); } } }; await new TestFlow(adapter, botCallbackHandler) .Send("hello") .AssertReply(activity => { Assert.Single(((Activity)activity).Attachments); Assert.Equal(OAuthCard.ContentType, ((Activity)activity).Attachments[0].ContentType); // Add a magic code to the adapter adapter.AddUserToken(connectionName, activity.ChannelId, activity.Recipient.Id, token, magicCode); // Add an exchangable token to the adapter adapter.AddExchangeableToken(connectionName, activity.ChannelId, activity.Recipient.Id, exchangeToken, token); }) .Send(oauthPromptActivity) .AssertReply("ended") .StartTestAsync(); }
public async Task OAuthPromptBeginLoggedIn() { // Arrange var userId = "user-id"; var connectionName = "connection-name"; var channelId = "channel-id"; string magicCode = null; // Arrange the Adapter. var mockConnectorFactory = new Mock <ConnectorFactory>(); mockConnectorFactory.Setup( x => x.CreateAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConnectorClient(new Uri("http://tempuri/"))); var mockUserTokenClient = new Mock <UserTokenClient>(); mockUserTokenClient.Setup( x => x.GetUserTokenAsync(It.Is <string>(s => s == userId), It.Is <string>(s => s == connectionName), It.Is <string>(s => s == channelId), It.Is <string>(s => s == magicCode), It.IsAny <CancellationToken>())) .ReturnsAsync(new TokenResponse { ChannelId = channelId, ConnectionName = connectionName, Token = $"TOKEN" }); var authenticateRequestResult = new AuthenticateRequestResult { CallerId = "callerId", ClaimsIdentity = new ClaimsIdentity(), ConnectorFactory = mockConnectorFactory.Object, }; var mockBotFrameworkAuthentication = new Mock <BotFrameworkAuthentication>(); mockBotFrameworkAuthentication.Setup( x => x.AuthenticateRequestAsync(It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(authenticateRequestResult); mockBotFrameworkAuthentication.Setup( x => x.CreateUserTokenClientAsync(It.IsAny <ClaimsIdentity>(), It.IsAny <CancellationToken>())) .ReturnsAsync(mockUserTokenClient.Object); var adapter = new TestCloudAdapter(mockBotFrameworkAuthentication.Object); // Arrange the Dialogs. var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var dialogs = new DialogSet(dialogState); // Add the OAuthPrompt. var oauthPromptSettings = new OAuthPromptSettings { ConnectionName = connectionName, Text = "Please sign in", Title = "Sign in", }; dialogs.Add(new OAuthPrompt("OAuthPrompt", oauthPromptSettings)); // The on-turn callback. DialogTurnResult dialogTurnResult = null; BotCallbackHandler callback = async(turnContext, cancellationToken) => { var dialogContext = await dialogs.CreateContextAsync(turnContext); dialogTurnResult = await dialogContext.BeginDialogAsync("OAuthPrompt"); }; // The Activity for the turn. var activity = new Activity { Type = ActivityTypes.Message, From = new ChannelAccount { Id = userId }, Conversation = new ConversationAccount { Id = "conversation-id" }, Text = "hi", ChannelId = channelId }; // Act var invokeResponse = await adapter.ProcessAsync(string.Empty, activity, callback); // Assert Assert.Equal(DialogTurnStatus.Complete, dialogTurnResult.Status); Assert.IsType <TokenResponse>(dialogTurnResult.Result); Assert.Equal("TOKEN", ((TokenResponse)dialogTurnResult.Result).Token); }
public UpdateResourceDialog(StateAccessors state, DialogSet dialogs, IApiInterface api, IConfiguration configuration) : base(state, dialogs, api, configuration) { }
public async Task OAuthPromptBeginNotLoggedIn_SignInCard() { // Arrange var userId = "user-id"; var connectionName = "connection-name"; var channelId = Channels.Skype; string magicCode = null; // Arrange the Adapter. var mockConnectorFactory = new Mock <ConnectorFactory>(); mockConnectorFactory.Setup( x => x.CreateAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConnectorClient(new Uri("http://tempuri/"))); var mockUserTokenClient = new Mock <UserTokenClient>(); mockUserTokenClient.Setup( x => x.GetUserTokenAsync(It.Is <string>(s => s == userId), It.Is <string>(s => s == connectionName), It.Is <string>(s => s == channelId), It.Is <string>(s => s == magicCode), It.IsAny <CancellationToken>())) .ReturnsAsync((TokenResponse)null); mockUserTokenClient.Setup( x => x.GetSignInResourceAsync(It.Is <string>(s => s == connectionName), It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new SignInResource()); var authenticateRequestResult = new AuthenticateRequestResult { CallerId = "callerId", ClaimsIdentity = new ClaimsIdentity(), ConnectorFactory = mockConnectorFactory.Object, }; var mockBotFrameworkAuthentication = new Mock <BotFrameworkAuthentication>(); mockBotFrameworkAuthentication.Setup( x => x.AuthenticateRequestAsync(It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(authenticateRequestResult); mockBotFrameworkAuthentication.Setup( x => x.CreateUserTokenClientAsync(It.IsAny <ClaimsIdentity>(), It.IsAny <CancellationToken>())) .ReturnsAsync(mockUserTokenClient.Object); var adapter = new TestCloudAdapter(mockBotFrameworkAuthentication.Object); // Arrange the Dialogs. var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var dialogs = new DialogSet(dialogState); // Add the OAuthPrompt. var oauthPromptSettings = new OAuthPromptSettings { ConnectionName = connectionName, Text = "Please sign in", Title = "Sign in", }; dialogs.Add(new OAuthPrompt("OAuthPrompt", oauthPromptSettings)); // The on-turn callback. DialogTurnResult dialogTurnResult = null; BotCallbackHandler callback = async(turnContext, cancellationToken) => { var dialogContext = await dialogs.CreateContextAsync(turnContext); dialogTurnResult = await dialogContext.BeginDialogAsync("OAuthPrompt"); }; // The Activity for the turn. var activity = new Activity { Type = ActivityTypes.Message, From = new ChannelAccount { Id = userId }, Conversation = new ConversationAccount { Id = "conversation-id" }, Text = "hi", ChannelId = channelId, }; // Act var invokeResponse = await adapter.ProcessAsync(string.Empty, activity, callback); // Assert Assert.Equal(DialogTurnStatus.Waiting, dialogTurnResult.Status); Assert.Single(adapter.SentActivities); var sentActivity = adapter.SentActivities.First(); Assert.Equal(ActivityTypes.Message, sentActivity.Type); Assert.Single(sentActivity.Attachments); var sentActivityAttachment = sentActivity.Attachments.First(); Assert.Equal(SigninCard.ContentType, sentActivityAttachment.ContentType); Assert.IsType <SigninCard>(sentActivityAttachment.Content); // TODO: complete verification of shape of outbound attachment var signinCard = (SigninCard)sentActivityAttachment.Content; Assert.Equal(oauthPromptSettings.Text, signinCard.Text); }
public async Task CallDialogInParentComponent() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter(TestAdapter.CreateConversation(nameof(CallDialogDefinedInParentComponent))) .Use(new AutoSaveStateMiddleware(convoState)) .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var state = await dialogState.GetAsync(turnContext, () => new DialogState()); var dialogs = new DialogSet(dialogState); var childComponent = new ComponentDialog("childComponent"); var childStep = new WaterfallStep[] { async(step, token) => { await step.Context.SendActivityAsync("Child started."); return(await step.BeginDialogAsync("parentDialog", "test")); }, async(step, token) => { await step.Context.SendActivityAsync($"Child finished. Value: {step.Result}"); return(await step.EndDialogAsync()); } }; childComponent.AddDialog(new WaterfallDialog("childDialog", childStep)); var parentComponent = new ComponentDialog("parentComponent"); parentComponent.AddDialog(childComponent); var parentStep = new WaterfallStep[] { async(step, token) => { await step.Context.SendActivityAsync("Parent called."); return(await step.EndDialogAsync(step.Options)); } }; parentComponent.AddDialog(new WaterfallDialog("parentDialog", parentStep)); dialogs.Add(parentComponent); var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.BeginDialogAsync("parentComponent", null, cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { var value = (int)results.Result; await turnContext.SendActivityAsync(MessageFactory.Text($"Bot received the number '{value}'."), cancellationToken); } }) .Send("Hi") .AssertReply("Child started.") .AssertReply("Parent called.") .AssertReply("Child finished. Value: test") .StartTestAsync(); }
public async Task OAuthPromptContinueWithTimeout() { // Arrange // Arrange the Adapter. var mockConnectorFactory = new Mock <ConnectorFactory>(); mockConnectorFactory.Setup( x => x.CreateAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConnectorClient(new Uri("http://tempuri/"))); var mockUserTokenClient = new Mock <UserTokenClient>(); var authenticateRequestResult = new AuthenticateRequestResult { CallerId = "callerId", ClaimsIdentity = new ClaimsIdentity(), ConnectorFactory = mockConnectorFactory.Object, }; var mockBotFrameworkAuthentication = new Mock <BotFrameworkAuthentication>(); mockBotFrameworkAuthentication.Setup( x => x.AuthenticateRequestAsync(It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(authenticateRequestResult); mockBotFrameworkAuthentication.Setup( x => x.CreateUserTokenClientAsync(It.IsAny <ClaimsIdentity>(), It.IsAny <CancellationToken>())) .ReturnsAsync(mockUserTokenClient.Object); var adapter = new TestCloudAdapter(mockBotFrameworkAuthentication.Object); // Arrange the Dialogs. var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var dialogs = new DialogSet(dialogState); // Add the OAuthPrompt. var oauthPromptSettings = new OAuthPromptSettings { Text = "Please sign in", ConnectionName = "myConnection", Title = "Sign in", }; dialogs.Add(new OAuthPrompt("OAuthPrompt", oauthPromptSettings)); // The on-turn callback. DialogTurnResult dialogTurnResult = null; BotCallbackHandler callback = async(turnContext, cancellationToken) => { var dialogContext = await dialogs.CreateContextAsync(turnContext); dialogContext.Stack.Insert(0, new DialogInstance { Id = "OAuthPrompt", State = new Dictionary <string, object> { { "expires", DateTime.UtcNow.AddMinutes(-5) } } }); dialogTurnResult = await dialogContext.ContinueDialogAsync(); }; // The Activity for the turn. var activity = new Activity { Type = ActivityTypes.Message, From = new ChannelAccount { Id = "from-id" }, Conversation = new ConversationAccount { Id = "conversation-id" }, Text = "hi", ChannelId = "channel-id" }; // Act var invokeResponse = await adapter.ProcessAsync(string.Empty, activity, callback); // Assert Assert.Equal(DialogTurnStatus.Complete, dialogTurnResult.Status); Assert.Null(dialogTurnResult.Result); }
public NewUserDialog(StateAccessors state, DialogSet dialogs, IApiInterface api, IConfiguration configuration) : base(state, dialogs, api, configuration) { }
public async Task OAuthPromptContinueWithInvokeTokenExchange() { // Arrange var userId = "user-id"; var connectionName = "connection-name"; var channelId = "channel-id"; var tokenExchangeRequestToken = "123456"; var tokenExchangeInvokeRequestId = "tokenExchangeInvokeRequest-id"; // Arrange the Adapter. var mockConnectorFactory = new Mock <ConnectorFactory>(); mockConnectorFactory.Setup( x => x.CreateAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConnectorClient(new Uri("http://tempuri/"))); var mockUserTokenClient = new Mock <UserTokenClient>(); mockUserTokenClient.Setup( x => x.ExchangeTokenAsync(It.Is <string>(s => s == userId), It.Is <string>(s => s == connectionName), It.Is <string>(s => s == channelId), It.Is <TokenExchangeRequest>(ter => ter.Token == tokenExchangeRequestToken), It.IsAny <CancellationToken>())) .ReturnsAsync(new TokenResponse { ChannelId = channelId, ConnectionName = connectionName, Token = $"TOKEN" }); var authenticateRequestResult = new AuthenticateRequestResult { CallerId = "callerId", ClaimsIdentity = new ClaimsIdentity(), ConnectorFactory = mockConnectorFactory.Object, }; var mockBotFrameworkAuthentication = new Mock <BotFrameworkAuthentication>(); mockBotFrameworkAuthentication.Setup( x => x.AuthenticateRequestAsync(It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(authenticateRequestResult); mockBotFrameworkAuthentication.Setup( x => x.CreateUserTokenClientAsync(It.IsAny <ClaimsIdentity>(), It.IsAny <CancellationToken>())) .ReturnsAsync(mockUserTokenClient.Object); var adapter = new TestCloudAdapter(mockBotFrameworkAuthentication.Object); // Arrange the Dialogs. var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var dialogs = new DialogSet(dialogState); // Add the OAuthPrompt. var oauthPromptSettings = new OAuthPromptSettings { Text = "Please sign in", ConnectionName = connectionName, Title = "Sign in", }; dialogs.Add(new OAuthPrompt("OAuthPrompt", oauthPromptSettings)); // The on-turn callback. DialogTurnResult dialogTurnResult = null; BotCallbackHandler callback = async(turnContext, cancellationToken) => { var dialogContext = await dialogs.CreateContextAsync(turnContext); dialogContext.Stack.Insert( 0, new DialogInstance { Id = "OAuthPrompt", State = new Dictionary <string, object> { { "expires", DateTime.UtcNow.AddHours(8) }, { "caller", null }, { "state", new Dictionary <string, object> { { "AttemptCount", 0 } } }, { "options", new PromptOptions() } } }); dialogTurnResult = await dialogContext.ContinueDialogAsync(); }; // The Activity for the turn. var tokenExchangeInvokeRequest = new JObject { { "id", tokenExchangeInvokeRequestId }, { "connectionName", connectionName }, { "token", tokenExchangeRequestToken }, }; var activity = new Activity { Type = ActivityTypes.Invoke, Name = SignInConstants.TokenExchangeOperationName, From = new ChannelAccount { Id = userId }, Conversation = new ConversationAccount { Id = "conversation-id" }, ChannelId = channelId, Value = tokenExchangeInvokeRequest, }; // Act var invokeResponse = await adapter.ProcessAsync(string.Empty, activity, callback); // Assert Assert.Equal(DialogTurnStatus.Complete, dialogTurnResult.Status); Assert.IsType <TokenResponse>(dialogTurnResult.Result); Assert.Equal("TOKEN", ((TokenResponse)dialogTurnResult.Result).Token); Assert.Equal(200, invokeResponse.Status); var tokenExchangeInvokeResponse = (TokenExchangeInvokeResponse)invokeResponse.Body; Assert.Equal(tokenExchangeInvokeRequestId, tokenExchangeInvokeResponse.Id); Assert.Equal(connectionName, tokenExchangeInvokeResponse.ConnectionName); }
public async Task ShouldAcceptAndRecognizeCustomLocaleDict() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(convoState)); // Create new DialogSet. var dialogs = new DialogSet(dialogState); var culture = new PromptCultureModel() { InlineOr = " customOr ", InlineOrMore = " customOrMore ", Locale = "custom-custom", Separator = "customSeparator", NoInLanguage = "customNo", YesInLanguage = "customYes", }; var customDict = new Dictionary <string, ChoiceFactoryOptions>() { { culture.Locale, new ChoiceFactoryOptions(culture.Separator, culture.InlineOr, culture.InlineOrMore, true) }, }; dialogs.Add(new ChoicePrompt("ChoicePrompt", customDict, null, culture.Locale)); var helloLocale = MessageFactory.Text("hello"); helloLocale.Locale = culture.Locale; await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.PromptAsync( "ChoicePrompt", new PromptOptions { Prompt = new Activity { Type = ActivityTypes.Message, Text = "favorite color?", Locale = culture.Locale }, Choices = _colorChoices, }, cancellationToken); } }) .Send(helloLocale) .AssertReply((activity) => { // Use ChoiceFactory to build the expected answer, manually var expectedChoices = ChoiceFactory.Inline(_colorChoices, null, null, new ChoiceFactoryOptions() { InlineOr = culture.InlineOr, InlineOrMore = culture.InlineOrMore, InlineSeparator = culture.Separator, }).Text; Assert.AreEqual($"favorite color?{expectedChoices}", activity.AsMessageActivity().Text); }) .StartTestAsync(); }
public async Task TextPromptValidatorWithMessageShouldNotSendRetryPrompt() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); var dialogs = new DialogSet(dialogState); PromptValidator <string> validator = async(promptContext, cancellationToken) => { var value = promptContext.Recognized.Value; if (value.Length <= 3) { await promptContext.Context.SendActivityAsync(MessageFactory.Text("The text should be greater than 3 chars."), cancellationToken); return(false); } else { return(true); } }; var textPrompt = new TextPrompt("TextPrompt", validator); dialogs.Add(textPrompt); await new TestFlow(adapter, async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { var options = new PromptOptions { Prompt = new Activity { Type = ActivityTypes.Message, Text = "Enter some text." }, RetryPrompt = new Activity { Type = ActivityTypes.Message, Text = "Make sure the text is greater than three characters." }, }; await dc.PromptAsync("TextPrompt", options); } else if (results.Status == DialogTurnStatus.Complete) { var textResult = (string)results.Result; await turnContext.SendActivityAsync(MessageFactory.Text($"Bot received the text '{textResult}'."), cancellationToken); } }) .Send("hello") .AssertReply("Enter some text.") .Send("hi") .AssertReply("The text should be greater than 3 chars.") .Send("hello") .AssertReply("Bot received the text 'hello'.") .StartTestAsync(); }
/// <summary> /// Initializes a new instance of the class. /// </summary> /// <param name="conversationState">The managed conversation state.</param> /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/> public EchoBot1Bot(ConversationState conversationState, ILoggerFactory loggerFactory, ConversationStateAccessors conversationStateAccessors, BotUserStateAccessors statePropertyAccessor, DialogSet dialogSet) { _botUserStateAccessors = statePropertyAccessor ?? throw new System.ArgumentNullException("state accessor can't be null"); _accessors = conversationStateAccessors; if (conversationState == null) { throw new System.ArgumentNullException(nameof(conversationState)); } _conversationState = conversationState; if (loggerFactory == null) { throw new System.ArgumentNullException(nameof(loggerFactory)); } _logger = loggerFactory.CreateLogger <EchoBot1Bot>(); _logger.LogTrace("Turn start."); if (dialogSet == null) { throw new System.ArgumentException(nameof(dialogSet)); } _dialogSet = dialogSet; }
public PartyRegistrationBot() { dialogs = PartyRegistrationForm.Build(); }
public CardsCommand(string dialogId = DefaultName, DialogSet dialogs = null) : base(dialogId, dialogs) { Dialogs.Add(dialogId, new WaterfallStep[] { async(dc, args, next) => { var message = dc.Context.Activity.Text; if (!string.IsNullOrEmpty(message)) { await next.Invoke(); return; } await dc.Prompt("cardPrompt", "Выберите тип нужной карточки", GenerateOptions()); }, async(dc, args, next) => { var selectedCard = (args as Microsoft.Bot.Builder.Prompts.ChoiceResult)?.Value.Value; var message = dc.Context.Activity.Text; if (selectedCard == null && !string.IsNullOrEmpty(message)) { var foundResult = GenerateOptions().Choices.FirstOrDefault(x => x.Synonyms.Contains(message.ToLower())); if (foundResult != null) { selectedCard = foundResult.Value; } } var activity = dc.Context.Activity; switch (selectedCard) { case "Adaptive card": await dc.Context.SendActivity(CreateResponse(activity, CreateAdaptiveCardAttachment())); break; case "Animation card": await dc.Context.SendActivity(CreateResponse(activity, CreateAnimationCardAttachment())); break; case "Audio card": await dc.Context.SendActivity(CreateResponse(activity, CreateAudioCardAttachment())); break; case "Hero card": await dc.Context.SendActivity(CreateResponse(activity, CreateHeroCardAttachment())); break; case "Receipt card": await dc.Context.SendActivity(CreateResponse(activity, CreateReceiptCardAttachment())); break; case "Signin card": await dc.Context.SendActivity(CreateResponse(activity, CreateSignInCardAttachment())); break; case "Thumbnail card": await dc.Context.SendActivity(CreateResponse(activity, CreateThumbnailCardAttachment())); break; case "Video card": await dc.Context.SendActivity(CreateResponse(activity, CreateVideoCardAttacment())); break; } await dc.End(); } }); var cardPrompt = new ChoicePrompt(Culture.English) { Style = Microsoft.Bot.Builder.Prompts.ListStyle.List }; Dialogs.Add("cardPrompt", cardPrompt); }
public async Task OAuthPromptWithTokenExchangeWrongConnectionNameFail() { var convoState = new ConversationState(new MemoryStorage()); var dialogState = convoState.CreateProperty <DialogState>("dialogState"); var adapter = new TestAdapter() .Use(new AutoSaveStateMiddleware(convoState)); var connectionName = "myConnection"; var exchangeToken = "exch123"; // Create new DialogSet. var dialogs = new DialogSet(dialogState); dialogs.Add(new OAuthPrompt("OAuthPrompt", new OAuthPromptSettings() { Text = "Please sign in", ConnectionName = connectionName, Title = "Sign in" })); BotCallbackHandler botCallbackHandler = async(turnContext, cancellationToken) => { var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dc.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dc.PromptAsync("OAuthPrompt", new PromptOptions(), cancellationToken : cancellationToken); } else if (results.Status == DialogTurnStatus.Complete) { if (results.Result is TokenResponse) { await turnContext.SendActivityAsync(MessageFactory.Text("Logged in."), cancellationToken); } else { await turnContext.SendActivityAsync(MessageFactory.Text("Failed."), cancellationToken); } } }; await new TestFlow(adapter, botCallbackHandler) .Send("hello") .AssertReply(activity => { Assert.Single(((Activity)activity).Attachments); Assert.Equal(OAuthCard.ContentType, ((Activity)activity).Attachments[0].ContentType); Assert.Equal(InputHints.AcceptingInput, ((Activity)activity).InputHint); // No exchangable token is added to the adapter }) .Send(new Activity() { Type = ActivityTypes.Invoke, Name = SignInConstants.TokenExchangeOperationName, Value = JObject.FromObject(new TokenExchangeInvokeRequest() { ConnectionName = "beepboop", Token = exchangeToken }) }) .AssertReply(a => { Assert.Equal("invokeResponse", a.Type); var response = ((Activity)a).Value as InvokeResponse; Assert.NotNull(response); Assert.Equal(400, response.Status); var body = response.Body as TokenExchangeInvokeResponse; Assert.Equal(connectionName, body.ConnectionName); Assert.NotNull(body.FailureDetail); }) .StartTestAsync(); }
public void sassy(DialogSet dialogs) { // Define our dialog dialogs.Add("sassyText", new WaterfallStep[] { async(dcS, args, next) => { // Prompt for the guest's name. await dcS.Context.SendActivity("Hello you ;-)"); try { await dcS.Prompt("textPrompt", "What's your name?"); } catch { await dcS.Context.SendActivity("Sorry, didn't get that textPrompt."); } }, async(dcS, args, next) => { await dcS.Context.SendActivity("I'm in the next activity now. about to record the nameResult." + ""); nameResult = (string)args["Text"]; await dcS.Context.SendActivity($"{nameResult}... I like that name!"); // Ask for next info await dcS.Prompt("partyPrompt", $"Do you like to party {nameResult}?"); }, async(dcS, args, next) => { partyResult = (string)args["Text"]; if (partyResult.ToLowerInvariant().Contains("no")) { await dcS.Prompt("rejectionPrompt", "Awe, Why not?"); } else { await dcS.Context.SendActivity("See ya soon!"); await dcS.End(); } }, async(dcS, args, next) => { reasonGiven = (string)args["Text"]; string msg = $"{reasonGiven}?..... Well... Hope you have a nice day {nameResult}"; //var convo = ConversationState<PhoebeState>.Get(dc.Context); //// In production, you may want to store something more helpful //convo[$"{dc.ActiveDialog.State["name"]} reservation"] = msg; await dcS.Context.SendActivity(msg); await dcS.End(); } }); // Add a prompt for the reservation date dialogs.Add("textPrompt", new Microsoft.Bot.Builder.Dialogs.TextPrompt()); // Add a prompt for the party size dialogs.Add("partyPrompt", new Microsoft.Bot.Builder.Dialogs.TextPrompt()); // Add a prompt for the user's name dialogs.Add("rejectionPrompt", new Microsoft.Bot.Builder.Dialogs.TextPrompt()); }
public MyBot(MyBotAccessors myBotAccessors, ILoggerFactory loggerFactory) { MyBotAccessors = myBotAccessors ?? throw new ArgumentNullException(nameof(myBotAccessors)); Logger = loggerFactory?.CreateLogger <MyBot>() ?? throw new ArgumentNullException(nameof(loggerFactory)); Dialogs = new DialogSet(MyBotAccessors.ConversationDialogState); // WaterfallDialog を登録。引数に Task<DialogTurnResult> Xxx(WaterfallStepContext, CancellationToken) の配列を渡す。 // 今回は一か所にまとめるためにラムダで書いたけど、普通は何らかのクラスのメソッドを渡すのがいいと思う。 Dialogs.Add(new WaterfallDialog("details", new WaterfallStep[] { (stepContext, cancellationToken) => stepContext.PromptAsync("name", new PromptOptions { Prompt = MessageFactory.Text("名前は?") }, cancellationToken), async(stepContext, cancellationToken) => { var userProfile = await MyBotAccessors.UserProfile.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken); userProfile.Name = (string)stepContext.Result; await stepContext.Context.SendActivityAsync($"ありがと!{userProfile.Name}!!", cancellationToken: cancellationToken); return(await stepContext.PromptAsync("confirm", new PromptOptions { Prompt = MessageFactory.Text("年齢教えてくれる?") }, cancellationToken)); }, async(stepContext, cancellationToken) => { if ((bool)stepContext.Result) { return(await stepContext.PromptAsync("age", new PromptOptions { Prompt = MessageFactory.Text("ありがとう!年齢入れて!") }, cancellationToken)); } else { // 年齢は -1 ということにして次のへ return(await stepContext.NextAsync(-1, cancellationToken)); } }, async(stepContext, cancellationToken) => { var userProfile = await MyBotAccessors.UserProfile.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken); userProfile.Age = (int)stepContext.Result; if (userProfile.Age == -1) { // 年齢キャンセルされた await stepContext.Context.SendActivityAsync($"ミステリアスなんだね!!", cancellationToken: cancellationToken); } else { // 年齢入れてもらった await stepContext.Context.SendActivityAsync($"{userProfile.Age} 歳なんだね!!", cancellationToken: cancellationToken); } return(await stepContext.PromptAsync("confirm", new PromptOptions { Prompt = MessageFactory.Text("あってる?") }, cancellationToken)); }, async(stepContext, cancellationToken) => { if ((bool)stepContext.Result) { var userProfile = await MyBotAccessors.UserProfile.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken); if (userProfile.Age == -1) { await stepContext.Context.SendActivityAsync($"ミステリアスな {userProfile.Name} さんだね!", cancellationToken: cancellationToken); } else { await stepContext.Context.SendActivityAsync($"{userProfile.Age} 歳の {userProfile.Name} さんだね!", cancellationToken: cancellationToken); } } else { await stepContext.Context.SendActivityAsync($"じゃぁ、君のことは覚えないで忘れておくね!", cancellationToken: cancellationToken); await MyBotAccessors.UserProfile.DeleteAsync(stepContext.Context, cancellationToken); } return(await stepContext.EndDialogAsync(cancellationToken: cancellationToken)); } })); // WaterfallDialog の中で PromptAsync で呼び出してるダイアログも追加する。 Dialogs.Add(new TextPrompt("name")); Dialogs.Add(new NumberPrompt <int>("age")); Dialogs.Add(new ConfirmPrompt("confirm")); }