Working on a Skill, I needed to block the execution of a WaterfallDialog while waiting for a specific event to arrive.
The solution is simple and based on the use of EventPrompt. Below I show how to use it.
Register EventPrompt in the constructor
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
HelloAsync,
WaitForEventAsync,
DoneAsync
}));
AddDialog(new EventPrompt(nameof(EventPrompt), "SampleEvent", Validate));
InitialDialogId = nameof(WaterfallDialog);
Implement the three dialog steps
private async Task<DialogTurnResult> HelloAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Hello :)"), cancellationToken);
return await stepContext.NextAsync(cancellationToken);
}
private async Task<DialogTurnResult> WaitForEventAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.PromptAsync(nameof(EventPrompt), new PromptOptions { Prompt = MessageFactory.Text("Waiting for the event") });
}
private async Task<DialogTurnResult> DoneAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("After I receive the event."), cancellationToken);
return await stepContext.NextAsync(cancellationToken);
}
Implement the event validator
async Task<bool> Validate(PromptValidatorContext<Activity> promptContext, CancellationToken cancellationToken)
{
var activity = promptContext.Recognized.Value;
if (activity.Type == ActivityTypes.Event)
{
try
{
string eventValue = (string)activity.Value;
if(eventValue == "OK")
{
return true;
}
}
catch { }
}
return false;
}