/
dateResolverDialog.ts
68 lines (56 loc) · 3.27 KB
/
dateResolverDialog.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { TimexProperty } from '@microsoft/recognizers-text-data-types-timex-expression';
import { InputHints, MessageFactory } from 'botbuilder';
import { DateTimePrompt, DateTimeResolution, DialogTurnResult, PromptValidatorContext, WaterfallDialog, WaterfallStepContext } from 'botbuilder-dialogs';
import { CancelAndHelpDialog } from './cancelAndHelpDialog';
const DATETIME_PROMPT = 'datetimePrompt';
const WATERFALL_DIALOG = 'waterfallDialog';
export class DateResolverDialog extends CancelAndHelpDialog {
private static async dateTimePromptValidator(promptContext: PromptValidatorContext<DateTimeResolution>): Promise<boolean> {
if (promptContext.recognized.succeeded) {
// This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
// TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year.
const timex = promptContext.recognized.value[0].timex.split('T')[0];
// If this is a definite Date including year, month and day we are good otherwise reprompt.
// A better solution might be to let the user know what part is actually missing.
return new TimexProperty(timex).types.has('definite');
}
return false;
}
constructor(id: string) {
super(id || 'dateResolverDialog');
this.addDialog(new DateTimePrompt(DATETIME_PROMPT, DateResolverDialog.dateTimePromptValidator.bind(this)))
.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [
this.initialStep.bind(this),
this.finalStep.bind(this)
]));
this.initialDialogId = WATERFALL_DIALOG;
}
private async initialStep(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {
const timex = (stepContext.options as any).date;
const promptMessageText = 'On what date would you like to travel?';
const promptMessage = MessageFactory.text(promptMessageText, promptMessageText, InputHints.ExpectingInput);
const repromptMessageText = 'I\'m sorry, for best results, please enter your travel date including the month, day and year.';
const repromptMessage = MessageFactory.text(repromptMessageText, repromptMessageText, InputHints.ExpectingInput);
if (!timex) {
// We were not given any date at all so prompt the user.
return await stepContext.prompt(DATETIME_PROMPT,
{
prompt: promptMessage,
retryPrompt: repromptMessage
});
}
// We have a Date we just need to check it is unambiguous.
const timexProperty = new TimexProperty(timex);
if (!timexProperty.types.has('definite')) {
// This is essentially a "reprompt" of the data we were given up front.
return await stepContext.prompt(DATETIME_PROMPT, { prompt: repromptMessage });
}
return await stepContext.next([{ timex }]);
}
private async finalStep(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {
const timex = stepContext.result[0].timex;
return await stepContext.endDialog(timex);
}
}