Change flow of messages in Microsoft Bot Framework

Solution 1:

This is a great question.The key thing is to use the SetActive and SetNext methods of the Field<T> class. You should consider using the FieldReflector class; though you can implement your own IField.

SetActive is described in the Dynamic Fields section of the FormFlow documentation. Basically it provides a delegate that enables the field based on a condition.

SetNext will allow you to decide what step of the form should come next based on your custom logic.

You can take a look to the ContosoFlowers sample. In the Order form; something similar is being done.

 public static IForm<Order> BuildOrderForm()
        {
            return new FormBuilder<Order>()
                .Field(nameof(RecipientFirstName))
                .Field(nameof(RecipientLastName))
                .Field(nameof(RecipientPhoneNumber))
                .Field(nameof(Note))
                .Field(new FieldReflector<Order>(nameof(UseSavedSenderInfo))
                    .SetActive(state => state.AskToUseSavedSenderInfo)
                    .SetNext((value, state) =>
                    {
                        var selection = (UseSaveInfoResponse)value;

                        if (selection == UseSaveInfoResponse.Edit)
                        {
                            state.SenderEmail = null;
                            state.SenderPhoneNumber = null;
                            return new NextStep(new[] { nameof(SenderEmail) });
                        }
                        else
                        {
                            return new NextStep();
                        }
                    }))
                .Field(new FieldReflector<Order>(nameof(SenderEmail))
                    .SetActive(state => !state.UseSavedSenderInfo.HasValue || state.UseSavedSenderInfo.Value == UseSaveInfoResponse.Edit)
                    .SetNext(
                        (value, state) => (state.UseSavedSenderInfo == UseSaveInfoResponse.Edit)
                        ? new NextStep(new[] { nameof(SenderPhoneNumber) })
                        : new NextStep()))
                .Field(nameof(SenderPhoneNumber), state => !state.UseSavedSenderInfo.HasValue || state.UseSavedSenderInfo.Value == UseSaveInfoResponse.Edit)
                .Field(nameof(SaveSenderInfo), state => !state.UseSavedSenderInfo.HasValue || state.UseSavedSenderInfo.Value == UseSaveInfoResponse.Edit)
                .Build();
        }
    }
}