Created
May 23, 2018 14:25
-
-
Save vwart/faddaee279aab5127707862ec4994574 to your computer and use it in GitHub Desktop.
Optional ChoicePrompts with Bot Framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Library, IPromptChoiceResult, Prompts, ListStyle, IDialogResult, IntentRecognizer, IRecognizeContext, IIntentRecognizerResult} from "botbuilder"; | |
// how to use the extended prompt: | |
const lib = new Library("ending"); | |
lib | |
.dialog("example", [ | |
(session, args) => { | |
session.sendTyping(); | |
const choiceOpt: CustomChoiceOptions = { | |
listStyle: ListStyle.button, | |
optional: true // <- this line makes the difference. Per default Choice Prompts will be unchanged | |
} | |
Prompts.choice(this, prompt, options, choiceOpt); | |
}, | |
async (session, result: IPromptChoiceResult) => { | |
switch (result.response!.index) { | |
case 0: { | |
session.sendTyping(); | |
session.endDialog("Ok, bye"); | |
break; | |
} | |
case 1: { | |
session.sendTyping(); | |
session.beginDialog("askForContact"); | |
break; | |
} | |
case -1: // <-- this is the new case. User did ignore the choices and entered some text | |
default: { | |
const userInput = result.response.entity; | |
// do something with the userInput | |
break; | |
} | |
} | |
} | |
]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Library, Session, IPromptChoiceResult } from "botbuilder"; | |
const lib = new Library("global"); | |
// whenever a choice prompt cannot match the user's input to a choice, it will trigger this "dialog". | |
// The dialog will then do nothing, but sending fake PromptchoiceResult to the next waterfall step. | |
// The following step can identify the scenario due to the index being -1. The user input is passed as "entity" | |
lib.dialog("optional-choice-dispatcher", (session: Session, args: any) => { | |
}).triggerAction({ | |
matches: "optional-choice-dispatcher", | |
onSelectAction: (session, args, next) => { | |
if (args && args.intent && args.intent.entities && args.intent.entities.length > 0 | |
&& args.intent.entities[0] && args.intent.entities[0].entity) { | |
const choiceResult: IPromptChoiceResult = { | |
response: { | |
entity: args.intent.entities[0].entity, | |
index: -1, | |
score: 1 | |
} | |
} | |
session.endDialogWithResult(choiceResult); | |
} else { | |
session.endDialog(); | |
} | |
} | |
}); | |
export default lib; | |
export class OptionalPromptRecognizer extends IntentRecognizer { | |
onRecognize(context: IRecognizeContext, callback: (err: Error, result: IIntentRecognizerResult) => void): void { | |
// this recognizer does nothing, until it sees a dialogData with "optional" flag | |
if (context.dialogData && context.dialogData.options && context.dialogData.options.optional) { | |
const dialogStack = context.dialogStack(); | |
// be sure to only intervene when a Choice Prompt is at the top of the stack | |
if (dialogStack && dialogStack.length > 0 && dialogStack[dialogStack.length - 1].id === "BotBuilder:prompt-choice") { | |
callback(null, { | |
intent: "optional-choice-dispatcher", // the intent that will proceed waterfall | |
score: 0.1337, // a low score, so that other recognizers may overried. E.g. LUISRecognizer. But larger than 0.1 is important | |
entities: [{ type: "string", entity: context.message.text}] | |
}); | |
return; | |
} | |
} | |
callback(null, { intent: "", score: 0 }); // no intent identified | |
} | |
} | |
export interface CustomChoiceOptions extends IPromptChoiceOptions { | |
optional: boolean | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import global from "./dialogs/global"; | |
//[...] | |
const bot = new UniversalBot(connector, defaultDialog); | |
// register dispatcher dialog | |
bot.library(global.clone()); | |
// enable Choice Prompts to be optional | |
bot.recognizer(new OptionalPromptRecognizer()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment