I would like to ask the user for confirmation before actually cancelling all dialogs. In the current sample code, the dialogs are cancelled as soon as the user types cancel or quit. Any suggestions how to do this?
async interrupt(innerDc) {
if (innerDc.context.activity.text) {
const text = innerDc.context.activity.text.toLowerCase();
switch (text) {
case 'help':
case '?': {
const helpMessageText = 'Show help here';
await innerDc.context.sendActivity(helpMessageText, helpMessageText, InputHints.ExpectingInput);
return { status: DialogTurnStatus.waiting };
}
case 'cancel':
case 'quit': {
const cancelMessageText = 'Cancelling...';
await innerDc.context.sendActivity(cancelMessageText, cancelMessageText, InputHints.IgnoringInput);
return await innerDc.cancelAllDialogs();
}
}
}
}
}
Looking at the Core Bot sample you can see that CancelAndHelpDialog
is a component dialog, which means it has its own dialog set that we can add dialogs to. In your case you'll want a confirm prompt and a waterfall dialog. You can use BookingDialog
as a guide for how to implement this because it extends CancelAndHelpDialog
and therefore extends ComponentDialog
.
You can see that BookingDialog
adds inner dialogs to its dialog set in its constructor:
constructor(id) { super(id || 'bookingDialog'); this.addDialog(new TextPrompt(TEXT_PROMPT)) .addDialog(new ConfirmPrompt(CONFIRM_PROMPT)) .addDialog(new DateResolverDialog(DATE_RESOLVER_DIALOG)) .addDialog(new WaterfallDialog(WATERFALL_DIALOG, [ this.destinationStep.bind(this), this.originStep.bind(this), this.travelDateStep.bind(this), this.confirmStep.bind(this), this.finalStep.bind(this) ])); this.initialDialogId = WATERFALL_DIALOG; }
If you want to add dialogs to the dialog set in the base class CancelAndHelpDialog
, you should define a constructor for that:
constructor(id) {
super(id);
this.addDialog(new ConfirmPrompt(CANCELLATION_CONFIRMATION))
.addDialog(new WaterfallDialog(CANCELLATION_WATERFALL, [
async stepContext => await stepContext.prompt(CANCELLATION_CONFIRMATION, 'Are you sure you want to cancel?'),
async stepContext => {
if (stepContext.result) {
const cancelMessageText = 'Cancelling...';
await stepContext.context.sendActivity(cancelMessageText, cancelMessageText, InputHints.IgnoringInput);
return await stepContext.cancelAllDialogs();
}
return stepContext.endDialog();
},
]));
}
Note that because CancelAndHelpDialog
is meant to be used as a base class, it will share its dialog set with any class that extends it. That means you need to make sure there aren't any dialog ID's that it has in common with the classes that extend it. For example, you can see that BookingDialog
already uses the ID's 'confirmPrompt'
and 'waterfallDialog'
:
const CONFIRM_PROMPT = 'confirmPrompt'; const DATE_RESOLVER_DIALOG = 'dateResolverDialog'; const TEXT_PROMPT = 'textPrompt'; const WATERFALL_DIALOG = 'waterfallDialog';
That means you can't use those strings as the ID's for the confirm prompt and waterfall dialog that you're creating in CancelAndHelpDialog
. Here are the strings I'm using instead:
const CANCELLATION_CONFIRMATION = 'cancellationConfirmation';
const CANCELLATION_WATERFALL = 'cancellationWaterfall';
Also note that I'm using anonymous arrow functions as the waterfall steps, but if you want to use named functions like BookingDialog
does then you'll need to come up with function names that don't conflict with the functions in the classes that extend CancelAndHelpDialog
, just like with the dialog ID's. So for example, because BookingDialog
contains a function called confirmStep
you shouldn't use that as the name of your function that calls the confirm prompt in CancelAndHelpDialog
.
You may notice that the second step in the waterfall dialog I've defined contains code that's almost identical to the second switch case in the interrupt
function:
const cancelMessageText = 'Cancelling...'; await innerDc.context.sendActivity(cancelMessageText, cancelMessageText, InputHints.IgnoringInput); return await innerDc.cancelAllDialogs();
You need to replace that code in the interrupt
function with code that calls your waterfall dialog:
return await innerDc.beginDialog(CANCELLATION_WATERFALL);