UNPKG

botbuilder-dialogs-adaptive

Version:

Rule system for the Microsoft BotBuilder dialog system.

139 lines (120 loc) 4.45 kB
/** * @module botbuilder-dialogs-adaptive */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import { BoolProperty, StringProperty, UnknownProperty } from '../properties'; import { BoolExpression, BoolExpressionConverter, StringExpression, StringExpressionConverter, ValueExpression, ValueExpressionConverter, } from 'adaptive-expressions'; import { Activity, ActivityEventNames, ActivityTypes, ConversationReference, QueueStorage, TurnContext, } from 'botbuilder'; import { Converter, ConverterFactory, Dialog, DialogConfiguration, DialogContext, DialogTurnResult, DialogTurnStateConstants, } from 'botbuilder-dialogs'; export interface ContinueConversationLaterConfiguration extends DialogConfiguration { disabled?: BoolProperty; date?: StringProperty; value?: UnknownProperty; } /** * Action which schedules the current conversation to be continued at a later time. */ export class ContinueConversationLater extends Dialog implements ContinueConversationLaterConfiguration { static $kind = 'Microsoft.ContinueConversationLater'; /** * Gets or sets an optional expression which if is true will disable this action. */ disabled?: BoolExpression; /** * Gets or sets the expression which resolves to the date/time to continue the conversation. */ date: StringExpression; /** * Gets or sets an optional value to use for EventActivity.Value. */ value: ValueExpression; /** * @param property The key of the conditional selector configuration. * @returns The converter for the selector configuration. */ getConverter(property: keyof ContinueConversationLaterConfiguration): Converter | ConverterFactory { switch (property) { case 'disabled': return new BoolExpressionConverter(); case 'date': return new StringExpressionConverter(); case 'value': return new ValueExpressionConverter(); default: return super.getConverter(property); } } /** * Called when the [Dialog](xref:botbuilder-dialogs.Dialog) is started and pushed onto the dialog stack. * * @param {DialogContext} dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation. * @param {object} _options Optional. Initial information to pass to the dialog. * @returns {Promise<DialogTurnResult>} A `Promise` representing the asynchronous operation. */ async beginDialog(dc: DialogContext, _options?: Record<string, unknown>): Promise<DialogTurnResult> { if (this.disabled && this.disabled.getValue(dc.state)) { return dc.endDialog(); } const dateString = this.date.getValue(dc.state); const date = Date.parse(dateString); if (!date || isNaN(date)) { throw new Error('Date is invalid'); } if (date <= Date.now()) { throw new Error('Date must be in the future'); } // create ContinuationActivity from the conversation reference. const reference = TurnContext.getConversationReference(dc.context.activity); const activity: Partial<Activity> = TurnContext.applyConversationReference( { type: ActivityTypes.Event, name: ActivityEventNames.ContinueConversation, relatesTo: reference as ConversationReference, }, reference, true, ); activity.value = this.value && this.value.getValue(dc.state); const visibility = (date - Date.now()) / 1000; const ttl = visibility + 2 * 60; const queueStorage: QueueStorage = dc.context.turnState.get(DialogTurnStateConstants.queueStorage); if (!queueStorage) { throw new Error('Unable to locate QueueStorage in HostContext'); } const receipt = await queueStorage.queueActivity(activity, visibility, ttl); // return the receipt as the result. return dc.endDialog(receipt); } /** * @protected * @returns {string} A `string` representing the compute Id. */ protected onComputeId(): string { return `ContinueConversationLater[${this.date && this.date.toString()}s]`; } }