UNPKG

voxa

Version:

A fsm (state machine) framework for Alexa, Dialogflow, Facebook Messenger and Botframework apps using Node.js

154 lines (130 loc) 4.43 kB
import { AudioCard as AudioCardType, HeroCard as HeroCardType, IAttachment, ISuggestedActions, SigninCard as SigninCardType, SuggestedActions as SuggestedActionsType, } from "botbuilder"; import * as _ from "lodash"; import { IDirective, IDirectiveClass } from "../../directives"; import { ITransition } from "../../StateMachine"; import { IVoxaEvent } from "../../VoxaEvent"; import { IVoxaReply } from "../../VoxaReply"; import { BotFrameworkReply } from "./BotFrameworkReply"; export interface ISignInCardOptions { url: string; cardText: string; buttonTitle: string; } export abstract class RenderDirective<T> { constructor(public options: T) {} protected renderOptions(event: IVoxaEvent): any { if (_.isString(this.options)) { return event.renderer.renderPath(this.options, event); } return this.options; } } export class SigninCard implements IDirective { public static platform: string = "botframework"; public static key: string = "botframeworkSigninCard"; constructor(public signInOptions: ISignInCardOptions) {} public async writeToReply( reply: IVoxaReply, event?: IVoxaEvent, transition?: ITransition, ) { const card = new SigninCardType(); card.button(this.signInOptions.buttonTitle, this.signInOptions.url); card.text(this.signInOptions.cardText); const attachments = (reply as BotFrameworkReply).attachments || []; attachments.push(card.toAttachment()); (reply as BotFrameworkReply).attachments = attachments; } } export class HeroCard extends RenderDirective<string | HeroCardType> implements IDirective { public static platform: string = "botframework"; public static key: string = "botframeworkHeroCard"; public async writeToReply( reply: IVoxaReply, event: IVoxaEvent, transition?: ITransition, ) { const card = await this.renderOptions(event); const attachments = (reply as BotFrameworkReply).attachments || []; attachments.push(card.toAttachment()); (reply as BotFrameworkReply).attachments = attachments; } } export class SuggestedActions extends RenderDirective<string | SuggestedActionsType> implements IDirective { public static key: string = "botframeworkSuggestedActions"; public static platform: string = "botframework"; public async writeToReply( reply: IVoxaReply, event: IVoxaEvent, transition?: ITransition, ) { const suggestedActionsType = await this.renderOptions(event); const suggestedActions: ISuggestedActions = suggestedActionsType.toSuggestedActions ? suggestedActionsType.toSuggestedActions() : suggestedActionsType; (reply as BotFrameworkReply).suggestedActions = suggestedActions; } } export class AudioCard extends RenderDirective<string | AudioCardType> implements IDirective { public static key: string = "botframeworkAudioCard"; public static platform: string = "botframework"; public async writeToReply( reply: IVoxaReply, event: IVoxaEvent, transition: ITransition, ) { const audioCard = await this.renderOptions(event); const attachment: IAttachment = audioCard.toAttachment ? audioCard.toAttachment() : audioCard; if (reply.hasMessages) { // we want to send stuff before the audio card (reply as BotFrameworkReply).inputHint = "ignoringInput"; await (reply as BotFrameworkReply).send(); reply.clear(); } // and now we add the card const attachments = (reply as BotFrameworkReply).attachments || []; attachments.push(attachment); (reply as BotFrameworkReply).attachments = attachments; reply.terminate(); transition.flow = "terminate"; return (reply as BotFrameworkReply).send(); } } function createMessageDirective<IOptions>( key: string, messageKey: string, ): IDirectiveClass { return class implements IDirective { public static key: string = key; public static platform: string = "botframework"; constructor(public options: IOptions) {} public async writeToReply( reply: IVoxaReply, event?: IVoxaEvent, transition?: ITransition, ) { (reply as any)[messageKey] = this.options; } }; } export const AttachmentLayout = createMessageDirective<string>( "botframeworkAttachmentLayout", "attachmentLayout", ); export const Attachments = createMessageDirective<string>( "botframeworkAttachments", "attachments", );