actions-on-google
Version:
Actions on Google Client Library for Node.js
271 lines (251 loc) • 6.84 kB
text/typescript
/**
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Api from './api/v2';
import * as ApiV1 from './api/v1';
import {values} from '../../common';
/** @public */
export interface Parameters {
/** @public */
[parameter: string]: string | Object | undefined;
}
/** @public */
export interface Contexts {
/** @public */
[context: string]: Context<Parameters> | undefined;
}
/** @public */
export interface OutputContexts {
/** @public */
[context: string]: OutputContext<Parameters> | undefined;
}
/** @public */
export interface Context<TParameters extends Parameters>
extends OutputContext<TParameters> {
/**
* Full name of the context.
* @public
*/
name: string;
/**
* Remaining number of intents
* @public
*/
lifespan: number;
/**
* The context parameters from the current intent.
* Context parameters include parameters collected in previous intents
* during the lifespan of the given context.
*
* See {@link https://dialogflow.com/docs/concept-actions#section-extracting-values-from-contexts|
* here}.
*
* @example
* ```javascript
*
* app.intent('Tell Greeting', conv => {
* const context1 = conv.contexts.get('context1')
* const parameters = context1.parameters
* const color = parameters.color
* const num = parameters.num
* })
*
* // Using destructuring
* app.intent('Tell Greeting', conv => {
* const context1 = conv.contexts.get('context1')
* const { color, num } = context1.parameters
* })
* ```
*
* @public
*/
parameters: TParameters;
}
/** @public */
export interface OutputContext<TParameters extends Parameters> {
/** @public */
lifespan: number;
/** @public */
parameters?: TParameters;
}
const isV1 = (
context: Api.GoogleCloudDialogflowV2Context | ApiV1.DialogflowV1Context
): context is ApiV1.DialogflowV1Context =>
typeof (context as ApiV1.DialogflowV1Context).lifespan === 'number';
export class ContextValues<TContexts extends Contexts> {
/** @public */
input: TContexts;
/** @public */
output: OutputContexts;
/** @hidden */
constructor(
outputContexts:
| Api.GoogleCloudDialogflowV2Context[]
| ApiV1.DialogflowV1Context[] = [],
private _session?: string
) {
this.input = {} as TContexts;
for (const context of outputContexts) {
const name = context.name!;
const parameters = context.parameters!;
if (isV1(context)) {
const lifespan = context.lifespan!;
Object.assign(this.input, {
[name]: {
name,
lifespan,
parameters,
},
});
continue;
}
const lifespanCount = context.lifespanCount!;
const find = /([^/]+)?$/.exec(name);
Object.assign(this.input, {
[find ? find[0] : name]: {
name,
lifespan: lifespanCount!,
parameters,
},
});
}
this.output = {};
}
/** @hidden */
_serialize(): Api.GoogleCloudDialogflowV2Context[] {
return Object.keys(this.output).map(
(name): Api.GoogleCloudDialogflowV2Context => {
const {lifespan, parameters} = this.output[name]!;
return {
name: `${this._session}/contexts/${name}`,
lifespanCount: lifespan,
parameters,
};
}
);
}
/** @hidden */
_serializeV1(): ApiV1.DialogflowV1Context[] {
return Object.keys(this.output).map((name): ApiV1.DialogflowV1Context => {
const {lifespan, parameters} = this.output[name]!;
return {
name,
lifespan,
parameters,
};
});
}
/**
* Returns the incoming context by name for this intent.
*
* @example
* ```javascript
*
* const AppContexts = {
* NUMBER: 'number',
* }
*
* const app = dialogflow()
*
* app.intent('Default Welcome Intent', conv => {
* conv.contexts.set(AppContexts.NUMBER, 1)
* conv.ask('Welcome to action snippets! Say a number.')
* })
*
* // Create intent with 'number' context as requirement
* app.intent('Number Input', conv => {
* const context = conv.contexts.get(AppContexts.NUMBER)
* })
* ```
*
* @param name The name of the Context to retrieve.
* @return Context value matching name or undefined if no matching context.
* @public
*/
get(name: keyof TContexts) {
return this.input[name];
}
/**
* Set a new context for the current intent.
*
* @example
* ```javascript
*
* const AppContexts = {
* NUMBER: 'number',
* }
*
* const app = dialogflow()
*
* app.intent('Default Welcome Intent', conv => {
* conv.contexts.set(AppContexts.NUMBER, 1)
* conv.ask('Welcome to action snippets! Say a number.')
* })
*
* // Create intent with 'number' context as requirement
* app.intent('Number Input', conv => {
* const context = conv.contexts.get(AppContexts.NUMBER)
* })
* ```
*
* @param name Name of the context. Dialogflow converts to lowercase.
* @param lifespan Context lifespan.
* @param parameters Context parameters.
* @public
*/
set(name: string, lifespan: number, parameters?: Parameters) {
this.output[name] = {
lifespan,
parameters,
};
}
/** @public */
delete(name: string) {
this.set(name, 0);
}
/**
* Returns the incoming contexts for this intent as an iterator.
*
* @example
* ```javascript
*
* const AppContexts = {
* NUMBER: 'number',
* }
*
* const app = dialogflow()
*
* app.intent('Default Welcome Intent', conv => {
* conv.contexts.set(AppContexts.NUMBER, 1)
* conv.ask('Welcome to action snippets! Say a number.')
* })
*
* // Create intent with 'number' context as requirement
* app.intent('Number Input', conv => {
* for (const context of conv.contexts) {
* // do something with the contexts
* }
* })
* ```
*
* @public
*/
[Symbol.iterator]() {
const contexts = values(this.input) as Context<Parameters>[];
return contexts[Symbol.iterator]();
// suppose to be Array.prototype.values(), but can't use because of bug:
// https://bugs.chromium.org/p/chromium/issues/detail?id=615873
}
}