/** * Copyright 2018 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as Api from '../../api/v2' import { SimpleResponse } from './simple' import { BasicCard, Table } from './card' import { BrowseCarousel } from './browse' import { MediaResponse } from './media' import { OrderUpdate } from './order' import { LinkOutSuggestion } from './linkout' import { Suggestions } from './suggestion' import { HtmlResponse } from './html' /** @public */ export type RichResponseItem = string | SimpleResponse | BasicCard | Table | BrowseCarousel | MediaResponse | OrderUpdate | LinkOutSuggestion | HtmlResponse | Api.GoogleActionsV2RichResponseItem /** @public */ export interface RichResponseOptions { /** * Ordered list of either SimpleResponse objects or BasicCard objects. * First item must be SimpleResponse. There can be at most one card. * @public */ items?: RichResponseItem[] /** * Ordered list of text suggestions to display. Optional. * @public */ suggestions?: string[] | Suggestions /** * Link Out Suggestion chip for this rich response. Optional. * @public */ link?: Api.GoogleActionsV2UiElementsLinkOutSuggestion } const isOptions = ( options: RichResponseOptions | RichResponseItem, ): options is RichResponseOptions => { const test = options as RichResponseOptions return typeof test.link === 'object' || Array.isArray(test.items) || Array.isArray(test.suggestions) || test.suggestions instanceof Suggestions } /** * Class for initializing and constructing Rich Responses with chainable interface. * @public */ export interface RichResponse extends Api.GoogleActionsV2RichResponse { } export class RichResponse implements Api.GoogleActionsV2RichResponse { /** * @param options RichResponse options * @public */ constructor(options: RichResponseOptions) /** * @param items RichResponse items * @public */ constructor(items: RichResponseItem[]) /** * @param items RichResponse items * @public */ constructor(...items: RichResponseItem[]) constructor( options?: RichResponseOptions | RichResponseItem[] | RichResponseItem, ...items: RichResponseItem[] ) { this.items = [] if (!options) { return } if (Array.isArray(options)) { this.add(...options) return } if (isOptions(options)) { if (options.items) { this.add(...options.items) } const { link, suggestions } = options this.linkOutSuggestion = link if (suggestions) { if (Array.isArray(suggestions)) { this.addSuggestion(...suggestions) } else { this.addSuggestion(suggestions) } } return } this.add(options, ...items) } /** * Add a RichResponse item * @public */ add(...items: RichResponseItem[]) { const raw = this.items! for (const item of items) { if (typeof item === 'string') { this.add(new SimpleResponse(item)) continue } if (item instanceof LinkOutSuggestion) { this.linkOutSuggestion = item continue } if (item instanceof SimpleResponse) { raw.push({ simpleResponse: item }) continue } if (item instanceof BasicCard) { raw.push({ basicCard: item }) continue } if (item instanceof Table) { raw.push({ tableCard: item }) continue } if (item instanceof BrowseCarousel) { raw.push({ carouselBrowse: item }) continue } if (item instanceof MediaResponse) { raw.push({ mediaResponse: item }) continue } if (item instanceof OrderUpdate) { raw.push({ structuredResponse: { orderUpdate: item } }) continue } if (item instanceof HtmlResponse) { raw.push({ htmlResponse: item }) continue } raw.push(item) } return this } /** * Adds a single suggestion or list of suggestions to list of items. * @public */ addSuggestion(...suggestions: (string | Suggestions)[]) { if (!this.suggestions) { this.suggestions = [] } for (const suggestion of suggestions) { if (typeof suggestion === 'string') { this.addSuggestion(new Suggestions(suggestion)) continue } this.suggestions.push(...suggestion.suggestions) } return this } }