Sequential Waterfall Models with Complex Dialog flows Bot Framework C# v4












2














I have 3 Independent waterfall models which are triggered by intents using Luis.
I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.



The 3 Waterfall Methods are as follows,




  • WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names

  • WaterFall_2 - Will perform some REST action, taking the names from waterFall_1

  • WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1


As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are




  1. How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.


  2. In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?



The figure might give more context Simple figure










share|improve this question





























    2














    I have 3 Independent waterfall models which are triggered by intents using Luis.
    I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.



    The 3 Waterfall Methods are as follows,




    • WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names

    • WaterFall_2 - Will perform some REST action, taking the names from waterFall_1

    • WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1


    As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are




    1. How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.


    2. In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?



    The figure might give more context Simple figure










    share|improve this question



























      2












      2








      2


      1





      I have 3 Independent waterfall models which are triggered by intents using Luis.
      I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.



      The 3 Waterfall Methods are as follows,




      • WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names

      • WaterFall_2 - Will perform some REST action, taking the names from waterFall_1

      • WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1


      As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are




      1. How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.


      2. In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?



      The figure might give more context Simple figure










      share|improve this question















      I have 3 Independent waterfall models which are triggered by intents using Luis.
      I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.



      The 3 Waterfall Methods are as follows,




      • WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names

      • WaterFall_2 - Will perform some REST action, taking the names from waterFall_1

      • WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1


      As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are




      1. How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.


      2. In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?



      The figure might give more context Simple figure







      c# botframework






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 18 '18 at 14:27







      Aditya Rao

















      asked Nov 18 '18 at 14:21









      Aditya RaoAditya Rao

      185




      185
























          1 Answer
          1






          active

          oldest

          votes


















          1














          You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).



          If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.



          You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.



          I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)



          AlteredStateBot



          Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:



          public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
          : base(nameof(TestDialog))
          {
          TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
          GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));

          // Add control flow dialogs
          var waterfallSteps = new WaterfallStep
          {
          InitializeStateStepAsync,
          PromptForAnimalStepAsync,
          // PromptForCityStepAsync,
          DisplayTestStateStepAsync,
          };
          AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));

          // AddDialog(new TextPrompt(NamePrompt, ValidateName));
          AddDialog(new TextPrompt(AnimalPrompt));
          }


          With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:



           private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
          {
          var context = stepContext.Context;
          var testState = await TestStateAccessor.GetAsync(context);
          var greetingState = await GreetingStateAccessor.GetAsync(context);

          // Display their profile information and end dialog.
          await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
          return await stepContext.EndDialogAsync();
          }


          Hope this helps!






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361886%2fsequential-waterfall-models-with-complex-dialog-flows-bot-framework-c-sharp-v4%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).



            If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.



            You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.



            I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)



            AlteredStateBot



            Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:



            public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
            : base(nameof(TestDialog))
            {
            TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
            GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));

            // Add control flow dialogs
            var waterfallSteps = new WaterfallStep
            {
            InitializeStateStepAsync,
            PromptForAnimalStepAsync,
            // PromptForCityStepAsync,
            DisplayTestStateStepAsync,
            };
            AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));

            // AddDialog(new TextPrompt(NamePrompt, ValidateName));
            AddDialog(new TextPrompt(AnimalPrompt));
            }


            With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:



             private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
            {
            var context = stepContext.Context;
            var testState = await TestStateAccessor.GetAsync(context);
            var greetingState = await GreetingStateAccessor.GetAsync(context);

            // Display their profile information and end dialog.
            await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
            return await stepContext.EndDialogAsync();
            }


            Hope this helps!






            share|improve this answer


























              1














              You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).



              If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.



              You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.



              I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)



              AlteredStateBot



              Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:



              public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
              : base(nameof(TestDialog))
              {
              TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
              GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));

              // Add control flow dialogs
              var waterfallSteps = new WaterfallStep
              {
              InitializeStateStepAsync,
              PromptForAnimalStepAsync,
              // PromptForCityStepAsync,
              DisplayTestStateStepAsync,
              };
              AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));

              // AddDialog(new TextPrompt(NamePrompt, ValidateName));
              AddDialog(new TextPrompt(AnimalPrompt));
              }


              With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:



               private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
              {
              var context = stepContext.Context;
              var testState = await TestStateAccessor.GetAsync(context);
              var greetingState = await GreetingStateAccessor.GetAsync(context);

              // Display their profile information and end dialog.
              await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
              return await stepContext.EndDialogAsync();
              }


              Hope this helps!






              share|improve this answer
























                1












                1








                1






                You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).



                If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.



                You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.



                I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)



                AlteredStateBot



                Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:



                public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
                : base(nameof(TestDialog))
                {
                TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
                GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));

                // Add control flow dialogs
                var waterfallSteps = new WaterfallStep
                {
                InitializeStateStepAsync,
                PromptForAnimalStepAsync,
                // PromptForCityStepAsync,
                DisplayTestStateStepAsync,
                };
                AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));

                // AddDialog(new TextPrompt(NamePrompt, ValidateName));
                AddDialog(new TextPrompt(AnimalPrompt));
                }


                With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:



                 private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
                {
                var context = stepContext.Context;
                var testState = await TestStateAccessor.GetAsync(context);
                var greetingState = await GreetingStateAccessor.GetAsync(context);

                // Display their profile information and end dialog.
                await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
                return await stepContext.EndDialogAsync();
                }


                Hope this helps!






                share|improve this answer












                You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).



                If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.



                You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.



                I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)



                AlteredStateBot



                Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:



                public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
                : base(nameof(TestDialog))
                {
                TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
                GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));

                // Add control flow dialogs
                var waterfallSteps = new WaterfallStep
                {
                InitializeStateStepAsync,
                PromptForAnimalStepAsync,
                // PromptForCityStepAsync,
                DisplayTestStateStepAsync,
                };
                AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));

                // AddDialog(new TextPrompt(NamePrompt, ValidateName));
                AddDialog(new TextPrompt(AnimalPrompt));
                }


                With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:



                 private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
                {
                var context = stepContext.Context;
                var testState = await TestStateAccessor.GetAsync(context);
                var greetingState = await GreetingStateAccessor.GetAsync(context);

                // Display their profile information and end dialog.
                await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
                return await stepContext.EndDialogAsync();
                }


                Hope this helps!







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 28 '18 at 22:40









                JJ_WailesJJ_Wailes

                635112




                635112






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361886%2fsequential-waterfall-models-with-complex-dialog-flows-bot-framework-c-sharp-v4%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                    ComboBox Display Member on multiple fields

                    Is it possible to collect Nectar points via Trainline?