diff --git a/types/actions-on-google/NOTICE b/types/actions-on-google/NOTICE new file mode 100644 index 0000000000..262b08db36 --- /dev/null +++ b/types/actions-on-google/NOTICE @@ -0,0 +1,13 @@ +License Notices: + +The API definitions are from Actions on Google reference site [1] and actions-on-google library [2]. +The actions-on-google library is licensed under the Apache 2.0 License [3]. + +The code documentation is reproduced from work created and shared by Google [4] +and used according to terms described in the Creative Commons 3.0 Attribution License [5]. + +[1] https://developers.google.com/actions/ +[2] https://github.com/actions-on-google/actions-on-google-nodejs +[3] http://www.apache.org/licenses/LICENSE-2.0 +[4] https://developers.google.com/readme/policies/ +[5] http://creativecommons.org/licenses/by/3.0/ diff --git a/types/actions-on-google/actions-on-google-tests.ts b/types/actions-on-google/actions-on-google-tests.ts new file mode 100644 index 0000000000..e57e1e8d98 --- /dev/null +++ b/types/actions-on-google/actions-on-google-tests.ts @@ -0,0 +1,33 @@ +import { ActionsSdkApp, ActionsSdkAppOptions, DialogflowApp, DialogflowAppOptions, AssistantApp, + Responses, Transactions } from 'actions-on-google'; +import * as express from 'express'; + +function testActionsSdk(request: express.Request, response: express.Response) { + const app = new ActionsSdkApp({request, response}); + const actionMap = new Map(); + actionMap.set(app.StandardIntents.MAIN, () => { + const richResponse: Responses.RichResponse = app.buildRichResponse() + .addSimpleResponse('Hello world') + .addSuggestions(['foo', 'bar']); + app.ask(richResponse); + }); + app.handleRequest(actionMap); +} + +function testDialogflow(request: express.Request, response: express.Response) { + const app = new DialogflowApp({request, response}); + const actionMap = new Map(); + actionMap.set(app.StandardIntents.MAIN, () => { + const order: Transactions.Order = app.buildOrder('foo'); + app.askForTransactionDecision(order, { + type: app.Transactions.PaymentType.PAYMENT_CARD, + displayName: 'VISA-1234', + deliveryAddressRequired: true + }); + }); + app.handleRequest(actionMap); +} + +const expressApp = express(); +expressApp.get('/actionssdk', testActionsSdk); +expressApp.get('/dialogflow', testDialogflow); diff --git a/types/actions-on-google/actions-sdk-app.d.ts b/types/actions-on-google/actions-sdk-app.d.ts new file mode 100644 index 0000000000..8de0de0cfb --- /dev/null +++ b/types/actions-on-google/actions-sdk-app.d.ts @@ -0,0 +1,390 @@ +import * as express from 'express'; + +import { AssistantApp } from './assistant-app'; +import { Carousel, List, RichResponse, SimpleResponse } from './response-builder'; + +// --------------------------------------------------------------------------- +// Actions SDK support +// --------------------------------------------------------------------------- + +export interface ActionsSdkAppOptions { + /** Express HTTP request object. */ + request: express.Request; + /** Express HTTP response object. */ + response: express.Response; + /** Function callback when session starts. */ + sessionStarted?(): any; +} + +/** + * This is the class that handles the conversation API directly from Assistant, + * providing implementation for all the methods available in the API. + */ +export class ActionsSdkApp extends AssistantApp { + /** + * Constructor for ActionsSdkApp object. + * To be used in the Actions SDK HTTP endpoint logic. + * + * @example + * const ActionsSdkApp = require('actions-on-google').ActionsSdkApp; + * const app = new ActionsSdkApp({request: request, response: response, + * sessionStarted:sessionStarted}); + * + * @actionssdk + */ + constructor(options: ActionsSdkAppOptions); + + /** + * Validates whether request is from Assistant through signature verification. + * Uses Google-Auth-Library to verify authorization token against given + * Google Cloud Project ID. Auth token is given in request header with key, + * "Authorization". + * + * @example + * const app = new ActionsSdkApp({request, response}); + * app.isRequestFromAssistant('nodejs-cloud-test-project-1234') + * .then(() => { + * app.ask('Hey there, thanks for stopping by!'); + * }) + * .catch(err => { + * response.status(400).send(); + * }); + * + * @param projectId Google Cloud Project ID for the Assistant app. + * @return Promise resolving with google-auth-library LoginTicket + * if request is from a valid source, otherwise rejects with the error reason + * for an invalid token. + * @actionssdk + */ + isRequestFromAssistant(projectId: string): Promise; + + /** + * Gets the request Conversation API version. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * const apiVersion = app.getApiVersion(); + * + * @return Version value or null if no value. + * @actionssdk + */ + getApiVersion(): string; + + /** + * Gets the user's raw input query. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * app.tell('You said ' + app.getRawInput()); + * + * @return User's raw query or null if no value. + * @actionssdk + */ + getRawInput(): string; + + /** + * Gets previous JSON dialog state that the app sent to Assistant. + * Alternatively, use the app.data field to store JSON values between requests. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * const dialogState = app.getDialogState(); + * + * @return JSON object provided to the Assistant in the previous + * user turn or {} if no value. + * @actionssdk + */ + getDialogState(): any; + + /** + * Gets the "versionLabel" specified inside the Action Package. + * Used by app to do version control. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * const actionVersionLabel = app.getActionVersionLabel(); + * + * @return The specified version label or null if unspecified. + * @actionssdk + */ + getActionVersionLabel(): string; + + /** + * Gets the unique conversation ID. It's a new ID for the initial query, + * and stays the same until the end of the conversation. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * const conversationId = app.getConversationId(); + * + * @return Conversation ID or null if no value. + * @actionssdk + */ + getConversationId(): string; + + /** + * Get the current intent. Alternatively, using a handler Map with + * {@link AssistantApp#handleRequest|handleRequest}, the client library will + * automatically handle the incoming intents. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * + * function responseHandler (app) { + * const intent = app.getIntent(); + * switch (intent) { + * case app.StandardIntents.MAIN: + * const inputPrompt = app.buildInputPrompt(false, 'Welcome to action snippets! Say anything.'); + * app.ask(inputPrompt); + * break; + * + * case app.StandardIntents.TEXT: + * app.tell('You said ' + app.getRawInput()); + * break; + * } + * } + * + * app.handleRequest(responseHandler); + * + * @return Intent id or null if no value. + * @actionssdk + */ + getIntent(): string; + + /** + * Get the argument value by name from the current intent. If the argument + * 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). + * + * @param argName Name of the argument. + * @return Argument value matching argName + * or null if no matching argument. + * @actionssdk + */ + getArgument(argName: string): string; + + /** + * Returns the option key user chose from options response. + * + * @example + * const app = new App({request: req, response: res}); + * + * function pickOption (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.askWithCarousel('Which of these looks good?', + * app.buildCarousel().addItems( + * app.buildOptionItem('another_choice', ['Another choice']). + * setTitle('Another choice').setDescription('Choose me!'))); + * } else { + * app.ask('What would you like?'); + * } + * } + * + * function optionPicked (app) { + * app.ask('You picked ' + app.getSelectedOption()); + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.TEXT, pickOption); + * actionMap.set(app.StandardIntents.OPTION, optionPicked); + * + * app.handleRequest(actionMap); + * + * @return Option key of selected item. Null if no option selected or + * if current intent is not OPTION intent. + * @actionssdk + */ + 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}. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * + * function mainIntent (app) { + * const inputPrompt = app.buildInputPrompt(true, 'Hi! ' + + * 'I can read out an ordinal like ' + + * '123. Say a number.', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * + * function rawInput (app) { + * if (app.getRawInput() === 'bye') { + * app.tell('Goodbye!'); + * } else { + * const inputPrompt = app.buildInputPrompt(true, 'You said, ' + + * app.getRawInput() + '', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.MAIN, mainIntent); + * actionMap.set(app.StandardIntents.TEXT, rawInput); + * + * app.handleRequest(actionMap); + * + * @param inputPrompt Holding initial and + * no-input prompts. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by App. + * @return The response that is sent to Assistant to ask user to provide input. + * @actionssdk + */ + ask(inputPrompt: object | SimpleResponse | RichResponse, dialogState?: object): express.Response | null; + + /** + * Asks to collect user's input with a list. + * + * @example + * const app = new ActionsSdkApp({request, response}); + * + * function welcomeIntent (app) { + * app.askWithlist('Which of these looks good?', + * app.buildList('List title') + * .addItems([ + * app.buildOptionItem(SELECTION_KEY_ONE, + * ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2']) + * .setTitle('Number one'), + * app.buildOptionItem(SELECTION_KEY_TWO, + * ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2']) + * .setTitle('Number two'), + * ])); + * } + * + * function optionIntent (app) { + * if (app.getSelectedOption() === SELECTION_KEY_ONE) { + * app.tell('Number one is a great choice!'); + * } else { + * app.tell('Number two is a great choice!'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.TEXT, welcomeIntent); + * actionMap.set(app.StandardIntents.OPTION, optionIntent); + * app.handleRequest(actionMap); + * + * @param inputPrompt Holding initial and + * no-input prompts. Cannot contain basic card. + * @param list List built with {@link AssistantApp#buildList|buildList}. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. + * @return The response that is sent to Assistant to ask user to provide input. + * @actionssdk + */ + askWithList(inputPrompt: object | SimpleResponse | RichResponse, list: List, dialogState?: object): express.Response | null; + + /** + * Asks to collect user's input with a carousel. + * + * @example + * const app = new ActionsSdkApp({request, response}); + * + * function welcomeIntent (app) { + * app.askWithCarousel('Which of these looks good?', + * app.buildCarousel() + * .addItems([ + * app.buildOptionItem(SELECTION_KEY_ONE, + * ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2']) + * .setTitle('Number one'), + * app.buildOptionItem(SELECTION_KEY_TWO, + * ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2']) + * .setTitle('Number two'), + * ])); + * } + * + * function optionIntent (app) { + * if (app.getSelectedOption() === SELECTION_KEY_ONE) { + * app.tell('Number one is a great choice!'); + * } else { + * app.tell('Number two is a great choice!'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.TEXT, welcomeIntent); + * actionMap.set(app.StandardIntents.OPTION, optionIntent); + * app.handleRequest(actionMap); + * + * @param inputPrompt Holding initial and + * no-input prompts. Cannot contain basic card. + * @param carousel Carousel built with + * {@link AssistantApp#buildCarousel|buildCarousel}. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. + * @return The response that is sent to Assistant to ask user to provide input. + * @actionssdk + */ + askWithCarousel(inputPrompt: object | SimpleResponse | RichResponse, carousel: Carousel, dialogState?: object): express.Response | null; + + /** + * Tells Assistant to render the speech response and close the mic. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * + * function mainIntent (app) { + * const inputPrompt = app.buildInputPrompt(true, 'Hi! ' + + * 'I can read out an ordinal like ' + + * '123. Say a number.', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * + * function rawInput (app) { + * if (app.getRawInput() === 'bye') { + * app.tell('Goodbye!'); + * } else { + * const inputPrompt = app.buildInputPrompt(true, 'You said, ' + + * app.getRawInput() + '', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.MAIN, mainIntent); + * actionMap.set(app.StandardIntents.TEXT, rawInput); + * + * app.handleRequest(actionMap); + * + * @param textToSpeech Final response. + * Spoken response can be SSML. + * @return The HTTP response that is sent back to Assistant. + * @actionssdk + */ + tell(textToSpeech: string | SimpleResponse | RichResponse): express.Response | null; + + /** + * Builds the {@link https://developers.google.com/actions/reference/conversation#InputPrompt|InputPrompt object} + * 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 + * (one for each no-input prompt that was configured) to help the user + * provide the right response. + * + * Note: we highly recommend app to provide all the prompts required here in order to ensure a + * good user experience. + * + * @example + * const inputPrompt = app.buildInputPrompt(false, 'Welcome to action snippets! Say a number.', + * ['Say any number', 'Pick a number', 'What is the number?']); + * app.ask(inputPrompt); + * + * @param isSsml Indicates whether the text to speech is SSML or not. + * @param initialPrompt The initial prompt the App asks the user. + * @param noInputs Array of re-prompts when the user does not respond (max 3). + * @return. + * @actionssdk + */ + buildInputPrompt(isSsml: boolean, initialPrompt: string, noInputs?: string[]): object; +} diff --git a/types/actions-on-google/assistant-app.d.ts b/types/actions-on-google/assistant-app.d.ts new file mode 100644 index 0000000000..d33f447a2e --- /dev/null +++ b/types/actions-on-google/assistant-app.d.ts @@ -0,0 +1,1316 @@ +import * as express from 'express'; + +import { BasicCard, Carousel, List, OptionItem, RichResponse } from './response-builder'; +import { ActionPaymentTransactionConfig, Cart, GooglePaymentTransactionConfig, LineItem, + Location, Order, OrderUpdate, TransactionDecision, TransactionValues } from './transactions'; + +/** + * List of standard intents that the app provides. + * @actionssdk + * @dialogflow + */ +export enum StandardIntents { + /** + * App fires MAIN intent for queries like [talk to $app]. + */ + MAIN, + /** + * App fires TEXT intent when action issues ask intent. + */ + TEXT, + /** + * App fires PERMISSION intent when action invokes askForPermission. + */ + PERMISSION, + /** + * App fires OPTION intent when user chooses from options provided. + */ + OPTION, + /** + * App fires TRANSACTION_REQUIREMENTS_CHECK intent when action sets up transaction. + */ + TRANSACTION_REQUIREMENTS_CHECK, + /** + * App fires DELIVERY_ADDRESS intent when action asks for delivery address. + */ + DELIVERY_ADDRESS, + /** + * App fires TRANSACTION_DECISION intent when action asks for transaction decision. + */ + TRANSACTION_DECISION, + /** + * App fires CONFIRMATION intent when requesting affirmation from user. + */ + CONFIRMATION, + /** + * App fires DATETIME intent when requesting date/time from user. + */ + DATETIME, + /** + * App fires SIGN_IN intent when requesting sign-in from user. + */ + SIGN_IN, + /** + * App fires NO_INPUT intent when user doesn't provide input. + */ + NO_INPUT, + /** + * App fires CANCEL intent when user exits app mid-dialog. + */ + CANCEL, + /** + * App fires NEW_SURFACE intent when requesting handoff to a new surface from user. + */ + NEW_SURFACE, +} + +/** + * List of supported permissions the app supports. + * @actionssdk + * @dialogflow + */ +export enum SupportedPermissions { + /** + * The user's name as defined in the + * {@link https://developers.google.com/actions/reference/conversation#UserProfile|UserProfile object} + */ + NAME, + /** + * The location of the user's current device, as defined in the + * {@link https://developers.google.com/actions/reference/conversation#Location|Location object}. + */ + DEVICE_PRECISE_LOCATION, + /** + * City and zipcode corresponding to the location of the user's current device, as defined in the + * {@link https://developers.google.com/actions/reference/conversation#Location|Location object}. + */ + DEVICE_COARSE_LOCATION, +} + +/** + * List of built-in argument names. + * @actionssdk + * @dialogflow + */ +export enum BuiltInArgNames { + /** + * Permission granted argument. + */ + PERMISSION_GRANTED, + /** + * Option selected argument. + */ + OPTION, + /** + * Transaction requirements check result argument. + */ + TRANSACTION_REQ_CHECK_RESULT, + /** + * Delivery address value argument. + */ + DELIVERY_ADDRESS_VALUE, + /** + * Transactions decision argument. + */ + TRANSACTION_DECISION_VALUE, + /** + * Confirmation argument. + */ + CONFIRMATION, + /** + * DateTime argument. + */ + DATETIME, + /** + * Sign in status argument. + */ + SIGN_IN, + /** + * Reprompt count for consecutive NO_INPUT intents. + */ + REPROMPT_COUNT, + /** + * Flag representing finality of NO_INPUT intent. + */ + IS_FINAL_REPROMPT, + /** + * New surface value argument. + */ + NEW_SURFACE, +} + +/** + * List of possible conversation stages, as defined in the + * {@link https://developers.google.com/actions/reference/conversation#Conversation|Conversation object}. + * @actionssdk + * @dialogflow + */ +export enum ConversationStages { + /** + * Unspecified conversation state. + */ + UNSPECIFIED, + /** + * A new conversation. + */ + NEW, + /** + * An active (ongoing) conversation. + */ + ACTIVE, +} + +/** + * List of surface capabilities supported by the app. + * @actionssdk + * @dialogflow + */ +export enum SurfaceCapabilities { + /** + * The ability to output audio. + */ + AUDIO_OUTPUT, + /** + * The ability to output on a screen + */ + SCREEN_OUTPUT, +} + +/** + * List of possible user input types. + * @actionssdk + * @dialogflow + */ +export enum InputTypes { + /** + * Unspecified. + */ + UNSPECIFIED, + /** + * Input given by touch. + */ + TOUCH, + /** + * Input given by voice (spoken). + */ + VOICE, + /** + * Input given by keyboard (typed). + */ + KEYBOARD +} + +/** + * List of possible sign in result status values. + * @actionssdk + * @dialogflow + */ +export enum SignInStatus { + /** + * Unknown status. + */ + UNSPECIFIED, + /** + * User successfully completed the account linking. + */ + OK, + /** + * Cancelled or dismissed account linking. + */ + CANCELLED, + /** + * System or network error. + */ + ERROR +} + +/** + * User provided date/time info. + */ +export interface DateTime { + date: { + year: number; + month: number; + day: number; + }; + time: { + hours: number; + minutes: number; + seconds: number; + nanos: number; + }; +} + +/** + * User's permissioned name info. + */ +export interface UserName { + /** User's display name. */ + displayName: string; + /** User's given name. */ + givenName: string; + /** User's family name. */ + familyName: string; +} + +/** + * User's permissioned device location. + */ +export interface DeviceLocation { + /** {latitude, longitude}. Requested with SupportedPermissions.DEVICE_PRECISE_LOCATION. */ + coordinates: object; + /** Full, formatted street address. Requested with SupportedPermissions.DEVICE_PRECISE_LOCATION. */ + address: string; + /** Zip code. Requested with SupportedPermissions.DEVICE_COARSE_LOCATION. */ + zipCode: string; + /** Device city. Requested with SupportedPermissions.DEVICE_COARSE_LOCATION. */ + city: string; +} + +/** + * User object. + */ +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)}. */ + userName: UserName; + /** Unique Oauth2 token. Only available with account linking. */ + accessToken: string; +} + +/** + * Actions on Google Surface. + */ +export interface Surface { + /** Capabilities of the surface. */ + capabilities: Capability[]; +} + +/** + * Surface capability. + */ +export interface Capability { + /** Name of the capability. */ + name: string; +} + +/** + * The Actions on Google client library AssistantApp base class. + * + * This class contains the methods that are shared between platforms to support the conversation API + * protocol from Assistant. It also exports the 'State' class as a helper to represent states by + * name. + */ +export class AssistantApp { + /** + * The session state. + */ + state: string; + + /** + * The session data in JSON format. + */ + data: object; + + /** + * List of standard intents that the app provides. + * @actionssdk + * @dialogflow + */ + readonly StandardIntents: typeof StandardIntents; + + /** + * List of supported permissions the app supports. + * @actionssdk + * @dialogflow + */ + readonly SupportedPermissions: typeof SupportedPermissions; + + /** + * List of built-in argument names. + * @actionssdk + * @dialogflow + */ + readonly BuiltInArgNames: typeof BuiltInArgNames; + + /** + * List of possible conversation stages, as defined in the + * {@link https://developers.google.com/actions/reference/conversation#Conversation|Conversation object}. + * @actionssdk + * @dialogflow + */ + readonly ConversationStages: typeof ConversationStages; + + /** + * List of surface capabilities supported by the app. + * @actionssdk + * @dialogflow + */ + readonly SurfaceCapabilities: typeof SurfaceCapabilities; + + /** + * List of possible user input types. + * @actionssdk + * @dialogflow + */ + readonly InputTypes: typeof InputTypes; + + /** + * List of possible sign in result status values. + * @actionssdk + * @dialogflow + */ + readonly SignInStatus: typeof SignInStatus; + + /** + * Values related to supporting {@link Transactions}. + */ + readonly Transactions: typeof TransactionValues; + + // --------------------------------------------------------------------------- + // Public APIs + // --------------------------------------------------------------------------- + + /** + * 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}); + * + * function mainIntent (app) { + * const inputPrompt = app.buildInputPrompt(true, 'Hi! ' + + * 'I can read out an ordinal like ' + + * '123. Say a number.', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * + * function rawInput (app) { + * if (app.getRawInput() === 'bye') { + * app.tell('Goodbye!'); + * } else { + * const inputPrompt = app.buildInputPrompt(true, 'You said, ' + + * app.getRawInput() + '', + * ['I didn\'t hear a number', 'If you\'re still there, what\'s the number?', 'What is the number?']); + * app.ask(inputPrompt); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.MAIN, mainIntent); + * actionMap.set(app.StandardIntents.TEXT, rawInput); + * + * app.handleRequest(actionMap); + * + * // 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.handleRequest(actionMap); + * + * @param handler The handler (or Map of handlers) for the request. + * @actionssdk + * @dialogflow + */ + handleRequest(handler: ((app: AssistantApp) => any) | (Map any>)): void; + + /** + * Equivalent to {@link AssistantApp#askForPermission|askForPermission}, + * but allows you to prompt the user for more than one permission at once. + * + * Notes: + * + * * The order in which you specify the permission prompts does not matter - + * it is controlled by the Assistant to provide a consistent user experience. + * * The user will be able to either accept all permissions at once, or none. + * If you wish to allow them to selectively accept one or other, make several + * dialog turns asking for each permission independently with askForPermission. + * * Asking for DEVICE_COARSE_LOCATION and DEVICE_PRECISE_LOCATION at once is + * equivalent to just asking for DEVICE_PRECISE_LOCATION + * + * @example + * const app = new DialogflowApp({request: req, response: res}); + * const REQUEST_PERMISSION_ACTION = 'request_permission'; + * const GET_RIDE_ACTION = 'get_ride'; + * + * function requestPermission (app) { + * const permission = [ + * app.SupportedPermissions.NAME, + * app.SupportedPermissions.DEVICE_PRECISE_LOCATION + * ]; + * app.askForPermissions('To pick you up', permissions); + * } + * + * function sendRide (app) { + * if (app.isPermissionGranted()) { + * const displayName = app.getUserName().displayName; + * const address = app.getDeviceLocation().address; + * app.tell('I will tell your driver to pick up ' + displayName + + * ' at ' + address); + * } else { + * // Response shows that user did not grant permission + * app.tell('Sorry, I could not figure out where to pick you up.'); + * } + * } + * const actionMap = new Map(); + * actionMap.set(REQUEST_PERMISSION_ACTION, requestPermission); + * actionMap.set(GET_RIDE_ACTION, sendRide); + * app.handleRequest(actionMap); + * + * @param context Context why the permission is being asked; it's the TTS + * prompt prefix (action phrase) we ask the user. + * @param permissions Array of permissions App supports, each of + * 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 ActionsSdkAssistant}. + * @return A response is sent to Assistant to ask for the user's permission; for any + * invalid input, we return null. + * @actionssdk + * @dialogflow + */ + askForPermissions(context: string, permissions: string[], dialogState?: object): express.Response | null; + + /** + * Checks whether user is in transactable state. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const WELCOME_INTENT = 'input.welcome'; + * const TXN_REQ_COMPLETE = 'txn.req.complete'; + * + * let transactionConfig = { + * deliveryAddressRequired: false, + * type: app.Transactions.PaymentType.BANK, + * displayName: 'Checking-1234' + * }; + * function welcomeIntent (app) { + * app.askForTransactionRequirements(transactionConfig); + * } + * + * function txnReqCheck (app) { + * if (app.getTransactionRequirementsResult() === app.Transactions.ResultType.OK) { + * // continue cart building flow + * } else { + * // don't continue cart building + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(TXN_REQ_COMPLETE, txnReqCheck); + * app.handleRequest(actionMap); + * + * @param + * transactionConfig Configuration for the transaction. Includes payment + * options and order options. Optional if order has no payment or + * delivery. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response. + * @actionssdk + * @dialogflow + */ + askForTransactionRequirements(transactionConfig?: ActionPaymentTransactionConfig | GooglePaymentTransactionConfig, dialogState?: object): express.Response | null; + + /** + * Asks user to confirm transaction information. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const WELCOME_INTENT = 'input.welcome'; + * const TXN_COMPLETE = 'txn.complete'; + * + * let transactionConfig = { + * deliveryAddressRequired: false, + * type: app.Transactions.PaymentType.BANK, + * displayName: 'Checking-1234' + * }; + * + * let order = app.buildOrder(); + * // fill order cart + * + * function welcomeIntent (app) { + * app.askForTransaction(order, transactionConfig); + * } + * + * function txnComplete (app) { + * // respond with order update + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(TXN_COMPLETE, txnComplete); + * app.handleRequest(actionMap); + * + * @param order Order built with buildOrder(). + * @param + * transactionConfig Configuration for the transaction. Includes payment + * options and order options. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response + * @dialogflow + */ + askForTransactionDecision(order: Order, transactionConfig: ActionPaymentTransactionConfig | GooglePaymentTransactionConfig, dialogState?: object): express.Response | null; + + /** + * Asks the Assistant to guide the user to grant a permission. For example, + * if you want your app to get access to the user's name, you would invoke + * the askForPermission method with a context containing the reason for the request, + * and the AssistantApp.SupportedPermissions.NAME permission. With this, the Assistant will ask + * the user, in your agent's voice, the following: '[Context with reason for the request], + * 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 + * 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 AssistantApp#getDeviceLocation|getDeviceLocation} + * * {@link AssistantApp#getUserName|getUserName} + * + * @example + * const app = new DialogflowApp({request: req, response: res}); + * const REQUEST_PERMISSION_ACTION = 'request_permission'; + * const GET_RIDE_ACTION = 'get_ride'; + * + * function requestPermission (app) { + * const permission = app.SupportedPermissions.NAME; + * app.askForPermission('To pick you up', permission); + * } + * + * function sendRide (app) { + * if (app.isPermissionGranted()) { + * const displayName = app.getUserName().displayName; + * app.tell('I will tell your driver to pick up ' + displayName); + * } else { + * // Response shows that user did not grant permission + * app.tell('Sorry, I could not figure out who to pick up.'); + * } + * } + * const actionMap = new Map(); + * actionMap.set(REQUEST_PERMISSION_ACTION, requestPermission); + * actionMap.set(GET_RIDE_ACTION, sendRide); + * app.handleRequest(actionMap); + * + * @param context Context why permission is asked; it's the TTS + * prompt prefix (action phrase) we ask the user. + * @param permission One of the permissions Assistant supports, each of + * which comes from AssistantApp.SupportedPermissions. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. + * @return A response is sent to the Assistant to ask for the user's permission; + * for any invalid input, we return null. + * @actionssdk + * @dialogflow + */ + askForPermission(context: string, permission: string, dialogState?: object): express.Response | null; + + /** + * Returns true if the request follows a previous request asking for + * permission from the user and the user granted the permission(s). Otherwise, + * false. Use with {@link AssistantApp#askForPermissions|askForPermissions}. + * + * @example + * const app = new ActionsSdkApp({request: request, response: response}); + * // or + * const app = new DialogflowApp({request: request, response: response}); + * app.askForPermissions("To get you a ride", [ + * app.SupportedPermissions.NAME, + * app.SupportedPermissions.DEVICE_PRECISE_LOCATION + * ]); + * // ... + * // In response handler for subsequent intent: + * if (app.isPermissionGranted()) { + * // Use the requested permission(s) to get the user a ride + * } + * + * @return true if permissions granted. + * @dialogflow + * @actionssdk + */ + isPermissionGranted(): boolean; + + /** + * Asks user for delivery address. + * + * @example + * // For DialogflowApp: + * const app = new DialogflowApp({request, response}); + * const WELCOME_INTENT = 'input.welcome'; + * const DELIVERY_INTENT = 'delivery.address'; + * + * function welcomeIntent (app) { + * app.askForDeliveryAddress('To make sure I can deliver to you'); + * } + * + * function addressIntent (app) { + * const postalCode = app.getDeliveryAddress().postalAddress.postalCode; + * if (isInDeliveryZone(postalCode)) { + * app.tell('Great looks like you\'re in our delivery area!'); + * } else { + * app.tell('I\'m sorry it looks like we can\'t deliver to you.'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(DELIVERY_INTENT, addressIntent); + * app.handleRequest(actionMap); + * + * // For ActionsSdkApp: + * const app = new ActionsSdkApp({request, response}); + * const WELCOME_INTENT = app.StandardIntents.MAIN; + * const DELIVERY_INTENT = app.StandardIntents.DELIVERY_ADDRESS; + * + * function welcomeIntent (app) { + * app.askForDeliveryAddress('To make sure I can deliver to you'); + * } + * + * function addressIntent (app) { + * const postalCode = app.getDeliveryAddress().postalAddress.postalCode; + * if (isInDeliveryZone(postalCode)) { + * app.tell('Great looks like you\'re in our delivery area!'); + * } else { + * app.tell('I\'m sorry it looks like we can\'t deliver to you.'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(DELIVERY_INTENT, addressIntent); + * app.handleRequest(actionMap); + * + * @param reason Reason given to user for asking delivery address. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. + * @return HTTP response. + * @actionssdk + * @dialogflow + */ + askForDeliveryAddress(reason: string, dialogState?: object): express.Response | null; + + /** + * Asks user for a confirmation. + * + * @example + * const app = new DialogflowApp({ request, response }); + * const WELCOME_INTENT = 'input.welcome'; + * const CONFIRMATION = 'confirmation'; + * + * function welcomeIntent (app) { + * app.askForConfirmation('Are you sure you want to do that?'); + * } + * + * function confirmation (app) { + * if (app.getUserConfirmation()) { + * app.tell('Great! I\'m glad you want to do it!'); + * } else { + * app.tell('That\'s okay. Let\'s not do it now.'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(CONFIRMATION, confirmation); + * app.handleRequest(actionMap); + * + * @param prompt The confirmation prompt presented to the user to + * query for an affirmative or negative response. If undefined or null, + * Google will use a generic yes/no prompt. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response. + * @actionssdk + * @dialogflow + */ + askForConfirmation(prompt?: string, dialogState?: object): express.Response | null; + + /** + * Asks user for a timezone-agnostic date and time. + * + * @example + * const app = new DialogflowApp({ request, response }); + * const WELCOME_INTENT = 'input.welcome'; + * const DATETIME = 'datetime'; + * + * function welcomeIntent (app) { + * app.askForDateTime('When do you want to come in?', + * 'Which date works best for you?', + * 'What time of day works best for you?'); + * } + * + * function datetime (app) { + * app.tell({speech: 'Great see you at your appointment!', + * displayText: 'Great, we will see you on ' + * + app.getDateTime().date.month + * + '/' + app.getDateTime().date.day + * + ' at ' + app.getDateTime().time.hours + * + (app.getDateTime().time.minutes || '')}); + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(DATETIME, datetime); + * app.handleRequest(actionMap); + * + * @param initialPrompt The initial prompt used to ask for a + * date and time. If undefined or null, Google will use a generic + * prompt. + * @param datePrompt The prompt used to specifically ask for the + * date if not provided by user. If undefined or null, Google will use a + * generic prompt. + * @param timePrompt The prompt used to specifically ask for the + * time if not provided by user. If undefined or null, Google will use a + * generic prompt. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response. + * @actionssdk + * @dialogflow + */ + askForDateTime(initialPrompt?: string, datePrompt?: string, timePrompt?: string, dialogState?: object): express.Response | null; + + /** + * Hands the user off to a web sign in flow. App sign in and OAuth credentials + * are set in the {@link https://console.actions.google.com|Actions Console}. + * Retrieve the access token in subsequent intents using + * app.getUser().accessToken. + * + * Note: Currently this API requires enabling the app for Transactions APIs. + * To do this, fill out the App Info section of the Actions Console project + * and check the box indicating the use of Transactions under "Privacy and + * consent". + * + * @example + * const app = new DialogflowApp({ request, response }); + * const WELCOME_INTENT = 'input.welcome'; + * const SIGN_IN = 'sign.in'; + * + * function welcomeIntent (app) { + * app.askForSignIn(); + * } + * + * function signIn (app) { + * if (app.getSignInStatus() === app.SignInstatus.OK) { + * let accessToken = app.getUser().accessToken; + * app.ask('Great, thanks for signing in!'); + * } else { + * app.ask('I won\'t be able to save your data, but let\'s continue!'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(SIGN_IN, signIn); + * app.handleRequest(actionMap); + * + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response. + * @actionssdk + * @dialogflow + */ + askForSignIn(dialogState?: object): express.Response | null; + + /** + * Requests the user to switch to another surface during the conversation. + * + * @example + * const app = new DialogflowApp({ request, response }); + * const WELCOME_INTENT = 'input.welcome'; + * const SHOW_IMAGE = 'show.image'; + * + * function welcomeIntent (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * showPicture(app); + * } else if (app.hasAvailableSurfaceCapabilities(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.askForNewSurface('To show you an image', + * 'Check out this image', + * [app.SurfaceCapabilities.SCREEN_OUTPUT] + * ); + * } else { + * app.tell('This part of the app only works on screen devices. Sorry about that'); + * } + * } + * + * function showImage (app) { + * if (!app.isNewSurface()) { + * app.tell('Ok, I understand. You don't want to see pictures. Bye'); + * } else { + * showPicture(app, pictureType); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(SHOW_IMAGE, showImage); + * app.handleRequest(actionMap); + * + * @param context Context why new surface is requested; it's the TTS + * prompt prefix (action phrase) we ask the user. + * @param notificationTitle Title of the notification appearing on + * new surface device. + * @param capabilities The list of capabilities required in + * the surface. + * @param dialogState JSON object the app uses to hold dialog state that + * will be circulated back by Assistant. Used in {@link ActionsSdkAssistant}. + * @return HTTP response. + * @dialogflow + * @actionssdk + */ + askForNewSurface(context: string, notificationTitle: string, capabilities: SurfaceCapabilities[], dialogState?: object): express.Response | null; + + /** + * Gets the {@link User} object. + * The user object contains information about the user, including + * a string identifier and personal information (requires requesting permissions, + * see {@link AssistantApp#askForPermissions|askForPermissions}). + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * // or + * const app = new ActionsSdkApp({request: request, response: response}); + * const userId = app.getUser().userId; + * + * @return Null if no value. + * @actionssdk + * @dialogflow + */ + getUser(): User; + + /** + * If granted permission to user's name in previous intent, returns user's + * display name, family name, and given name. If name info is unavailable, + * returns null. + * + * @example + * const app = new DialogflowApp({request: req, response: res}); + * const REQUEST_PERMISSION_ACTION = 'request_permission'; + * const SAY_NAME_ACTION = 'get_name'; + * + * function requestPermission (app) { + * const permission = app.SupportedPermissions.NAME; + * app.askForPermission('To know who you are', permission); + * } + * + * function sayName (app) { + * if (app.isPermissionGranted()) { + * app.tell('Your name is ' + app.getUserName().displayName)); + * } else { + * // Response shows that user did not grant permission + * app.tell('Sorry, I could not get your name.'); + * } + * } + * const actionMap = new Map(); + * actionMap.set(REQUEST_PERMISSION_ACTION, requestPermission); + * actionMap.set(SAY_NAME_ACTION, sayName); + * app.handleRequest(actionMap); + * @return Null if name permission is not granted. + * @actionssdk + * @dialogflow + */ + getUserName(): UserName; + + /** + * Gets the user locale. Returned string represents the regional language + * information of the user set in their Assistant settings. + * For example, 'en-US' represents US English. + * + * @example + * const app = new DialogflowApp({request, response}); + * const locale = app.getUserLocale(); + * + * @return User's locale, e.g. 'en-US'. Null if no locale given. + * @actionssdk + * @dialogflow + */ + getUserLocale(): string; + + /** + * If granted permission to device's location in previous intent, returns device's + * location (see {@link AssistantApp#askForPermissions|askForPermissions}). + * If device info is unavailable, returns null. + * + * @example + * const app = new DialogflowApp({request: req, response: res}); + * // or + * const app = new ActionsSdkApp({request: req, response: res}); + * app.askForPermission("To get you a ride", + * app.SupportedPermissions.DEVICE_PRECISE_LOCATION); + * // ... + * // In response handler for permissions fallback intent: + * if (app.isPermissionGranted()) { + * sendCarTo(app.getDeviceLocation().coordinates); + * } + * + * @return Null if location permission is not granted. + * @actionssdk + * @dialogflow + */ + getDeviceLocation(): DeviceLocation; + + /** + * Gets type of input used for this request. + * @return One of AssistantApp.InputTypes. + * Null if no input type given. + * @dialogflow + * @actionssdk + */ + 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. + * + * @return One of Transactions.ResultType. + * @dialogflow + * @actionssdk + */ + getTransactionRequirementsResult(): string; + + /** + * Gets order delivery address. Only use after calling askForDeliveryAddress. + * + * @return Delivery address information. Null if user + * denies permission, or no address given. + * @dialogflow + * @actionssdk + */ + getDeliveryAddress(): Location; + + /** + * Gets transaction decision information. Only use after calling + * askForTransactionDecision. + * + * @return Transaction decision data. Returns object with + * userDecision only if user declines. userDecision will be one of + * Transactions.ConfirmationDecision. Null if no decision given. + * @dialogflow + * @actionssdk + */ + getTransactionDecision(): TransactionDecision; + + /** + * Gets confirmation decision. Use after askForConfirmation. + * + * @return False if user replied with negative response. Null if no user + * confirmation decision given. + * @dialogflow + * @actionssdk + */ + getUserConfirmation(): boolean | null; + + /** + * Gets user provided date and time. Use after askForDateTime. + * + * @return Date and time given by the user. Null if no user + * date and time given. + * @dialogflow + * @actionssdk + */ + getDateTime(): DateTime; + + /** + * Gets status of user sign in request. + * + * @return Result of user sign in request. One of + * DialogflowApp.SignInStatus or ActionsSdkApp.SignInStatus + * Null if no sign in status. + * @dialogflow + * @actionssdk + */ + getSignInStatus(): string; + + /** + * Returns true if user device has a given surface capability. + * + * @param requestedCapability Must be one of {@link SurfaceCapabilities}. + * @return True if user device has the given capability. + * + * @example + * const app = new DialogflowApp({request: req, response: res}); + * const DESCRIBE_SOMETHING = 'DESCRIBE_SOMETHING'; + * + * function describe (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.tell(richResponseWithBasicCard); + * } else { + * app.tell('Let me tell you about ...'); + * } + * } + * const actionMap = new Map(); + * actionMap.set(DESCRIBE_SOMETHING, describe); + * app.handleRequest(actionMap); + * + * @dialogflow + * @actionssdk + */ + hasSurfaceCapability(requestedCapability: SurfaceCapabilities): boolean; + + /** + * Gets surface capabilities of user device. + * + * @return Supported surface capabilities, as defined in + * AssistantApp.SurfaceCapabilities. + * @dialogflow + * @actionssdk + */ + getSurfaceCapabilities(): string[]; + + /** + * Returns the set of other available surfaces for the user. + * + * @return Empty if no available surfaces. + * @actionssdk + * @dialogflow + */ + getAvailableSurfaces(): Surface[]; + + /** + * Returns true if user has an available surface which includes all given + * capabilities. Available surfaces capabilities may exist on surfaces other + * than that used for an ongoing conversation. + * + * @param capabilities Must be one of + * {@link SurfaceCapabilities}. + * @return True if user has a capability available on some surface. + * + * @dialogflow + * @actionssdk + */ + hasAvailableSurfaceCapabilities(capabilities: SurfaceCapabilities | SurfaceCapabilities[]): boolean; + + /** + * Returns the result of the AskForNewSurface helper. + * + * @return True if user has triggered conversation on a new device + * following the NEW_SURFACE intent. + * @actionssdk + * @dialogflow + */ + isNewSurface(): boolean; + + /** + * Returns true if the app is being tested in sandbox mode. Enable sandbox + * mode in the (Actions console)[console.actions.google.com] to test + * transactions. + * + * @return True if app is being used in Sandbox mode. + * @dialogflow + * @actionssdk + */ + isInSandbox(): boolean; + + /** + * Returns the number of subsequent reprompts related to silent input from the + * user. This should be used along with the NO_INPUT intent to reprompt the + * user for input in cases where the Google Assistant could not pick up any + * speech. + * + * @example + * const app = new ActionsSdkApp({request, response}); + * + * function welcome (app) { + * app.ask('Welcome to your app!'); + * } + * + * function noInput (app) { + * if (app.getRepromptCount() === 0) { + * app.ask(`What was that?`); + * } else if (app.getRepromptCount() === 1) { + * app.ask(`Sorry I didn't catch that. Could you repeat yourself?`); + * } else if (app.isFinalReprompt()) { + * app.tell(`Okay let's try this again later.`); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.MAIN, welcome); + * actionMap.set(app.StandardIntents.NO_INPUT, noInput); + * app.handleRequest(actionMap); + * + * @return The current reprompt count. Null if no reprompt count + * available (e.g. not in the NO_INPUT intent). + * @dialogflow + * @actionssdk + */ + getRepromptCount(): number; + + /** + * Returns true if it is the final reprompt related to silent input from the + * user. This should be used along with the NO_INPUT intent to give the final + * response to the user after multiple silences and should be an app.tell + * which ends the conversation. + * + * @example + * const app = new ActionsSdkApp({request, response}); + * + * function welcome (app) { + * app.ask('Welcome to your app!'); + * } + * + * function noInput (app) { + * if (app.getRepromptCount() === 0) { + * app.ask(`What was that?`); + * } else if (app.getRepromptCount() === 1) { + * app.ask(`Sorry I didn't catch that. Could you repeat yourself?`); + * } else if (app.isFinalReprompt()) { + * app.tell(`Okay let's try this again later.`); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(app.StandardIntents.MAIN, welcome); + * actionMap.set(app.StandardIntents.NO_INPUT, noInput); + * app.handleRequest(actionMap); + * + * @return True if in a NO_INPUT intent and this is the final turn + * of dialog. + * @dialogflow + * @actionssdk + */ + isFinalReprompt(): boolean; + + // --------------------------------------------------------------------------- + // Response Builders + // --------------------------------------------------------------------------- + + /** + * Constructs RichResponse with chainable property setters. + * + * @param richResponse RichResponse to clone. + * @return Constructed RichResponse. + */ + buildRichResponse(richResponse?: RichResponse): RichResponse; + + /** + * Constructs BasicCard with chainable property setters. + * + * @param bodyText Body text of the card. Can be set using setTitle + * instead. + * @return Constructed BasicCard. + */ + buildBasicCard(bodyText?: string): BasicCard; + + /** + * Constructs List with chainable property setters. + * + * @param title A title to set for a new List. + * @return Constructed List. + */ + buildList(title?: string): List; + + /** + * Constructs Carousel with chainable property setters. + * + * @return Constructed Carousel. + */ + buildCarousel(): Carousel; + + /** + * Constructs OptionItem with chainable property setters. + * + * @param key A unique key to identify this option. This key will + * be returned as an argument in the resulting actions.intent.OPTION + * intent. + * @param synonyms A list of synonyms which the user may + * use to identify this option instead of the option key. + * @return Constructed OptionItem. + */ + buildOptionItem(key?: string, synonyms?: string | string[]): OptionItem; + + // --------------------------------------------------------------------------- + // Transaction Builders + // --------------------------------------------------------------------------- + + /** + * Constructs Order with chainable property setters. + * + * @param orderId Unique identifier for the order. + * @return Constructed Order. + */ + buildOrder(orderId: string): Order; + + /** + * Constructs Cart with chainable property setters. + * + * @param cartId Unique identifier for the cart. + * @return Constructed Cart. + */ + buildCart(cartId?: string): Cart; + + /** + * Constructs LineItem with chainable property setters. + * Because of a previous bug, the parameters are swapped compared to + * the LineItem constructor to prevent a breaking change. + * + * @param name Name of the line item. + * @param id Unique identifier for the item. + * @return Constructed LineItem. + */ + buildLineItem(name: string, id: string): LineItem; + + /** + * Constructs OrderUpdate with chainable property setters. + * + * @param orderId Unique identifier of the order. + * @param isGoogleOrderId True if the order ID is provided by + * Google. False if the order ID is app provided. + * @return Constructed OrderUpdate. + */ + buildOrderUpdate(orderId: string, isGoogleOrderId: boolean): OrderUpdate; +} diff --git a/types/actions-on-google/dialogflow-app.d.ts b/types/actions-on-google/dialogflow-app.d.ts new file mode 100644 index 0000000000..ab768241c2 --- /dev/null +++ b/types/actions-on-google/dialogflow-app.d.ts @@ -0,0 +1,571 @@ +import * as express from 'express'; + +import { AssistantApp } from './assistant-app'; +import { Carousel, List, RichResponse, SimpleResponse } from './response-builder'; + +// --------------------------------------------------------------------------- +// Dialogflow support +// --------------------------------------------------------------------------- + +/** + * Dialogflow {@link https://dialogflow.com/docs/concept-contexts|Context}. + */ +export interface Context { + /** Full name of the context. */ + name: string; + /** + * Parameters carried within this context. + * See {@link https://dialogflow.com/docs/concept-actions#section-extracting-values-from-contexts|here}. + */ + parameters: object; + /** Remaining number of intents */ + lifespan: number; +} + +export interface DialogflowAppOptions { + /** Express HTTP request object. */ + request: express.Request; + /** Express HTTP response object. */ + response: express.Response; + /** + * Function callback when session starts. + * Only called if webhook is enabled for welcome/triggering intents, and + * called from Web Simulator or Google Home device (i.e., not Dialogflow simulator). + */ + sessionStarted?(): any; +} + +/** + * This is the class that handles the communication with Dialogflow's fulfillment API. + */ +export class DialogflowApp extends AssistantApp { + /** + * Constructor for DialogflowApp object. + * To be used in the Dialogflow fulfillment webhook logic. + * + * @example + * const DialogflowApp = require('actions-on-google').DialogflowApp; + * const app = new DialogflowApp({request: request, response: response, + * sessionStarted:sessionStarted}); + * + * @dialogflow + */ + constructor(options: DialogflowAppOptions); + + /** + * @deprecated + * Verifies whether the request comes from Dialogflow. + * + * @param key The header key specified by the developer in the + * Dialogflow Fulfillment settings of the app. + * @param value The private value specified by the developer inside the + * fulfillment header. + * @return True if the request comes from Dialogflow. + * @dialogflow + */ + isRequestFromApiAi(key: string, value: string): boolean; + + /** + * Verifies whether the request comes from Dialogflow. + * + * @param key The header key specified by the developer in the + * Dialogflow Fulfillment settings of the app. + * @param value The private value specified by the developer inside the + * fulfillment header. + * @return True if the request comes from Dialogflow. + * @dialogflow + */ + isRequestFromDialogflow(key: string, value: string): boolean; + + /** + * Get the current intent. Alternatively, using a handler Map with + * {@link AssistantApp#handleRequest|handleRequest}, + * the client library will automatically handle the incoming intents. + * 'Intent' in the Dialogflow context translates into the current action. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * + * function responseHandler (app) { + * const intent = app.getIntent(); + * switch (intent) { + * case WELCOME_INTENT: + * app.ask('Welcome to action snippets! Say a number.'); + * break; + * + * case NUMBER_INTENT: + * const number = app.getArgument(NUMBER_ARGUMENT); + * app.tell('You said ' + number); + * break; + * } + * } + * + * app.handleRequest(responseHandler); + * + * @return Intent id or null if no value (action name). + * @dialogflow + */ + getIntent(): 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 + */ + getArgument(argName: string): object; + + /** + * Get the context argument value by name from the current intent. Context + * arguments include parameters collected in previous intents during the + * lifespan of the given context. If the context argument has an original + * value, usually representing the underlying entity value, that will be given + * as part of the return object. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const WELCOME_INTENT = 'input.welcome'; + * const NUMBER_INTENT = 'input.number'; + * const OUT_CONTEXT = 'output_context'; + * const NUMBER_ARG = 'myNumberArg'; + * + * function welcomeIntent (app) { + * const parameters = {}; + * parameters[NUMBER_ARG] = '42'; + * app.setContext(OUT_CONTEXT, 1, parameters); + * app.ask('Welcome to action snippets! Ask me for your number.'); + * } + * + * function numberIntent (app) { + * const number = app.getContextArgument(OUT_CONTEXT, NUMBER_ARG); + * // number === { value: 42 } + * app.tell('Your number is ' + number.value); + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(NUMBER_INTENT, numberIntent); + * app.handleRequest(actionMap); + * + * @param contextName Name of the context. + * @param argName Name of the argument. + * @return Object containing value property and optional original + * property matching context argument. Null if no matching argument. + * @dialogflow + */ + getContextArgument(contextName: string, argName: string): object; + + /** + * Returns the RichResponse constructed in Dialogflow response builder. + * + * @example + * const app = new App({request: req, response: res}); + * + * function tellFact (app) { + * let fact = 'Google was founded in 1998'; + * + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.ask(app.getIncomingRichResponse().addSimpleResponse('Here\'s a ' + + * 'fact for you. ' + fact + ' Which one do you want to hear about ' + + * 'next, Google\'s history or headquarters?')); + * } else { + * app.ask('Here\'s a fact for you. ' + fact + ' Which one ' + + * 'do you want to hear about next, Google\'s history or headquarters?'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set('tell.fact', tellFact); + * + * app.handleRequest(actionMap); + * + * @return RichResponse created in Dialogflow. If no RichResponse was + * created, an empty RichResponse is returned. + * @dialogflow + */ + getIncomingRichResponse(): RichResponse; + + /** + * Returns the List constructed in Dialogflow response builder. + * + * @example + * const app = new App({request: req, response: res}); + * + * function pickOption (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.askWithList('Which of these looks good?', + * app.getIncomingList().addItems( + * app.buildOptionItem('another_choice', ['Another choice']). + * setTitle('Another choice'))); + * } else { + * app.ask('What would you like?'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set('pick.option', pickOption); + * + * app.handleRequest(actionMap); + * + * @return List created in Dialogflow. If no List was created, an empty + * List is returned. + * @dialogflow + */ + getIncomingList(): List; + + /** + * Returns the Carousel constructed in Dialogflow response builder. + * + * @example + * const app = new App({request: req, response: res}); + * + * function pickOption (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.askWithCarousel('Which of these looks good?', + * app.getIncomingCarousel().addItems( + * app.buildOptionItem('another_choice', ['Another choice']). + * setTitle('Another choice').setDescription('Choose me!'))); + * } else { + * app.ask('What would you like?'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set('pick.option', pickOption); + * + * app.handleRequest(actionMap); + * + * @return Carousel created in Dialogflow. If no Carousel was created, + * an empty Carousel is returned. + * @dialogflow + */ + getIncomingCarousel(): Carousel; + + /** + * Returns the option key user chose from options response. + * + * @example + * const app = new App({request: req, response: res}); + * + * function pickOption (app) { + * if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) { + * app.askWithCarousel('Which of these looks good?', + * app.getIncomingCarousel().addItems( + * app.buildOptionItem('another_choice', ['Another choice']). + * setTitle('Another choice').setDescription('Choose me!'))); + * } else { + * app.ask('What would you like?'); + * } + * } + * + * function optionPicked (app) { + * app.ask('You picked ' + app.getSelectedOption()); + * } + * + * const actionMap = new Map(); + * actionMap.set('pick.option', pickOption); + * actionMap.set('option.picked', optionPicked); + * + * app.handleRequest(actionMap); + * + * @return Option key of selected item. Null if no option selected or + * if current intent is not OPTION intent. + * @dialogflow + */ + getSelectedOption(): string; + + /** + * Asks to collect the user's input. + * {@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}. + * + * NOTE: Due to a bug, if you specify the no-input prompts, + * the mic is closed after the 3rd prompt, so you should use the 3rd prompt + * for a bye message until the bug is fixed. + * + * @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.', + * ['Say any number', 'Pick a number', 'We can stop here. See you soon.']); + * } + * + * 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 inputPrompt The input prompt + * response. + * @param noInputs Array of re-prompts when the user does not respond (max 3). + * @return HTTP response. + * @dialogflow + */ + ask(inputPrompt: string | SimpleResponse | RichResponse, noInputs?: string[]): express.Response | null; + + /** + * Asks to collect the user's input with a list. + * + * @example + * const app = new DialogflowApp({request, response}); + * const WELCOME_INTENT = 'input.welcome'; + * const OPTION_INTENT = 'option.select'; + * + * function welcomeIntent (app) { + * app.askWithList('Which of these looks good?', + * app.buildList('List title') + * .addItems([ + * app.buildOptionItem(SELECTION_KEY_ONE, + * ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2']) + * .setTitle('Title of First List Item'), + * app.buildOptionItem(SELECTION_KEY_TWO, + * ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2']) + * .setTitle('Title of Second List Item'), + * ])); + * } + * + * function optionIntent (app) { + * if (app.getSelectedOption() === SELECTION_KEY_ONE) { + * app.tell('Number one is a great choice!'); + * } else { + * app.tell('Number two is a great choice!'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(OPTION_INTENT, optionIntent); + * app.handleRequest(actionMap); + * + * @param inputPrompt The input prompt + * response. + * @param.list List built with {@link AssistantApp#buildList|buildList} + * @return HTTP response. + * @dialogflow + */ + askWithList(inputPrompt: string | RichResponse | SimpleResponse, list: List): express.Response | null; + + /** + * Asks to collect the user's input with a carousel. + * + * @example + * const app = new DialogflowApp({request, response}); + * const WELCOME_INTENT = 'input.welcome'; + * const OPTION_INTENT = 'option.select'; + * + * function welcomeIntent (app) { + * app.askWithCarousel('Which of these looks good?', + * app.buildCarousel() + * .addItems([ + * app.buildOptionItem(SELECTION_KEY_ONE, + * ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2']) + * .setTitle('Number one'), + * app.buildOptionItem(SELECTION_KEY_TWO, + * ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2']) + * .setTitle('Number two'), + * ])); + * } + * + * function optionIntent (app) { + * if (app.getSelectedOption() === SELECTION_KEY_ONE) { + * app.tell('Number one is a great choice!'); + * } else { + * app.tell('Number two is a great choice!'); + * } + * } + * + * const actionMap = new Map(); + * actionMap.set(WELCOME_INTENT, welcomeIntent); + * actionMap.set(OPTION_INTENT, optionIntent); + * app.handleRequest(actionMap); + * + * @param inputPrompt The input prompt + * response. + * @param carousel Carousel built with + * {@link AssistantApp#buildCarousel|buildCarousel}. + * @return HTTP response. + * @dialogflow + */ + askWithCarousel(inputPrompt: string | RichResponse | SimpleResponse, carousel: Carousel): express.Response | null; + + /** + * Tells the Assistant to render the speech response and close the mic. + * + * @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 speechResponse Final response. + * Spoken response can be SSML. + * @return The response that is sent back to Assistant. + * @dialogflow + */ + tell(speechResponse: string | SimpleResponse | RichResponse): express.Response | null; + + /** + * Set a new context for the current intent. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const CONTEXT_NUMBER = 'number'; + * const NUMBER_ARGUMENT = 'myNumber'; + * + * function welcomeIntent (app) { + * app.setContext(CONTEXT_NUMBER); + * 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 name Name of the context. Dialogflow converts to lowercase. + * @param [lifespan=1] Context lifespan. + * @param parameters Context JSON parameters. + * @return Null if the context name is not defined. + * @dialogflow + */ + setContext(name: string, lifespan?: number, parameters?: any): null | undefined; + + /** + * Returns the incoming contexts for this intent. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const CONTEXT_NUMBER = 'number'; + * const NUMBER_ARGUMENT = 'myNumber'; + * + * function welcomeIntent (app) { + * app.setContext(CONTEXT_NUMBER); + * app.ask('Welcome to action snippets! Say a number.'); + * } + * + * function numberIntent (app) { + * let contexts = app.getContexts(); + * // contexts === [{ + * // name: 'number', + * // lifespan: 0, + * // parameters: { + * // myNumber: '23', + * // myNumber.original: '23' + * // } + * // }] + * 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); + * + * @return Empty if no active contexts. + * @dialogflow + */ + getContexts(): Context[]; + + /** + * Returns the incoming context by name for this intent. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * const CONTEXT_NUMBER = 'number'; + * const NUMBER_ARGUMENT = 'myNumber'; + * + * function welcomeIntent (app) { + * app.setContext(CONTEXT_NUMBER); + * app.ask('Welcome to action snippets! Say a number.'); + * } + * + * function numberIntent (app) { + * let context = app.getContext(CONTEXT_NUMBER); + * // context === { + * // name: 'number', + * // lifespan: 0, + * // parameters: { + * // myNumber: '23', + * // myNumber.original: '23' + * // } + * // } + * 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 name The name of the Context to retrieve. + * @return Context value matching name + * or null if no matching context. + * @dialogflow + */ + getContext(name: string): object; + + /** + * Gets the user's raw input query. + * + * @example + * const app = new DialogflowApp({request: request, response: response}); + * app.tell('You said ' + app.getRawInput()); + * + * @return User's raw query or null if no value. + * @dialogflow + */ + getRawInput(): string; +} diff --git a/types/actions-on-google/index.d.ts b/types/actions-on-google/index.d.ts new file mode 100644 index 0000000000..5f7baba3b8 --- /dev/null +++ b/types/actions-on-google/index.d.ts @@ -0,0 +1,24 @@ +// Type definitions for actions-on-google 1.5 +// Project: https://github.com/actions-on-google/actions-on-google-nodejs +// Definitions by: Joel Hegg +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.4 + +/** + * The Actions on Google client library. + * https://developers.google.com/actions/ + */ + +import * as Transactions from './transactions'; +import * as Responses from './response-builder'; + +export { AssistantApp } from './assistant-app'; +export { ActionsSdkApp, ActionsSdkAppOptions } from './actions-sdk-app'; +export { DialogflowApp, DialogflowAppOptions } from './dialogflow-app'; +export { Transactions }; +export { Responses }; +// Backwards compatibility +export { AssistantApp as Assistant } from './assistant-app'; +export { ActionsSdkApp as ActionsSdkAssistant } from './actions-sdk-app'; +export { DialogflowApp as ApiAiAssistant } from './dialogflow-app'; +export { DialogflowApp as ApiAiApp } from './dialogflow-app'; diff --git a/types/actions-on-google/response-builder.d.ts b/types/actions-on-google/response-builder.d.ts new file mode 100644 index 0000000000..1e11984551 --- /dev/null +++ b/types/actions-on-google/response-builder.d.ts @@ -0,0 +1,386 @@ +/** + * A collection of response builders. + */ + +import { OrderUpdate } from './transactions'; + +/** + * Simple Response type. + */ +export interface SimpleResponse { + /** Speech to be spoken to user. SSML allowed. */ + speech: string; + /** Optional text to be shown to user */ + displayText?: string; +} + +/** + * Suggestions to show with response. + */ +export interface Suggestion { + /** Text of the suggestion. */ + title: string; +} + +/** + * Link Out Suggestion. Used in rich response as a suggestion chip which, when + * selected, links out to external URL. + */ +export interface LinkOutSuggestion { + /** Text shown on the suggestion chip. */ + title: string; + /** String URL to open. */ + url: string; +} + +/** + * Image type shown on visual elements. + */ +export interface Image { + /** Image source URL. */ + url: string; + /** Text to replace for image for accessibility. */ + accessibilityText: string; + /** Width of the image. */ + width: number; + /** Height of the image. */ + height: number; +} + +/** + * Basic Card Button. Shown below basic cards. Open a URL when selected. + */ +export interface Button { + /** Text shown on the button. */ + title: string; + /** Action to take when selected. */ + openUrlAction: { + /** String URL to open. */ + url: string; + }; +} + +/** + * Option info. Provides unique identifier for a given OptionItem. + */ +export interface OptionInfo { + /** Unique string ID for this option. */ + key: string; + /** Synonyms that can be used by the user to indicate this option if they do not use the key. */ + synonyms: string[]; +} + +/** + * Class for initializing and constructing Rich Responses with chainable interface. + */ +export class RichResponse { + /** + * Constructor for RichResponse. Accepts optional RichResponse to clone. + * + * @param richResponse Optional RichResponse to clone. + */ + constructor(richResponse?: RichResponse); + + /** + * Ordered list of either SimpleResponse objects or BasicCard objects. + * First item must be SimpleResponse. There can be at most one card. + */ + items: Array; + + /** + * Ordered list of text suggestions to display. Optional. + */ + suggestions: Suggestion[]; + + /** + * Link Out Suggestion chip for this rich response. Optional. + */ + linkOutSuggestion?: LinkOutSuggestion; + + /** + * Adds a SimpleResponse to list of items. + * + * @param simpleResponse Simple response to present to + * user. If just a string, display text will not be set. + * @return Returns current constructed RichResponse. + */ + addSimpleResponse(simpleResponse: string | SimpleResponse): RichResponse; + + /** + * Adds a BasicCard to list of items. + * + * @param basicCard Basic card to include in response. + * @return Returns current constructed RichResponse. + */ + addBasicCard(basicCard: BasicCard): RichResponse; + + /** + * Adds a single suggestion or list of suggestions to list of items. + * + * @param suggestions Either a single string suggestion + * or list of suggestions to add. + * @return Returns current constructed RichResponse. + */ + addSuggestions(suggestions: string | string[]): RichResponse; + + /** + * Returns true if the given suggestion text is valid to be added to the suggestion list. A valid + * text string is not longer than 25 characters. + * @param suggestionText Text to validate as suggestion. + * @return True if the text is valid, false otherwise.s + */ + isValidSuggestionText(suggestionText: string): boolean; + + /** + * Sets the suggestion link for this rich response. + * + * @param destinationName Name of the link out destination. + * @param suggestionUrl - String URL to open when suggestion is used. + * @return Returns current constructed RichResponse. + */ + addSuggestionLink(destinationName: string, suggestionUrl: string): RichResponse; + + /** + * Adds an order update to this response. Use after a successful transaction + * decision to confirm the order. + * + * @param orderUpdate OrderUpdate object to add. + * @return Returns current constructed RichResponse. + */ + addOrderUpdate(orderUpdate: OrderUpdate): RichResponse; +} + +/** + * Class for initializing and constructing Basic Cards with chainable interface. + */ +export class BasicCard { + /** + * Constructor for BasicCard. Accepts optional BasicCard to clone. + * + * @param basicCard Optional BasicCard to clone. + */ + constructor(basicCard?: BasicCard); + + /** + * Title of the card. Optional. + */ + title?: string; + + /** + * Body text to show on the card. Required, unless image is present. + */ + formattedText: string; + + /** + * Subtitle of the card. Optional. + */ + subtitle?: string; + + /** + * Image to show on the card. Optional. + */ + image?: Image; + + /** + * Ordered list of buttons to show below card. Optional. + */ + buttons: Button[]; + + /** + * Sets the title for this Basic Card. + * + * @param title Title to show on card. + * @return Returns current constructed BasicCard. + */ + setTitle(title: string): BasicCard; + + /** + * Sets the subtitle for this Basic Card. + * + * @param subtitle Subtitle to show on card. + * @return Returns current constructed BasicCard. + */ + setSubtitle(subtitle: string): BasicCard; + + /** + * Sets the body text for this Basic Card. + * + * @param bodyText Body text to show on card. + * @return Returns current constructed BasicCard. + */ + setBodyText(bodyText: string): BasicCard; + + /** + * Sets the image for this Basic Card. + * + * @param url Image source URL. + * @param accessibilityText Text to replace for image for + * accessibility. + * @param width Width of the image. + * @param height Height of the image. + * @return Returns current constructed BasicCard. + */ + setImage(url: string, accessibilityText: string, width?: number, height?: number): BasicCard; + + /** + * Adds a button below card. + * + * @param text Text to show on button. + * @param url URL to open when button is selected. + * @return Returns current constructed BasicCard. + */ + addButton(text: string, url: string): BasicCard; +} + +/** + * Class for initializing and constructing Lists with chainable interface. + */ +export class List { + /** + * Constructor for List. Accepts optional List to clone, string title, or + * list of items to copy. + * + * @param list Either a list to clone, a title + * to set for a new List, or an array of OptionItem to initialize a new + * list. + */ + constructor(list?: List | string | OptionItem[]); + + /** + * Title of the list. Optional. + */ + title?: string; + + /** + * List of 2-20 items to show in this list. Required. + */ + items: OptionItem[]; + + /** + * Sets the title for this List. + * + * @param title Title to show on list. + * @return Returns current constructed List. + */ + setTitle(title: string): List; + + /** + * Adds a single item or list of items to the list. + * + * @param optionItems OptionItems to add. + * @return Returns current constructed List. + */ + addItems(optionItems: OptionItem | OptionItem[]): List; +} + +/** + * Class for initializing and constructing Carousel with chainable interface. + */ +export class Carousel { + /** + * Constructor for Carousel. Accepts optional Carousel to clone or list of + * items to copy. + * + * @param carousel Either a carousel to clone + * or an array of OptionItem to initialize a new carousel + */ + constructor(carousel?: Carousel | OptionItem[]); + + /** + * List of 2-20 items to show in this carousel. Required. + */ + items: OptionItem[]; + + /** + * Adds a single item or list of items to the carousel. + * + * @param optionItems OptionItems to add. + * @return Returns current constructed Carousel. + */ + addItems(optionItems: OptionItem | OptionItem[]): Carousel; +} + +/** + * Class for initializing and constructing Option Items with chainable interface. + */ +export class OptionItem { + /** + * Constructor for OptionItem. Accepts optional OptionItem to clone. + * + * @param optionItem Optional OptionItem to clone. + */ + constructor(optionItem?: OptionItem); + + /** + * Option info of the option item. Required. + */ + optionInfo: OptionInfo; + + /** + * Title of the option item. Required. + */ + title: string; + + /** + * Description text of the item. Optional. + */ + description?: string; + + /** + * Image to show on item. Optional. + */ + image?: Image; + + /** + * Sets the title for this Option Item. + * + * @param title Title to show on item. + * @return Returns current constructed OptionItem. + */ + setTitle(title: string): OptionItem; + + /** + * Sets the description for this Option Item. + * + * @param description Description to show on item. + * @return Returns current constructed OptionItem. + */ + setDescription(description: string): OptionItem; + + /** + * Sets the image for this Option Item. + * + * @param url Image source URL. + * @param accessibilityText Text to replace for image for + * accessibility. + * @param width Width of the image. + * @param height Height of the image. + * @return Returns current constructed OptionItem. + */ + setImage(url: string, accessibilityText: string, width?: number, height?: number): OptionItem; + + /** + * Sets the key for the OptionInfo of this Option Item. This will be returned + * as an argument in the resulting actions.intent.OPTION intent. + * + * @param key Key to uniquely identify this item. + * @return Returns current constructed OptionItem. + */ + setKey(key: string): OptionItem; + + /** + * Adds a single synonym or list of synonyms to item. + * + * @param synonyms Either a single string synonyms + * or list of synonyms to add. + * @return Returns current constructed OptionItem. + */ + addSynonyms(synonyms: string | string[]): OptionItem; +} + +/** + * Check if given text contains SSML. + * @param text Text to check. + * @return True if text contains SSML, false otherwise. + */ +export function isSsml(text: string): boolean; diff --git a/types/actions-on-google/transactions.d.ts b/types/actions-on-google/transactions.d.ts new file mode 100644 index 0000000000..8cc26165db --- /dev/null +++ b/types/actions-on-google/transactions.d.ts @@ -0,0 +1,1023 @@ +/** + * A collection of Transaction related constants, utility functions, and + * builders. + */ + +import { Image } from './response-builder'; + +/** + * Price type. + */ +export interface Price { + /** One of Transaction.PriceType. */ + type: PriceType; + amount: { + /** Currency code of price. */ + currencyCode: string; + /** Unit count of price. */ + units: number; + /** Partial unit count of price. */ + nanos?: number; + }; +} + +/** + * Order rejection info. + */ +export interface RejectionInfo { + /** One of Transaction.RejectionType. */ + type: RejectionType; + /** Reason for the order rejection. */ + reason: string; +} + +/** + * Order receipt info. + */ +export interface ReceiptInfo { + /** Action provided order ID. Used when the order has been received by the integrator. */ + confirmedActionOrderId: string; +} + +/** + * Order cancellation info. + */ +export interface CancellationInfo { + /** Reason for the cancellation. */ + reason: string; +} + +/** + * Order transit info. + */ +export interface TransitInfo { + /** UTC timestamp of the transit update. */ + updatedTime: { + /** Seconds since Unix epoch. */ + seconds: number; + /** Partial seconds since Unix epoch. */ + nanos?: number; + }; +} + +/** + * Order fulfillment info. + */ +export interface FulfillmentInfo { + /** UTC timestamp of the fulfillment update. */ + deliveryTime: { + /** Seconds since Unix epoch. */ + seconds: number; + /** Partial seconds since Unix epoch. */ + nanos?: number; + }; +} + +/** + * Order return info. + */ +export interface ReturnInfo { + /** Reason for the return. */ + reason: string; +} + +/** + * Transaction config for transactions not involving a Google provided + * payment instrument. + */ +export interface ActionPaymentTransactionConfig { + /** True if delivery address is required for the transaction. */ + deliveryAddressRequired: boolean; + /** One of Transactions.PaymentType. */ + type: PaymentType; + /** The name of the instrument displayed on receipt. For example, for card payment, could be "VISA-1234". */ + displayName: string; + customerInfoOptions?: CustomerInfoOptions; +} + +/** + * Transaction config for transactions involving a Google provided payment + * instrument. + */ +export interface GooglePaymentTransactionConfig { + /** True if delivery address is required for the transaction. */ + deliveryAddressRequired: boolean; + /** Tokenization parameters provided by payment gateway. */ + tokenizationParameters: object; + /** List of accepted card networks. Must be any number of Transactions.CardNetwork. */ + cardNetworks: CardNetwork[]; + /** True if prepaid cards are not allowed for transaction. */ + prepaidCardDisallowed: boolean; + customerInfoOptions?: CustomerInfoOptions; +} + +/** + * Customer information requested as part of the transaction + */ +export interface CustomerInfoOptions { + customerInfoProperties: string[]; +} + +/** + * Generic Location type. + */ +export interface Location { + postalAddress: { + regionCode: string; + languageCode: string; + postalCode: string; + administrativeArea: string; + locality: string; + addressLines: string[]; + recipients: string; + }; + phoneNumber: string; + notes: string; +} + +/** + * Decision and order information returned when calling getTransactionDecision(). + */ +export interface TransactionDecision { + /** One of Transactions.ConfirmationDecision. */ + userDecision: ConfirmationDecision; + checkResult: { + /** One of Transactions.ResultType. */ + resultType: ResultType; + }; + order: { + /** The proposed order used in the transaction decision. */ + finalOrder: Order; + /** Order ID assigned by Google. */ + googleOrderId: string; + /** User visible order ID set in proposed order. */ + actionOrderId: string; + orderDate: { + seconds: string; + nanos: number; + }; + paymentInfo: object; + customerInfo: { + /** Customer email. */ + email: string; + }; + }; + /** + * The delivery address if user requested. + * Will appear if userDecision is Transactions.DELIVERY_ADDRESS_UPDATED. + */ + deliveryAddress: Location; +} + +/** + * Values related to supporting transactions + */ +export const TransactionValues: { + /** List of transaction card networks available when paying with Google. */ + readonly CardNetwork: typeof CardNetwork; + /** List of possible item types. */ + readonly ItemType: typeof ItemType; + /** List of price types. */ + readonly PriceType: typeof PriceType; + /** List of possible item types. */ + readonly PaymentType: typeof PaymentType; + /** List of customer information properties that can be requested. */ + readonly CustomerInfoProperties: typeof CustomerInfoProperties; + /** List of possible order confirmation user decisions */ + readonly ConfirmationDecision: typeof ConfirmationDecision; + /** List of possible order states. */ + readonly OrderState: typeof OrderState; + /** List of possible actions to take on the order. */ + readonly OrderAction: typeof OrderAction; + /** List of possible types of order rejection. */ + readonly RejectionType: typeof RejectionType; + /** List of possible order state objects. */ + readonly OrderStateInfo: typeof OrderStateInfo; + /** List of possible order transaction requirements check result types. */ + readonly ResultType: typeof ResultType; + /** List of possible user decisions to give delivery address. */ + readonly DeliveryAddressDecision: typeof DeliveryAddressDecision; + /** List of possible order location types. */ + readonly LocationType: typeof LocationType; + /** List of possible order time types. */ + readonly TimeType: typeof TimeType; +}; + +/** + * List of transaction card networks available when paying with Google. + */ +export enum CardNetwork { + /** + * Unspecified. + */ + UNSPECIFIED, + /** + * American Express. + */ + AMEX, + /** + * Discover. + */ + DISCOVER, + /** + * Master Card. + */ + MASTERCARD, + /** + * Visa. + */ + VISA, + /** + * JCB. + */ + JCB +} + +/** + * List of possible item types. + */ +export enum ItemType { + /** + * Unspecified. + */ + UNSPECIFIED, + /** + * Regular. + */ + REGULAR, + /** + * Tax. + */ + TAX, + /** + * Discount + */ + DISCOUNT, + /** + * Gratuity + */ + GRATUITY, + /** + * Delivery + */ + DELIVERY, + /** + * Subtotal + */ + SUBTOTAL, + /** + * Fee. For everything else, there's fee. + */ + FEE +} + +/** + * List of price types. + */ +export enum PriceType { + /** + * Unknown. + */ + UNKNOWN, + /** + * Estimate. + */ + ESTIMATE, + /** + * Actual. + */ + ACTUAL +} + +/** + * List of possible item types. + */ +export enum PaymentType { + /** + * Unspecified. + */ + UNSPECIFIED, + /** + * Payment card. + */ + PAYMENT_CARD, + /** + * Bank. + */ + BANK, + /** + * Loyalty program. + */ + LOYALTY_PROGRAM, + /** + * On order fulfillment, such as cash on delivery. + */ + ON_FULFILLMENT, + /** + * Gift card. + */ + GIFT_CARD +} + +/** + * List of customer information properties that can be requested. + */ +export enum CustomerInfoProperties { + EMAIL +} + +/** + * List of possible order confirmation user decisions + */ +export enum ConfirmationDecision { + /** + * Order was approved by user. + */ + ACCEPTED, + /** + * Order was declined by user. + */ + REJECTED, + /** + * Order was not declined, but the delivery address was updated during + * confirmation. + */ + DELIVERY_ADDRESS_UPDATED, + /** + * Order was not declined, but the cart was updated during confirmation. + */ + CART_CHANGE_REQUESTED +} + +/** + * List of possible order states. + */ +export enum OrderState { + /** + * Order was rejected. + */ + REJECTED, + /** + * Order was confirmed by integrator and is active. + */ + CONFIRMED, + /** + * User cancelled the order. + */ + CANCELLED, + /** + * Order is being delivered. + */ + IN_TRANSIT, + /** + * User performed a return. + */ + RETURNED, + /** + * User received what was ordered. + */ + FULFILLED +} + +/** + * List of possible actions to take on the order. + */ +export enum OrderAction { + /** + * View details. + */ + VIEW_DETAILS, + /** + * Modify order. + */ + MODIFY, + /** + * Cancel order. + */ + CANCEL, + /** + * Return order. + */ + RETURN, + /** + * Exchange order. + */ + EXCHANGE, + /** + * Email. + */ + EMAIL, + /** + * Call. + */ + CALL, + /** + * Reorder. + */ + REORDER, + /** + * Review. + */ + REVIEW +} + +/** + * List of possible types of order rejection. + */ +export enum RejectionType { + /** + * Unknown + */ + UNKNOWN, + /** + * Payment was declined. + */ + PAYMENT_DECLINED +} + +/** + * List of possible order state objects. + */ +export enum OrderStateInfo { + /** + * Information about order rejection. Used with {@link RejectionInfo}. + */ + REJECTION, + /** + * Information about order receipt. Used with {@link ReceiptInfo}. + */ + RECEIPT, + /** + * Information about order cancellation. Used with {@link CancellationInfo}. + */ + CANCELLATION, + /** + * Information about in-transit order. Used with {@link TransitInfo}. + */ + IN_TRANSIT, + /** + * Information about order fulfillment. Used with {@link FulfillmentInfo}. + */ + FULFILLMENT, + /** + * Information about order return. Used with {@link ReturnInfo}. + */ + RETURN +} + +/** + * List of possible order transaction requirements check result types. + */ +export enum ResultType { + /** + * Unspecified. + */ + UNSPECIFIED, + /** + * OK to continue transaction. + */ + OK, + /** + * User is expected to take action, e.g. enable payments, to continue + * transaction. + */ + USER_ACTION_REQUIRED, + /** + * Transactions are not supported on current device/surface. + */ + ASSISTANT_SURFACE_NOT_SUPPORTED, + /** + * Transactions are not supported for current region/country. + */ + REGION_NOT_SUPPORTED +} + +/** + * List of possible user decisions to give delivery address. + */ +export enum DeliveryAddressDecision { + /** + * Unknown. + */ + UNKNOWN, + /** + * User granted delivery address. + */ + ACCEPTED, + /** + * User denied to give delivery address. + */ + REJECTED +} + +/** + * List of possible order location types. + */ +export enum LocationType { + /** + * Unknown. + */ + UNKNOWN, + /** + * Delivery location for an order. + */ + DELIVERY, + /** + * Business location of order provider. + */ + BUSINESS, + /** + * Origin of the order. + */ + ORIGIN, + /** + * Destination of the order. + */ + DESTINATION +} + +/** + * List of possible order time types. + */ +export enum TimeType { + /** + * Unknown. + */ + UNKNOWN, + /** + * Date of delivery for the order. + */ + DELIVERY_DATE, + /** + * Estimated Time of Arrival for order. + */ + ETA, + /** + * Reservation time. + */ + RESERVATION_SLOT +} + +/** + * Class for initializing and constructing Order with chainable interface. + */ +export class Order { + /** + * Constructor for Order. + * + * @param orderId Unique identifier for the order. + */ + constructor(orderId: string); + + /** + * ID for the order. Required. + */ + id: string; + + /** + * Cart for the order. + */ + cart?: Cart; + + /** + * Items not held in the order cart. + */ + otherItems: LineItem[]; + + /** + * Image for the order. + */ + image?: Image; + + /** + * TOS for the order. + */ + termsOfServiceUrl?: string; + + /** + * Total price for the order. + */ + totalPrice?: Price; + + /** + * Extensions for this order. Used for vertical-specific order attributes, + * like times and locations. + */ + extension?: object; + + /** + * Set the cart for this order. + * + * @param cart Cart for this order. + * @return Returns current constructed Order. + */ + setCart(cart: Cart): Order; + + /** + * Adds a single item or list of items to the non-cart items list. + * + * @param items Line Items to add. + * @return Returns current constructed Order. + */ + addOtherItems(items: LineItem | LineItem[]): Order; + + /** + * Sets the image for this order. + * + * @param url Image source URL. + * @param accessibilityText Text to replace for image for + * accessibility. + * @param width Width of the image. + * @param height Height of the image. + * @return Returns current constructed Order. + */ + setImage(url: string, accessibilityText: string, width?: number, height?: number): Order; + + /** + * Set the TOS for this order. + * + * @param url String URL of the TOS. + * @return Returns current constructed Order. + */ + setTermsOfService(url: string): Order; + + /** + * Sets the total price for this order. + * + * @param priceType One of TransactionValues.PriceType. + * @param currencyCode Currency code of price. + * @param units Unit count of price. + * @param nanos Partial unit count of price. + * @return Returns current constructed Order. + */ + setTotalPrice(priceType: PriceType, currencyCode: string, units: number, nanos?: number): Order; + + /** + * Adds an associated location to the order. Up to 2 locations can be added. + * + * @param type One of TransactionValues.LocationType. + * @param location Location to add. + * @return Returns current constructed Order. + */ + addLocation(type: LocationType, location: Location): Order; + + /** + * Sets an associated time to the order. + * + * @param type One of TransactionValues.TimeType. + * @param time Time to add. Time should be ISO 8601 representation + * of time value. Could be date, datetime, or duration. + * @return Returns current constructed Order. + */ + setTime(type: TimeType, time: string): Order; +} + +/** + * Class for initializing and constructing Cart with chainable interface. + */ +export class Cart { + /** + * Constructor for Cart. + * + * @param cartId Optional unique identifier for the cart. + */ + constructor(cartId?: string); + + /** + * ID for the cart. Optional. + */ + id?: string; + + /** + * Merchant providing the cart. + */ + merchant?: object; + + /** + * Optional notes about the cart. + */ + notes?: string; + + /** + * Items held in the order cart. + */ + lineItems: LineItem[]; + + /** + * Non-line items. + */ + otherItems: LineItem[]; + + /** + * Set the merchant for this cart. + * + * @param id Merchant ID. + * @param name Name of the merchant. + * @return Returns current constructed Cart. + */ + setMerchant(id: string, name: string): Cart; + + /** + * Set the notes for this cart. + * + * @param notes Notes. + * @return Returns current constructed Cart. + */ + setNotes(notes: string): Cart; + + /** + * Adds a single item or list of items to the cart. + * + * @param items Line Items to add. + * @return Returns current constructed Cart. + */ + addLineItems(items: LineItem | LineItem[]): Cart; + + /** + * Adds a single item or list of items to the non-items list of this cart. + * + * @param items Line Items to add. + * @return Returns current constructed Cart. + */ + addOtherItems(items: LineItem | LineItem[]): Cart; +} + +/** + * Class for initializing and constructing LineItem with chainable interface. + */ +export class LineItem { + /** + * Constructor for LineItem. + * + * @param lineItemId Unique identifier for the item. + * @param name Name of the item. + */ + constructor(lineItemId: string, name: string); + + /** + * Item ID. + */ + id: string; + + /** + * Name of the item. + */ + name: string; + + /** + * Item price. + */ + price?: Price; + + /** + * Sublines for current item. Only valid if item type is REGULAR. + */ + subLines?: Array; + + /** + * Image of the item. + */ + image?: Image; + + /** + * Type of the item. One of TransactionValues.ItemType. + */ + type?: ItemType; + + /** + * Quantity of the item. + */ + quantity?: number; + + /** + * Description for the item. + */ + description?: string; + + /** + * Offer ID for the item. + */ + offerId?: string; + + /** + * Adds a single item or list of items or notes to the sublines. Only valid + * if item type is REGULAR. + * + * @param items Sublines to add. + * @return Returns current constructed LineItem. + */ + addSublines(items: string | LineItem | Array): LineItem; + + /** + * Sets the image for this item. + * + * @param url Image source URL. + * @param accessibilityText Text to replace for image for + * accessibility. + * @param width Width of the image. + * @param height Height of the image. + * @return Returns current constructed LineItem. + */ + setImage(url: string, accessibilityText: string, width?: number, height?: number): LineItem; + + /** + * Sets the price of this item. + * + * @param priceType One of TransactionValues.PriceType. + * @param currencyCode Currency code of price. + * @param units Unit count of price. + * @param nanos Partial unit count of price. + * @return Returns current constructed LineItem. + */ + setPrice(priceType: PriceType, currencyCode: string, units: number, nanos?: number): LineItem; + + /** + * Set the type of the item. + * + * @param type Type of the item. One of TransactionValues.ItemType. + * @return Returns current constructed LineItem. + */ + setType(type: ItemType): LineItem; + + /** + * Set the quantity of the item. + * + * @param quantity Quantity of the item. + * @return Returns current constructed LineItem. + */ + setQuantity(quantity: number): LineItem; + + /** + * Set the description of the item. + * + * @param description Description of the item. + * @return Returns current constructed LineItem. + */ + setDescription(description: string): LineItem; + + /** + * Set the Offer ID of the item. + * + * @param offerId Offer ID of the item. + * @return Returns current constructed LineItem. + */ + setOfferId(offerId: string): LineItem; +} + +/** + * Class for initializing and constructing OrderUpdate with chainable interface. + */ +export class OrderUpdate { + /** + * Constructor for OrderUpdate. + * + * @param orderId Unique identifier of the order. + * @param isGoogleOrderId True if the order ID is provided by + * Google. False if the order ID is app provided. + */ + constructor(orderId: string, isGoogleOrderId: boolean); + + /** + * Google provided identifier of the order. + */ + googleOrderId?: string; + + /** + * App provided identifier of the order. + */ + actionOrderId?: string; + + /** + * State of the order. + */ + orderState?: object; + + /** + * Updates for items in the order. Mapped by item id to state or price. + */ + lineItemUpdates: object; + + /** + * UTC timestamp of the order update. + */ + updateTime?: object; + + /** + * Actionable items presented to the user to manage the order. + */ + orderManagementActions: object[]; + + /** + * Notification content to the user for the order update. + */ + userNotification?: object; + + /** + * Updated total price of the order. + */ + totalPrice?: Price; + + /** + * Set the Google provided order ID of the order. + * + * @param orderId Google provided order ID. + * @return Returns current constructed OrderUpdate. + */ + setGoogleOrderId(orderId: string): OrderUpdate; + + /** + * Set the Action provided order ID of the order. + * + * @param orderId Action provided order ID. + * @return Returns current constructed OrderUpdate. + */ + setActionOrderId(orderId: string): OrderUpdate; + + /** + * Set the state of the order. + * + * @param state One of TransactionValues.OrderState. + * @param label Label for the order state. + * @return Returns current constructed OrderUpdate. + */ + setOrderState(state: OrderState, label: string): OrderUpdate; + + /** + * Set the update time of the order. + * + * @param seconds Seconds since Unix epoch. + * @param nanos Partial time units. + * @return Returns current constructed OrderUpdate. + */ + setUpdateTime(seconds: number, nanos?: number): OrderUpdate; + + /** + * Set the user notification content of the order update. + * + * @param title Title of the notification. + * @param text Text of the notification. + * @return Returns current constructed OrderUpdate. + */ + setUserNotification(title: string, text: object): OrderUpdate; + + /** + * Sets the total price for this order. + * + * @param priceType One of TransactionValues.PriceType. + * @param currencyCode Currency code of price. + * @param units Unit count of price. + * @param nanos Partial unit count of price. + * @return Returns current constructed OrderUpdate. + */ + setTotalPrice(priceType: PriceType, currencyCode: string, units: number, nanos?: number): OrderUpdate; + + /** + * Adds an actionable item for the user to manage the order. + * + * @param type One of TransactionValues.OrderActions. + * @param label Button label. + * @param url URL to open when button is clicked. + * @return Returns current constructed OrderUpdate. + */ + addOrderManagementAction(type: OrderAction, label: string, url: string): OrderUpdate; + + /** + * Adds a single price update for a particular line item in the order. + * + * @param itemId Line item ID for the order item updated. + * @param priceType One of TransactionValues.PriceType. + * @param currencyCode Currency code of new price. + * @param units Unit count of new price. + * @param nanos Partial unit count of new price. + * @param reason Reason for the price change. Required unless a + * reason for this line item change was already declared in + * addLineItemStateUpdate. + * @return Returns current constructed OrderUpdate. + */ + addLineItemPriceUpdate(itemId: string, priceType: PriceType, currencyCode: string, units: number, nanos?: number, reason?: string): OrderUpdate; + + /** + * Adds a single state update for a particular line item in the order. + * + * @param itemId Line item ID for the order item updated. + * @param state One of TransactionValues.OrderState. + * @param label Label for the new item state. + * @param reason Reason for the price change. This will overwrite + * any reason given in addLineitemPriceUpdate. + * @return Returns current constructed OrderUpdate. + */ + addLineItemStateUpdate(itemId: string, state: OrderState, label: string, reason?: string): OrderUpdate; + + /** + * Sets some extra information about the order. Takes an order update info + * type, and any accompanying data. This should only be called once per + * order update. + * + * @param type One of TransactionValues.OrderStateInfo. + * @param data Proper Object matching the data necessary for the info + * type. For instance, for the TransactionValues.OrderStateInfo.RECEIPT info + * type, use the {@link ReceiptInfo} data type. + * @return Returns current constructed OrderUpdate. + */ + setInfo(type: string, data: object): OrderUpdate; +} diff --git a/types/actions-on-google/tsconfig.json b/types/actions-on-google/tsconfig.json new file mode 100644 index 0000000000..6682b5c194 --- /dev/null +++ b/types/actions-on-google/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "assistant-app.d.ts", + "actions-sdk-app.d.ts", + "dialogflow-app.d.ts", + "response-builder.d.ts", + "transactions.d.ts", + "actions-on-google-tests.ts" + ] +} diff --git a/types/actions-on-google/tslint.json b/types/actions-on-google/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/actions-on-google/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }