Search code examples
c#botframework

WaterfallDialog, fire the first step without the user sending any message. C#


I want the first step of the WaterfallDialog to prompt when the class is called. Right now to only do this is to use the OnMembersAddedAsync method which sends like a welcome message. Which is not I needed.

I want the StartConversation to automatically fire when the class is called.

   public class HomeOfficeDialogV3 : ComponentDialog
    {
        private readonly StateAccessor _StateAccessor;
        private readonly DirectlineApi _TokenReq;
        private readonly IndicatorDelay _IndicatorDelay;
        private UserDataExtractedDto _UserDataExtractedDto;

        public HomeOfficeDialogV3(StateAccessor userState)
        {
            _StateAccessor = userState;
            _TokenReq = new DirectlineApi();
            _IndicatorDelay = new IndicatorDelay();
            var waterfallSteps = new WaterfallStep[]
            {
                StartConversation,

            };
            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
            AddDialog(new TextPrompt(nameof(TextPrompt)));
            AddDialog(new ChoicePrompt(nameof(ChoicePrompt)) { Style = ListStyle.SuggestedAction });
            AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
            AddDialog(new NumberPrompt<int>(nameof(NumberPrompt<int>)));
            
            InitialDialogId = nameof(WaterfallDialog);
        }

        public HomeOfficeDialogV3(UserDataExtractedDto userDataExtractedDto)
        {
            _UserDataExtractedDto = userDataExtractedDto;
        }

        public async Task<DialogTurnResult> StartConversation(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            await _IndicatorDelay.ShowTypingIndicator(stepContext.Context, 1400);
            return await stepContext.PromptAsync(nameof(ChoicePrompt),
               new PromptOptions { 
                   Prompt = MessageFactory.Text($"Did you know your office space can affect your well-being?"), 
                   Choices = ChoiceFactory.ToChoices(new List<string> { "Hello Buddy 😊" })
               }
           );
        }
  }

        public MainDialog(IConfiguration configuration, StateAccessor userState)
        {
            _StateAccessor = userState;
            _TokenReq = new DirectlineApi();
            _DialogsTurn = new DialogsTurn();
private DialogCurrentDayId _DialogCurrentDayId;

            var waterfallSteps = new WaterfallStep[]
            {
                DialogsTurn
            };

            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
            AddDialog(new WelcomeDiloagV1(userState));
            AddDialog(new ExerciseDialogV2(userState));
            AddDialog(new HomeOfficeDialogV3(userState));

            InitialDialogId = nameof(WaterfallDialog);
        }
        public MainDialog(DialogCurrentDayId dialogCurrentDayId)
        {
            _DialogCurrentDayId = dialogCurrentDayId;
        }
        private async Task<DialogTurnResult> DialogsTurn(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var dialogTurnID = Convert.ToInt32(UserDataExtractedDto.DialogTurnID);
            var dialogEnum = Enum.GetValues(typeof(DialogEnumerator)).Cast<DialogEnumerator>();
            var currentDialog = String.Empty;

            foreach(DialogEnumerator dialog in dialogEnum)
            {
                if (dialogTurnID > (int)dialog)
                {
                    dialogTurnID = dialogEnum.Count();
                }
                if ((int)dialog == dialogTurnID)
                {   
                    currentDialog = dialog.ToString();
                }

            }
            return await stepContext.BeginDialogAsync(currentDialog, null, cancellationToken);
        }
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<MainDialog>();
        services.AddTransient<IBot, MainBot<MainDialog>>();
    }
        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in turnContext.Activity.MembersAdded)
            {
                if (member.Id != turnContext.Activity.Recipient.Id)
                {                                       
                    var token = turnContext.Activity.From.Name;
                    
                    if (!String.IsNullOrEmpty(token))
                    {
                        var ConversationExistingId = await _StateAccessor.existingConversation.GetAsync(turnContext, () => new ExistingConversation(), cancellationToken);
                        
                        if (_IsTest)
                        {
                            _UserDataFromReactWebChat.Token = _TokenTest;
                            _UserDataFromReactWebChat.UserId = _IdTest;
                        }
                        else
                        {
                            _UserDataFromReactWebChat.Token = turnContext.Activity.From.Name;
                            _UserDataFromReactWebChat.UserId = Int32.Parse(turnContext.Activity.From.Id);                           
                        }

                        
                        var getDialogID = new DialogsTurn(_UserDataFromReactWebChat);
                        var initializeDialogsById = await getDialogID.GetNextDialog();
                        
                        if (initializeDialogsById != null){
                            new MainDialog(initializeDialogsById);
                        }
                        await _IndicatorDelay.ShowTypingIndicator(turnContext, 5500);

                        var isGranted = String.Empty;
                        var userAllData = new UsersAllData(_UserDataFromReactWebChat);
                        var usersInfoFromWebApp = await userAllData.GetUsersInfoFromWebApp();
                        foreach (var i in usersInfoFromWebApp)
                        {
                            
                            if(!String.IsNullOrEmpty(i.IsGranted))
                            {
                                isGranted = i.IsGranted.ToString();
                            }
                            new WelcomeDiloagV1(i);
                            new ExerciseDialogV2(i);
                            new HomeOfficeDialogV3(i);
                            //break;
                        }
                        if (isGranted == "true")
                        {
                            if (string.IsNullOrEmpty(ConversationExistingId.ConverstationId))
                            {
                                ConversationExistingId.ConverstationId = turnContext.Activity.Conversation.Id;
                                await _StateAccessor.existingConversation.SetAsync(turnContext, ConversationExistingId, cancellationToken);
                                await _StateAccessor.existingConversationState.SaveChangesAsync(turnContext);
                            }
                            else
                            {
                                var Conversation_id = ConversationExistingId.ConverstationId;
                                var TokenGenerated = _UserDataFromReactWebChat.Token;
                            }
                        }
                        else if (isGranted == "false")
                        {
                            await turnContext.SendActivityAsync(MessageFactory.Text("Unathorized requests."), cancellationToken);
                        }
                    }
                    else
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text($"Oops! Something went wrong."), cancellationToken);
                    }
                }
            }
        }

I have multiple steps but I cut it out for this example.


Solution

  • If your bot is based on the document that you linked to then it will access the dialog stack from OnMessageActivityAsync using Dialog.RunAsync. You can do the same thing in OnMembersAddedAsync.