[actions-on-google] Upgrade to 1.7 (#22714)

* [actions-on-google] Upgrade to 1.6.1

* [actions-on-google] Upgrade to 1.7

* Make TransactionValues a namespace to avoid issue with enums that can't be imported and acccessed properly

* Use SurfaceCapabilities in more places, warning about AssistantApp enums
This commit is contained in:
joelhegg 2018-01-07 03:21:28 -05:00 committed by Mohamed Hegazy
parent bb43bdb9d1
commit 3423a601fb
6 changed files with 628 additions and 556 deletions

View File

@ -224,18 +224,24 @@ export class ActionsSdkApp extends AssistantApp {
getSelectedOption(): string;
/**
* Asks to collect user's input; all user's queries need to be sent to
* the app.
* {@link https://developers.google.com/actions/policies/general-policies#user_experience|The guidelines when prompting the user for a response must be followed at all times}.
* Asks to collect user's input; all user's queries need to be sent to the app.
* {@link https://developers.google.com/actions/policies/general-policies#user_experience|
* The guidelines when prompting the user for a response must be followed at all times}.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const inputPrompt = app.buildInputPrompt(true, '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
@ -243,9 +249,9 @@ export class ActionsSdkApp extends AssistantApp {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const inputPrompt = app.buildInputPrompt(true, '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
@ -272,7 +278,7 @@ export class ActionsSdkApp extends AssistantApp {
* const app = new ActionsSdkApp({request, response});
*
* function welcomeIntent (app) {
* app.askWithlist('Which of these looks good?',
* app.askWithList('Which of these looks good?',
* app.buildList('List title')
* .addItems([
* app.buildOptionItem(SELECTION_KEY_ONE,
@ -356,11 +362,17 @@ export class ActionsSdkApp extends AssistantApp {
* @example
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const inputPrompt = app.buildInputPrompt(true, '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
@ -368,9 +380,9 @@ export class ActionsSdkApp extends AssistantApp {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const inputPrompt = app.buildInputPrompt(true, '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
@ -390,7 +402,7 @@ export class ActionsSdkApp extends AssistantApp {
/**
* Builds the {@link https://developers.google.com/actions/reference/conversation#InputPrompt|InputPrompt object}
* from initial prompt and no-input prompts.
* from initial prompt and no-input prompts.
*
* The App needs one initial prompt to start the conversation. If there is no user response,
* the App re-opens the mic and renders the no-input prompts three times

View File

@ -1,9 +1,15 @@
import * as express from 'express';
import { BasicCard, Carousel, List, OptionItem, RichResponse } from './response-builder';
import { BasicCard, Carousel, ImageDisplays, List, OptionItem, RichResponse } from './response-builder';
import { ActionPaymentTransactionConfig, Cart, GooglePaymentTransactionConfig, LineItem,
Location, Order, OrderUpdate, TransactionDecision, TransactionValues } from './transactions';
//
// Note: These enums are exported due to limitations with Typescript and this
// library. If you try to import and access them they'll end up null at runtime.
// Either access them through an AssistantApp instance or AssistantApp.prototype.
//
/**
* List of standard intents that the app provides.
* @actionssdk
@ -36,9 +42,9 @@ export enum StandardIntents {
CANCEL,
/** App fires NEW_SURFACE intent when requesting handoff to a new surface from user. */
NEW_SURFACE,
/** App fires REGISTER_UPDATE intent when requesting the user to register for proactive updates. */
/** App fires REGISTER_UPDATE intent when requesting user to register for proactive updates. */
REGISTER_UPDATE,
/** App receives CONFIGURE_UPDATES intent to indicate a custom REGISTER_UPDATE intent should be sent. */
/** App receives CONFIGURE_UPDATES intent to indicate a REGISTER_UPDATE intent should be sent. */
CONFIGURE_UPDATES
}
@ -273,7 +279,10 @@ export interface DeviceLocation {
export interface User {
/** Random string ID for Google user. */
userId: string;
/** User name information. Null if not requested with {@link AssistantApp#askForPermission|askForPermission(SupportedPermissions.NAME)}. */
/**
* User name information. Null if not requested with
* {@link AssistantApp#askForPermission|askForPermission(SupportedPermissions.NAME)}.
*/
userName: UserName;
/** Unique Oauth2 token. Only available with account linking. */
accessToken: string;
@ -303,7 +312,7 @@ export interface Surface {
*/
export interface Capability {
/** Name of the capability. */
name: string;
name: SurfaceCapabilities;
}
/**
@ -408,6 +417,11 @@ export class AssistantApp {
*/
readonly SignInStatus: typeof SignInStatus;
/**
* Values related to supporting {@link ImageDisplays}.
*/
readonly ImageDisplays: typeof ImageDisplays;
/**
* Values related to supporting {@link Transactions}.
*/
@ -430,11 +444,17 @@ export class AssistantApp {
* // Actions SDK
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const inputPrompt = app.buildInputPrompt(true, '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
@ -442,9 +462,9 @@ export class AssistantApp {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const inputPrompt = app.buildInputPrompt(true, '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>',
* ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']);
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
@ -479,6 +499,87 @@ export class AssistantApp {
*/
handleRequest(handler: ((app: AssistantApp) => any) | (Map<string, (app: AssistantApp) => any>)): void;
/**
* Asynchronously handles the incoming Assistant request using a handler or Map of handlers.
* Each handler can be a function callback or Promise.
*
* @example
* // Actions SDK
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
* function rawInput (app) {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.MAIN, mainIntent);
* actionMap.set(app.StandardIntents.TEXT, rawInput);
*
* app.handleRequestAsync(actionMap)
* .then(
* (result) => {
* // handle the result
* })
* .catch(
* (reason) => {
* // handle an error
* });
*
* // Dialogflow
* const app = new DialogflowApp({request: req, response: res});
* const NAME_ACTION = 'make_name';
* const COLOR_ARGUMENT = 'color';
* const NUMBER_ARGUMENT = 'number';
*
* function makeName (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* const color = app.getArgument(COLOR_ARGUMENT);
* app.tell('Alright, your silly name is ' +
* color + ' ' + number +
* '! I hope you like it. See you next time.');
* }
*
* const actionMap = new Map();
* actionMap.set(NAME_ACTION, makeName);
*
* app.handleRequestAsync(actionMap)
* .then(
* (result) => {
* // handle the result
* })
* .catch(
* (reason) => {
* // handle an error
* });
*
* @param handler The handler (or Map of handlers) for the request.
* @return Promise to resolve the result of the handler that was invoked.
* @actionssdk
* @dialogflow
*/
handleRequestAsync(handler: ((app: AssistantApp) => any) | (Map<string, (app: AssistantApp) => any>)): Promise<any>;
/**
* Equivalent to {@link AssistantApp#askForPermission|askForPermission},
* but allows you to prompt the user for more than one permission at once.
@ -528,8 +629,8 @@ export class AssistantApp {
* which comes from AssistantApp.SupportedPermissions.
* @param dialogState JSON object the app uses to hold dialog state that
* will be circulated back by Assistant. Used in {@link ActionsSdkApp}.
* @return A response is sent to Assistant to ask for the user's permission; for any
* invalid input, we return null.
* @return A response is sent to Assistant to ask for the user's permission.
* For any invalid input, we return null.
* @actionssdk
* @dialogflow
*/
@ -580,8 +681,8 @@ export class AssistantApp {
* {@link AssistantApp#getArgument}.
* @param dialogState JSON object the app uses to hold dialog state that
* will be circulated back by Assistant. Used in {@link ActionsSdkApp}.
* @return A response is sent to Assistant to ask for the user's permission; for any
* invalid input, we return null.
* @return A response is sent to Assistant to ask for the user's permission.
* For any invalid input, we return null.
* @actionssdk
* @dialogflow
*/
@ -679,13 +780,15 @@ export class AssistantApp {
* I'll just need to get your name from Google, is that OK?'.
*
* Once the user accepts or denies the request, the Assistant will fire another intent:
* assistant.intent.action.PERMISSION with a boolean argument: AssistantApp.BuiltInArgNames.PERMISSION_GRANTED
* app.StandardIntents.PERMISSION with a boolean argument: app.BuiltInArgNames.PERMISSION_GRANTED
* and, if granted, the information that you requested.
*
* Read more:
*
* * {@link https://developers.google.com/actions/reference/conversation#ExpectedIntent|Supported Permissions}
* * Check if the permission has been granted with {@link AssistantApp#isPermissionGranted|isPermissionsGranted}
* * {@link https://developers.google.com/actions/reference/conversation#ExpectedIntent|
* Supported Permissions}
* * Check if the permission has been granted with
* {@link AssistantApp#isPermissionGranted|isPermissionsGranted}
* * {@link AssistantApp#getDeviceLocation|getDeviceLocation}
* * {@link AssistantApp#getUserName|getUserName}
*
@ -896,6 +999,7 @@ export class AssistantApp {
* are set in the {@link https://console.actions.google.com|Actions Console}.
* Retrieve the access token in subsequent intents using
* app.getUser().accessToken.
* Works only for en-* locales.
*
* @example
* const app = new DialogflowApp({ request, response });
@ -930,6 +1034,7 @@ export class AssistantApp {
/**
* Requests the user to switch to another surface during the conversation.
* Works only for en-* locales.
*
* @example
* const app = new DialogflowApp({ request, response });
@ -1126,41 +1231,6 @@ export class AssistantApp {
*/
getInputType(): number | string;
/**
* Get the argument value by name from the current intent.
* If the argument is included in originalRequest, and is not a text argument,
* the entire argument object is returned.
*
* Note: If incoming request is using an API version under 2 (e.g. 'v1'),
* the argument object will be in Proto2 format (snake_case, etc).
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const WELCOME_INTENT = 'input.welcome';
* const NUMBER_INTENT = 'input.number';
*
* function welcomeIntent (app) {
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param argName Name of the argument.
* @return Argument value matching argName
* or null if no matching argument.
* @dialogflow
* @actionssdk
*/
getArgumentCommon(argName: string): object;
/**
* Gets transactability of user. Only use after calling
* askForTransactionRequirements. Null if no result given.
@ -1258,7 +1328,7 @@ export class AssistantApp {
* @dialogflow
* @actionssdk
*/
getSurfaceCapabilities(): string[];
getSurfaceCapabilities(): SurfaceCapabilities[];
/**
* Returns the set of other available surfaces for the user.

View File

@ -36,7 +36,8 @@ export interface DialogflowAppOptions {
}
/**
* This is the class that handles the communication with Dialogflow's fulfillment API.
* This is the class that handles the communication with Dialogflow's fulfillment API v1.
* Doesn't currently support Dialogflow's fulfillment API v2.
*/
export class DialogflowApp extends AssistantApp {
/**

View File

@ -1,4 +1,4 @@
// Type definitions for actions-on-google 1.6
// Type definitions for actions-on-google 1.7
// Project: https://github.com/actions-on-google/actions-on-google-nodejs
// Definitions by: Joel Hegg <https://github.com/joelhegg>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

View File

@ -4,6 +4,27 @@
import { OrderUpdate } from './transactions';
/**
* List of possible options to display the image in a BasicCard.
* When the aspect ratio of an image is not the same as the surface,
* this attribute changes how the image is displayed in the card.
*/
export enum ImageDisplays {
/**
* Pads the gaps between the image and image frame with a blurred copy of the
* same image.
*/
DEFAULT,
/**
* Fill the gap between the image and image container with white bars.
*/
WHITE,
/**
* Image is centered and resized so the image fits perfectly in the container.
*/
CROPPED
}
/**
* Simple Response type.
*/
@ -74,19 +95,19 @@ export interface StructuredResponse {
orderUpdate: OrderUpdate;
}
export interface RichResponseItemBasicCard {
export interface ItemBasicCard {
basicCard: BasicCard;
}
export interface RichResponseItemSimpleResponse {
export interface ItemSimpleResponse {
simpleResponse: SimpleResponse;
}
export interface RichResponseItemStructuredResponse {
export interface ItemStructuredResponse {
structuredResponse: StructuredResponse;
}
export type RichResponseItem = RichResponseItemBasicCard | RichResponseItemSimpleResponse | RichResponseItemStructuredResponse;
export type RichResponseItem = ItemBasicCard | ItemSimpleResponse | ItemStructuredResponse;
/**
* Class for initializing and constructing Rich Responses with chainable interface.
@ -150,7 +171,8 @@ export class RichResponse {
isValidSuggestionText(suggestionText: string): boolean;
/**
* Sets the suggestion link for this rich response.
* Sets the suggestion link for this rich response. The destination site must be verified
* (https://developers.google.com/actions/console/brand-verification).
*
* @param destinationName Name of the link out destination.
* @param suggestionUrl - String URL to open when suggestion is used.
@ -240,6 +262,16 @@ export class BasicCard {
*/
setImage(url: string, accessibilityText: string, width?: number, height?: number): BasicCard;
/**
* Sets the display options for the image in this Basic Card.
* Use one of the image display constants. If none is chosen,
* ImageDisplays.DEFAULT will be enforced.
*
* @param option The option for displaying the image.
* @return Returns current constructed BasicCard.
*/
setImageDisplay(option: ImageDisplays): BasicCard;
/**
* Adds a button below card.
*
@ -402,3 +434,10 @@ export class OptionItem {
* @return True if text contains SSML, false otherwise.
*/
export function isSsml(text: string): boolean;
/**
* Check if given text contains SSML, allowing for whitespace padding.
* @param text Text to check.
* @return True if text contains possibly whitespace padded SSML, false otherwise.
*/
export function isPaddedSsml(text: string): boolean;

File diff suppressed because it is too large Load Diff