UNPKG

altervoice-asterisk-callbot

Version:

Jovo plugin for Altervoice asterisk integration

261 lines (217 loc) 10.1 kB
import { Plugin, BaseApp, SpeechBuilder, Log} from '../../jovo-core'; import { Config } from '../../jovo-platform-dialogflow/dist/src/DialogflowCore'; import { Dialogflow , DialogflowConfig} from '../../jovo-platform-dialogflow'; import { DialogflowAgent} from '../../jovo-platform-dialogflow/dist/src/DialogflowAgent'; import { DialogflowRequest } from '../../jovo-platform-dialogflow/dist/src/core/DialogflowRequest'; import { DialogflowResponse } from '../../jovo-platform-dialogflow/dist/src/core/DialogflowResponse'; import { EntityOverrideMode, SessionEntity, SessionEntityType } from '../../jovo-platform-dialogflow'; import _get = require('lodash.get'); import _set = require('lodash.set'); const _sample = require('lodash.sample'); import _unionWith = require('lodash.unionwith'); import { TelephonyActions } from './Interfaces'; import { AltervoiceAsteriskCallbotUser } from './altervoice-asterisk-callbot-user'; type reprompt = string | SpeechBuilder; //const idPlatform = 'telephony'; const idPlatform = 'phone_gateway'; const idSource = 'phone_gateway'; declare module '../../jovo-platform-dialogflow/dist/src/DialogflowAgent' { export interface DialogflowAgent { isCallbot(): boolean; addActions(action : TelephonyActions) : void; getDtmf(): string; getResult(): any; addOutputContext(name: string, parameters: { [key: string]: any }, lifespanCount:number): void; getOutputContext(name: string): void; addSessionEntityTypes(sessionEntityTypes: SessionEntityType[] ) : this; addSessionEntityType(sessionEntityTypes: SessionEntityType ) : this; addSessionEntity(name: string,value: string,synonyms: string[], entityOverrideMode?: EntityOverrideMode): this; actions : (TelephonyActions| any)[]; $request : DialogflowRequest; } } export * from '../../jovo-platform-dialogflow'; export class AltervoiceAsteriskCallbot implements Plugin { config = { enabled: true, }; constructor(config?: Config) { } install(dialogFlow: Dialogflow): void { dialogFlow.middleware('$output')!.use(this.output.bind(this)); dialogFlow.middleware('$type')!.use(this.type.bind(this)); DialogflowAgent.prototype.isCallbot = function () { return _get(this.$request, 'originalDetectIntentRequest.payload.source') === idSource; }; DialogflowAgent.prototype.addActions = function (action : TelephonyActions) { action.platform = idPlatform; if(action.telephonyMaxCall && action.telephonyMaxCall.prompt) action.telephonyMaxCall.prompt = action.telephonyMaxCall.prompt.toString(); if(action.telephonyInact && action.telephonyInact.prompt) action.telephonyInact.prompt = action.telephonyInact.prompt.toString(); if(!this.actions) this.actions = []; this.actions!.push(action); }; DialogflowAgent.prototype.ask = function( speech: string | SpeechBuilder | string[], reprompt: string | SpeechBuilder | string[], ...reprompts: reprompt[] ) { delete this.$output.tell; if (Array.isArray(speech)) { speech = _sample(speech); } if (Array.isArray(reprompt)) { reprompt = _sample(reprompt); } if (!reprompt) { reprompt = []; } this.$output.ask = { speech: speech.toString(), reprompt: [reprompt.toString()], }; if (reprompts) { this.$output.ask.reprompt = [reprompt.toString()]; reprompts.forEach((repr: string | SpeechBuilder) => { (this.$output.ask!.reprompt as string[]).push(repr.toString()); }); } return this; } DialogflowAgent.prototype.getDtmf = function () { let reg = /\/telephony_dtmf$/g; let outputContext = _get(this.$request, 'queryResult.outputContexts'); let data = outputContext ? outputContext.find((x :any) => reg.exec(x.name)) : {}; return data.parameters; }; DialogflowAgent.prototype.getResult = function () { let reg = /\/telephony_result$/g; let outputContext = _get(this.$request, 'queryResult.outputContexts'); let data = outputContext ? outputContext.find((x :any) => reg.exec(x.name)) : {}; return data.parameters; }; DialogflowAgent.prototype.addOutputContext = function(name: string, parameters: { [key: string]: any }, lifespanCount = 1) { let output = _get(this.$output, "Dialogflow.OutputContexts") || []; output.push({name,parameters,lifespanCount}); _set(this.$output, 'Dialogflow.OutputContexts',output); } DialogflowAgent.prototype.getOutputContext = function(name: string) { return _get(this.$request, 'queryResult.outputContexts', []).find((context: any) => { return context.name.indexOf(`/contexts/${name}`) > -1; }); } DialogflowAgent.prototype.addSessionEntityTypes = function ( sessionEntityTypes: SessionEntityType[] ) { if (! _get(this.$output,'Dialogflow.SessionEntityTypes')) { _set(this.$output, 'Dialogflow.SessionEntityTypes',[]); } sessionEntityTypes.forEach((el: SessionEntityType) => { // Place session id in front of session entity name to accomodate to proper format const sessionId = this.$request!.getSessionId(); const entityName = el.name; el.name = `${sessionId}/entityTypes/${entityName}`; // Set default override mode if (!el.entityOverrideMode) { el.entityOverrideMode = 'ENTITY_OVERRIDE_MODE_SUPPLEMENT'; } }); // Merge existing entities with new ones provided as arguments with _.unionWith. _set(this.$output, 'Dialogflow.SessionEntityTypes', _unionWith( _get( this.$output, 'Dialogflow.SessionEntityTypes'), sessionEntityTypes, (newEntry: SessionEntityType, original: SessionEntityType) => { // If the new session entity does not yet exist by its name, just add it to the new array. if (newEntry.name !== original.name) { return false; } // If the session entity already exists by its name, check if its entity values already exist. const entities = _unionWith( newEntry.entities, original.entities, (n: SessionEntity, o: SessionEntity) => { // If the current value is not yet present, just add it with a new entry. if (n.value !== o.value) { return false; } // Else merge the respective synonyms and unify them. o.synonyms = _unionWith(o.synonyms, n.synonyms); return true; } ); // Replace old entries with new, merged ones. original.entities = entities; return true; }) ); return this; }; DialogflowAgent.prototype.addSessionEntityType = function (sessionEntityType: SessionEntityType) { return this.addSessionEntityTypes([sessionEntityType]); }; } uninstall(app: BaseApp) : void { } type(dialogflowAgent: DialogflowAgent) { if (dialogflowAgent.isCallbot()) { dialogflowAgent.$user = new AltervoiceAsteriskCallbotUser(dialogflowAgent); if (!dialogflowAgent.$response) dialogflowAgent.$response = new DialogflowResponse(); } } output(dialogflowAgent: DialogflowAgent) : void { if (dialogflowAgent.isCallbot()) { const output = dialogflowAgent.$output; if (!dialogflowAgent.$response) { dialogflowAgent.$response = new DialogflowResponse(); } const response = dialogflowAgent.$response as DialogflowResponse; if(dialogflowAgent.actions === undefined) dialogflowAgent.actions = []; if( dialogflowAgent.$output.Dialogflow){ response.sessionEntityTypes = _get(dialogflowAgent.$output.Dialogflow, 'SessionEntityTypes') ; } if( dialogflowAgent.$output.ask ){ // _set(response, 'fulfillmentText', dialogflowAgent.$output.ask.speech); dialogflowAgent.actions.push({ simpleResponse:{ssml: dialogflowAgent.$output.ask.speech}} ); if((dialogflowAgent.$output.ask!.reprompt as string[]).length) _set(response, 'payload.'+idPlatform+'.noInputPrompts', (dialogflowAgent.$output.ask!.reprompt as string[]).map((x: string | SpeechBuilder) => {return {ssml: x};} )); _set(response, 'payload.'+idPlatform+'.expectUserResponse',true); response.end_interaction = false; // delete dialogflowAgent.$output.ask; } else if( dialogflowAgent.$output.tell ){ // _set(response, 'fulfillmentText', dialogflowAgent.$output.tell.speech); dialogflowAgent.actions.push({simpleResponse:{ssml: dialogflowAgent.$output.tell.speech}} ); _set(response, 'payload.'+idPlatform+'.expectUserResponse',false); response.end_interaction = true; // delete dialogflowAgent.$output.tell; } if (response.fulfillmentText && SpeechBuilder.isSSML(response.fulfillmentText)) { const ssml = response.fulfillmentText; if (!response.fulfillmentMessages) { response.fulfillmentMessages = []; } response.fulfillmentMessages.push({ platform: idSource, telephonySynthesizeSpeech: { ssml, }, }); response.fulfillmentText = SpeechBuilder.removeSSML(response.fulfillmentText); } else { Log.debug('Response does not contain SSML'); } if(dialogflowAgent.actions){ _set(response, 'payload.'+idPlatform+'.richResponse.items',dialogflowAgent.actions ); dialogflowAgent.actions = []; } /* let user = _get(dialogflowAgent.$request, 'originalDetectIntentRequest.payload.user'); console.log('user=',user); _set(response, 'payload.'+idPlatform+'.user.',user); */ // _set(response, 'userStorage.user', user); // console.log("response", Object.keys(response)); } } }