Actions on Google components

Actions on Google is compatible with not only phones, but also smart displays and speakers. For your bot to work on these platforms, you'll need to use special Meya component properties. There are also some special bot design decisions to consider. These properties and design options are summarized on this page.

Suggestion chips

In Actions on Google, buttons and suggestions are displayed as suggestion chips. Specifically, these components use suggestion chips:

  • meya.text_buttons
  • meya.text_suggestions
  • meya.image_buttons
  • meya.image_suggestions
  • meya.card
  • meya.cards
  • meya.list
  • meya.table

🚧

Start buttons are not supported in Actions on Google.

Google limits the number of link buttons that can appear on a card depending on the card type and surface type (e.g. smart display). Review the component documentation below for more detail.

🚧

In addition, there can never be more than eight suggestion chips on a card. Each chip must contain no more than 25 characters.

meya.card

Supported surfaces: phone, smart display

A basic card designed to present key information to users in a concise manner. They can contain text, an image, and suggestion chips.

PropertyDescription
titleThe title of the cardOptional
subtitleA one-line string. Extra characters are truncated.Optional This property is only valid in standalone (meya.card) cards, not when the card is part of a carousel (meya.cards).
textThe text to output.

This text must not include a URL.

The text may take up to 10 lines if an image is present, or 15 lines without an image. This is roughtly 500-750 characters. Extra characters will be truncated.
Required if there is no image_url.
image_urlThe URL of the image to output. GIFs are allowed.Required if there is no text.
accessibility_textA description of the image.Optional Default: [image]
image_display_optionsOne of DEFAULT, WHITE, or CROPPED.Optional Default: CROPPED
buttonsAn array of buttons.Optional
blockTreat any non-button press as a user input. This will trigger the no_match action, so you must implement the transition as you would with an input.Optional Default: false
outputThe key used to store the data for subsequent steps in the flow.Optional Default: value
scopeWhere to store the data. One of flow, user, bot.Optional Default: flow
footerA single line of text that appears under the main text.Optional

This property is only valid when the card is an element in a meya.cards component.
expect_user_actionTells the Actions on Google device to expect a response from the user.Optional Default: true
passthruAutomatically advance without waiting for the user's response.Optional Default: false

Important details

If you wish to display a card without any buttons, you'll need to ensure passthru is true and expect_user_action is false. See the Without buttons code example below.

If you do not specify image_url you must specify text. Likewise, if you do not specify text you must specify image_url.

A card may have at most one link button. Without a link button, the card will have no interaction capabilities.

Here are some examples:

# supported: phone, smart display (partial)
states:
    # meya.text is required before meya.card
    basic_card_0:
        component: meya.text
        properties:
            text: This is a basic card example.
    basic_card_1:
        component: meya.card
        properties:
            title: Basic card title
            subtitle: Basic card subtitle
            text: "Formatted text goes here"
            image_url: "https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg"
            output: button_click
            # buttons are optional
            buttons:
                # rendered as suggestions
                - text: transition
                  action: button_action
                  data:
                    foo: bar
                # supported: phone
                # rendered in card
                - text: link
                  url: https://meya.ai
                - text: start
                  action: subflow
        transitions:
            button_action: basic_card_2
            subflow: basic_card_3
    basic_card_2:
        component: meya.text
        properties:
            text: You clicked {{ flow.button_click }}. Your data is {{ flow.foo }}
        return: true
    basic_card_3:
        flow: subflow
        return: true
component: meya.card
properties:
  title: "Basic card title"
  subtitle: "Basic card subtitle"
  text: "Formatted text goes here"
  image_url: "http://bit.ly/1NPO0xx"
  accessibility_text: "A picture of an elephant"
  image_display_options: CROPPED
  passthru: true
  expect_user_action: false

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import Card, Button


class HelloWorld(Component):

    def start(self):
        # Max of one button. Button must be a link, not transition.
        card = Card(
            title='My Title',
            subtitle='My subtitle',
            text='Some text',
            image_url='https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg',
            accessibility_text='An image',
            buttons=[
                Button(
                    text='Open image',
                    url='https://upload.wikimedia.org/wikipedia/commons/7/71'
                        '/2010-kodiak-bear-1.jpg'),
                Button(text='Done', action='next')
            ]
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is a basic card...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages)
states:
    first:
        component: py_card
        properties:
            expect_user_action: true # Must be true
    done:
        component: meya.text
        properties:
            text: "All done!"
1125

A card on a smart display.

418

A card on a smartphone.

meya.cards

Supported surfaces: phone.

A browsing carousel is a rich response that allows users to scroll vertically and select a tile in a collection. Browsing carousels are designed specifically for web content by opening the selected tile in a web browser. The browsing carousel will also persist on the user's surface for browsing later.

📘

The meya.table and meya.list components can also be used to display a collection of items.

🚧

A meya.text component must be placed immediately before a meya.cards component.

PropertyDescription
elementsA list of meya.card components.Required
passthruAutomatically advance without waiting for the user's response.Optional Default: false
blockTreat any non-button press as a user input. This will trigger the no_match action, so you must implement the transition as you would with an input.Optional Default: false
outputThe key used to store the data for subsequent steps in the flow.Optional Default: value
scopeWhere to store the data. One of flow, user, bot.Optional Default: false

🚧

All cards in the carousel must have the same components. For example, if one card has an image, all of the cards must have an image.

If you wish to display cards without any buttons, you'll need to ensure passthru is true and expect_user_action is false. See the Without buttons code example below.

# supported: phone
states:
    # meya.text is required before meya.cards
    browsing_carousel_0:
        component: meya.text
        properties:
            text: This is a browse carousel example.
    browsing_carousel_1:
        component: meya.cards
        properties:
            passthru: true
            expect_user_action: false
            output: button_click
            elements:
                - title: "Title of item 1"
                  text: "Description of item 1"
                  item_url: "https://www.google.com/"
                  image_url: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/2560px-Google_%22G%22_Logo.svg.png"
                  footer: "Item 1 footer"
                  buttons:
                    - text: Link
                      url: "https://en.wikipedia.org"
                    - text: Transition1
                      action: next
                - title: "Google Assistant"
                  text: "Google Assistant on Android and iOS"
                  item_url: "https://meya.ai/"
                  image_url: "https://upload.wikimedia.org/wikipedia/en/2/2c/Google_Actions_Logo.png"
                  footer: "Item 2 footer"
                  buttons:
                    - text: Transition2
                      action: next
    browsing_carousel_2:
        component: meya.text
        properties:
            text: The next state {{ flow.button_click }}
component: meya.cards
properties:
    output: button_click
    passthru: true
    expect_user_action: false
    elements:
        - title: "Basic card title"
          text: "Formatted text goes here"
          image_url: "http://i.imgur.com/7Z9IX5W.jpg"
          accessibility_text: "An African elephant"
          footer: "This is some footer text"
        - title: "Basic card title"
          text: "Formatted text goes here"
          image_url: "http://i.imgur.com/w5qzZ7I.jpg"
          accessibility_text: "An Asian elephant"
          footer: "This is some footer text"

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import Card, Cards, Button


class HelloWorld(Component):

    def start(self):
        cards = Cards(
            elements=[
                Card(
                    title='My Title 1',
                    subtitle='My subtitle 1',
                    text='Some text 1',
                    item_url='https://en.wikipedia.org/wiki/African_elephant',
                    footer='Item 1 footer',
                    image_url='http://i.imgur.com/7Z9IX5W.jpg',
                    accessibility_text='An image',
                    buttons=[Button(text='Cool!', action='next')]
                ),
                Card(
                    title='My Title 2',
                    subtitle='My subtitle 2',
                    text='Some text 2',
                    item_url='https://en.wikipedia.org/wiki/Asian_elephant',
                    footer='Item 2 footer',
                    image_url='http://i.imgur.com/w5qzZ7I.jpg',
                    accessibility_text='An image',
                    buttons=[Button(text='Awesome!', action='next')]
                )
            ]
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is a multi card...'),
            self.create_message(card=cards)
        ]
        return self.respond(messages=messages)
states:
    first:
        component: py_cards
        properties:
            expect_user_action: true
        transitions:
            next: done
    done:
        component: meya.text
        properties:
            text: "All done!"
436

A browsing carousel on a smartphone.

meya.image

Supported surfaces: phone, smart display.

Displays an image specified by the image_url.

PropertyDescription
image_urlThe URL of the image to display.Required
accessibility_textA description of the image.Optional Default: [image]
image_display_optionsOne of DEFAULT, WHITE, or CROPPED.Optional Default: CROPPED

Here is an example image card.

component: meya.image
properties:
    image_url: "https://upload.wikimedia.org/wikipedia/commons/c/c1/Lionel_Messi_20180626.jpg"
    accessibility_text: "Messi photo"
    image_display_options: "WHITE"

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import Image


class HelloWorld(Component):

    def start(self):
        # Max of one button. Button must be a link, not transition.
        card = Image(
            image_url='https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg',
            accessibility_text='An image'
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is an image card...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages, action='next')
states:
    first:
        component: py_image
    done:
        component: meya.text
        properties:
            text: "All done!"
418

meya.image_buttons

Supported surfaces: phone, smart display.

Displays an image and suggestions chips.

PropertyDescription
image_urlThe URL of the image to output.Required
accessibility_textA description of the image.Optional Default: [image]
image_display_optionsOne of DEFAULT, WHITE, or CROPPED.Optional Default: CROPPED
buttonsA list of buttons displayed as suggestion chips.Optional
passthruAutomatically advance without waiting for the user's response.Optional Default: false
expect_user_actionTells the Actions on Google device to expect a response from the user.Optional Default: true

Here's an example of an image card with buttons.

basic_card_1:
    component: meya.image_buttons
    properties:
        image_url: "https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg"
        accessibility_text: "bear photo"
        image_display_options: "CROPPED"
        output: button_click
        buttons:
            - text: transition
              action: button_action
              data:
                foo: bar
            - text: link
              url: https://meya.ai
            - text: start
              action: subflow
    transitions:
        button_action: basic_card_2
        subflow: basic_card_3

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import ImageWithButtons, Button


class HelloWorld(Component):

    def start(self):
        # Max of one button. Button must be a link, not transition.
        card = ImageWithButtons(
            image_url='https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg',
            accessibility_text='An image',
            passthru=False,
            buttons=[
                Button(text='Done', action='next'),
                Button(
                    text='Link',
                    url='https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg'
                ),
            ]
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is an image card with buttons...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages)
states:
    first:
        component: py_imagebuttons
        properties:
            expect_user_action: true # Must be true
        transitions:
            next: done
    done:
        component: meya.text
        properties:
            text: "All done!"
1125

An image with buttons on a smart display.

meya.image_suggestions

Supported surfaces: phone, smart display.

Displays an image and suggestions chips.

PropertyDescription
image_urlThe URL of the image to output.Required
accessibility_textA description of the image.Optional Default: [image]
image_display_optionsOne of DEFAULT, WHITE, or CROPPED.Optional Default: CROPPED
suggestionsA list of suggestions rendered as suggestion chips.Optional
passthruAutomatically advance without waiting for the user's response.Optional Default: false
expect_user_actionTells the Actions on Google device to expect a response from the user.Optional Default: true

Here's an example of an image card with suggestions.

basic_card_1:
    component: meya.image_buttons
    properties:
        image_url: "https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg"
        accessibility_text: "bear photo"
        image_display_options: "CROPPED"
        output: button_click
        suggestions:
            - suggestion_1
            - suggestion_2
    transitions:
        suggestion_1: text_suggestions_1
        suggestion_2: text_suggestions_2
421

An image with suggestions on a phone.

1118

An image with suggestions on a smart display.

meya.text_buttons

Supported surfaces: phone, smart display.

Displays text and suggestions chips.

PropertyDescription
textThe text to output.Required if there is no image_url.
buttonsA list of buttons rendered as suggestion chips.Required
passthruAutomatically advance without waiting for the user's response.Optional Default: false
blockTreat any non-button press as a user input. This will trigger the no_match action, so you must implement the transition as you would with an input.Optional Default: false
outputThe key used to store the data for subsequent steps in the flow.Optional Default: value
scopeWhere to store the data. One of flow, user, bot.Optional Default: flow

Here is an example of a text card with buttons.

text_buttons_0:
    component: meya.text_buttons
    properties:
        text: text buttons test
        output: button_click
        buttons:
            - text: transition
              action: next
            - text: transition2
              action: next
            - text: link
              url: https://meya.ai

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import TextWithButtons, Button


class HelloWorld(Component):

    def start(self):
        # Max of one button. Button must be a link, not transition.
        card = TextWithButtons(
            text='Some text',
            passthru=False,
            buttons=[
                Button(text='Done', action='next'),
                Button(
                    text='Link',
                    url='https://upload.wikimedia.org/wikipedia/commons/7/71/2010-kodiak-bear-1.jpg'
                ),
            ]
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is a text card with buttons...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages)
states:
    first:
        component: py_textbuttons
        properties:
            expect_user_action: true # Must be true
        transitions:
            next: done
    done:
        component: meya.text
        properties:
            text: "All done!"
1122

A text card with buttons.

meya.text_suggestions

Supported surfaces: phone, smart display.

Displays text and suggestions chips.

PropertyDescription
textThe text to display.Required if there is no image_url.
suggestionsA list of suggestions displayed as suggestions chips.Required

Here is an example of a text card with suggestions.

# supported: phone, smart display
triggers:
  - type: meya.keyword
    properties:
        ignorecase: true
        keyword: text_suggestions
states:
    text_suggestions_0:
        component: meya.text_suggestions
        properties:
            text: text suggestions test
            suggestions:
                - suggestion_1
                - suggestion_2
        transitions:
            suggestion_1: text_suggestions_1
            suggestion_2: text_suggestions_2
    text_suggestions_1:
        component: meya.text
        properties:
            text: Suggestion 1
        return: true
    text_suggestions_2:
        component: meya.text
        properties:
            text: Suggestion 2
        return: true
1124

Text suggestions on a smart display.

meya.list

Supported surfaces: phone, smart display. For speakers, the list/carousel card itself will be skipped.

The meya.list component has two modes: list, and carousel.

List

The single-select list presents the user with a vertical list of multiple items and allows the user to select a single one. Selecting an item from the list generates a user query (chat bubble) containing the title of the list item.

Carousel

The carousel scrolls horizontally and allows for selecting one item. Compared to the list selector, it has large tiles-allowing for richer content. The tiles that make up a carousel are similar to the basic card with an image. Selecting an item from the carousel will generate a chat bubble as the response just like list mode.

📘

The meya.table and meya.cards components can also be used to display a collection of items.

PropertyDescription
titleA title for the entire list. Must be no more than 1 line. Extra characters will be truncated.

Not used if carousel is true.
Optional
carouselIf true, display the card as a carousel.
If false, display the card as a list.
Optional Default: false
outputA variable name where the item click will be stored.Optional Default: value
scopeOne of bot, user, flow.Optional Default: flow
elementsA list of items. See the table below for more details.Required
buttonsA list of buttons displayed as suggestion chips.Optional

Each entry in the list has the following properties.

PropertyDescription
titleThe title of the item must be unique and no more than one line. Extra characters will be truncated.Required
subtitleA description of the item. It must be no more than 2 lines. Extra characters will be truncated.Optional
image_urlAn image of the item.Optional
accessibility_textA description of the image.Optional Default: [image]
buttonsA list of buttons displayed as suggestion chips.

Although defined as a list of buttons, the list may contain only one button. The button must be a transition button.
Optional

Here are two examples of a list and a carousel.

list_1:
    component: meya.list
    properties:
        title: "My list"
        output: option_selected
        elements:
            - title: "Title 1"
              subtitle: "Subtitle 1"
              image_url: "https://image.shutterstock.com/image-photo/robotic-artificial-intelligence-robo-advisor-600w-664114771.jpg"
              # only 1 transition button allowed
              buttons:
                - text: "Button 1"
                  action: selection
            - title: "Title 2"
              subtitle: "Subtitle 2"
              image_url: "https://image.shutterstock.com/image-photo/moscow-russia-october-16-2017-600w-754222927.jpg"
              buttons:
                - text: "Button 2"
                  action: selection
            - title: "Title 3"
              subtitle: "Subtitle 3"
              image_url: "https://image.shutterstock.com/image-photo/concept-artificial-brain-robot-composed-600w-261598403.jpg"
              buttons:
                - text: "Button 3"
                  action: selection
        # optional suggestion chips
        buttons:
            - text: "A transition button"
              action: suggestion
            - text: "A link button"
              url: https://meya.ai
    transitions:
        suggestion: list_2
        selection: list_3
list_1:
    component: meya.list
    properties:
        carousel: true
        output: option_selected
        elements:
            - title: "Title 1"
              subtitle: "Subtitle 1"
              image_url: "https://image.shutterstock.com/image-photo/robotic-artificial-intelligence-robo-advisor-600w-664114771.jpg"
              # only 1 transition button per item is allowed
              buttons:
                - text: "Button 1"
                  action: selection
            - title: "Title 2"
              subtitle: "Subtitle 2"
              image_url: "https://image.shutterstock.com/image-photo/moscow-russia-october-16-2017-600w-754222927.jpg"
              buttons:
                - text: "Button 2"
                  action: selection
            - title: "Title 3"
              subtitle: "Subtitle 3"
              image_url: "https://image.shutterstock.com/image-photo/concept-artificial-brain-robot-composed-600w-261598403.jpg"
              buttons:
                - text: "Button 3"
                  action: selection
        # optional suggestion chips
        buttons:
            - text: "A transition button"
              action: suggestion
            - text: "A link button"
              url: https://meya.ai
    transitions:
        suggestion: list_2
        selection: list_3
# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import List, Element, Button


class HelloWorld(Component):

    def start(self):
        elements = [
            Element(
                title="Robot 1", 
                subtitle="It's a hand", 
                image_url="https://image.shutterstock.com/image-photo/robotic-artificial-intelligence-robo-advisor-600w-664114771.jpg",
                buttons=[Button(text="robot1", action="next")]
            ),
            Element(
                title="Robot 2", 
                subtitle="It's a hand", 
                image_url="https://image.shutterstock.com/image-photo/moscow-russia-october-16-2017-600w-754222927.jpg",
                buttons=[Button(text="robot2", action="next")]
            ),
            Element(
                title="Robot 3", 
                subtitle="It's a hand", 
                image_url="https://image.shutterstock.com/image-photo/concept-artificial-brain-robot-composed-600w-261598403.jpg",
                buttons=[Button(text="robot3", action="next")]
            ),
        ]
        
        card = List(
            title="mytitle",
            elements=elements,
            top_element_style="compact",
            buttons=[Button(text="done", action="next")]
        )
        
        # Note that a text message must precede a list.
        messages = [
            self.create_message(text='Here is a list...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages)
419

A list on a smartphone.

1137

A list on a smart display.

1124

A carousel on a smart display.

meya.table

Supported surfaces: phone, smart display. For speakers, the table card itself will be skipped.

Table cards allow you to display tabular data in your response (for example, sports standings, election results, and flights). You can define columns and rows (up to 3 each) that the Assistant is required to show in your table card. You can also define additional columns and rows along with their prioritization.

📘

Table cells display static data and are non-interactive. You may add suggestion chips to the table itself to create interactivity.

📘

The meya.cards and meya.list components can also be used to display a collection of items.

PropertyDescription
titleThe title of the table.Optional
subtitleThe subtitle of the table.Optional
image_urlAn image associated with the table.Optional
accessibility_textA description of the image.Optional Default: [image]
buttonsA list of buttons displayed as suggestion chips.Optional
columnsA list of column headers and other column attributes.

See column properties below.
Optional
rowsA list of cells.

See cell properties below.
Required
passthruAutomatically advance without waiting for the user's response.Optional Default: false
expect_user_actionTells the Actions on Google device to expect a response from the user.Optional Default: true

Each entry in columns has the following properties.

PropertyDescription
headerThe header text for the column.Optional
alignmentOne of CENTER, LEADING, or TRAILING.Optional Default: LEADING

Each entry in rows has the following properties.

PropertyDescription
cellsA list of cells in the row.Required
dividerWhether or not a dividing line should appear after the row.Optional Default: false

Each entry in cells has the following property.

PropertyDescription
textThe text to display.Required

If you wish to display a table without any buttons, you'll need to ensure passthru is true and expect_user_action is false. See the Without buttons code example below.

table_1:
    component: meya.table
    properties:
        title: "Table title"
        subtitle: "Table subtitle"   # title must be set first
        image_url: "https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png"
        accessibility_text: "Alt Text"
        columns:
            - header: "header 1"
            - header: "header 2"
              alignment: "CENTER"
            - header: "header 3"
              alignment: "TRAILING"
        rows:
            - cells:
                - text: "row 1 item 1"
                - text: "row 1 item 2"
                - text: "row 1 item 3"
            - cells:
                - text: "row 2 item 1"
                - text: "row 2 item 2"
                - text: "row 2 item 3"
              divider: true
            - cells:
                - text: "row 3 item 1"
                - text: "row 3 item 2"
                - text: "row 4 item 3"
              divider: false
        buttons:
            # appears as a suggestion chip
            - text: transition
              action: next
              data:
                foo: bar
            # appears as link button on tablet
            # supported: phone
            - text: link
              url: https://meya.ai
table_1:
    component: meya.table
    properties:
        title: "Table title"
        subtitle: "Table subtitle"   # title must be set first
        image_url: "https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png"
        accessibility_text: "Alt Text"
        columns:
            - header: "header 1"
            - header: "header 2"
              alignment: "CENTER" # CENTER, LEADING (default), TRAILING
            - header: "header 3"
              alignment: "TRAILING"
        rows:
            - cells:
                - text: "row 1 item 1"
                - text: "row 1 item 2"
                - text: "row 1 item 3"
            - cells:
                - text: "row 2 item 1"
                - text: "row 2 item 2"
                - text: "row 2 item 3"
              divider: true
            - cells:
                - text: "row 3 item 1"
                - text: "row 3 item 2"
                - text: "row 4 item 3"
              divider: false
        passthru: true
        expect_user_action: false

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import Card, Button


class HelloWorld(Component):

    def start(self):
        card = Card(
            title='Table Title',
            subtitle='Table subtitle',
            is_table=True,
            passthru=False,
            columns=[
                {'header': 'Header 1'},
                {'header': 'Header 2', 'alignment': 'CENTER'},
                {'header': 'Header 3', 'alignment': 'TRAILING'},
            ],
            rows=[
                {
                    'cells': [
                        {'text': 'row 1 item 1'},
                        {'text': 'row 1 item 2'},
                        {'text': 'row 1 item 3'},
                    ]
                },
                {
                    'cells': [
                        {'text': 'row 1 item 1'},
                        {'text': 'row 1 item 2'},
                        {'text': 'row 1 item 3'},
                    ],
                    'divider': True
                },
                {
                    'cells': [
                        {'text': 'row 1 item 1'},
                        {'text': 'row 1 item 2'},
                        {'text': 'row 1 item 3'},
                    ],
                    'divider': False
                },
            ],
            # Only one button is allowed.
            buttons=[Button(text='Done', action='next')]
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is a basic card...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages)
states:
    first:
        component: py_table
        properties:
            expect_user_action: true # Must be true
        transitions:
            next: done
    done:
        component: meya.text
        properties:
            text: "All done!"
416

A table with a suggestion chip on a phone.

1126

A table with a suggestion chip on a smart display.

meya.audio

Supported surfaces: phone, speaker, smart display.

Displays audio content. The card contains audio controls (e.g. play, pause, rewind).

PropertyDescription
urlThe URL of the audio to play. The URL must use HTTPS. The audio file must be an .mp3.Required
nameThe name of the audio file.Optional
descriptionA description of the audio file.Optional
icon_urlThe image should be 36 x 36 px. Larger images are resized to fit. GIFs are allowed.Optional
accessibility_textA description of the icon image.Optional Default: [image]

Here's an example of an audio card.

states:
    # meya.text required before meya.audio
    audio_0:
        component: meya.text
        properties:
            text: "This is a media response example."
    audio_1:
        component: meya.audio
        properties:
            url: "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3"
            accessibility_text: "Ocean view"
            icon_url: "https://storage.googleapis.com/automotive-media/album_art.jpg"
            description: "A funky Jazz tune"
            name: "Jazz in Paris"

Here is an example of how to construct a card programmatically.

# -*- coding: utf-8 -*-
from meya import Component
from meya.cards import Audio


class HelloWorld(Component):

    def start(self):
        card = Audio(
            url='https://storage.googleapis.com/automotive-media'
                '/Jazz_In_Paris.mp3',
            accessibility_text='Ocean view',
            icon_url='https://storage.googleapis.com/automotive-media'
                     '/album_art.jpg',
            description='A funky Jazz tune',
            name='Jazz in Paris'
        )

        # A basic text message is required before a card.
        messages = [
            self.create_message(text='Here is an audio card...'),
            self.create_message(card=card)
        ]
        return self.respond(messages=messages, action='next')
states:
    first:
        component: py_audio

🚧

The meya.audio component must be preceded by a meya.text component.

1126

An audio card.

meya.input_location

Supported surfaces: phone, speaker, smart display.

Have the Google Assistant ask the user for permission to access their coarse or precise location.

Requesting coarse permission will add the following fields to the user's user DB:

  • city
  • postal_code

Requesting precise permission will add the following fields to the user's user DB:

  • city
  • state
  • country
  • postal_code
  • lat
  • lng
  • timezone

Meya uses a standard naming convention for location properties. Location data returned from Google is re-mapped to conform to this standard. For example, zipCode is mapped to postal_code, coordinates.latitude is mapped to lat. The raw location data returned by Google can be found in its unaltered form at user._location.

PropertyDescription
textThe text to display to the user.
speechText to speak to the user. This field also accepts SSML markup to customize pronunciation.Optional
precisionOne of precise or coarse. Determines if the DEVICE_COARSE_LOCATION or DEVICE_PRECISE_LOCATION permission is requested.Optional. Default: true
opt_contextThe beginning of a phrase the Google Assistant will display to the user. It should explain why you need the user's location.

The phrase has this format: <opt_context>, I'll just need to get your current location from Google. Is that ok?

Note that only the beginning of the phrase can be altered, so it's important to set opt_context to something that will make sense within the whole sentence.
Optional. Default: To know your location
outputThe key used to store the data entered by the user.Default: value
confidenceThe assumed confidence when matching.Optional. Default: 0.95
require_matchIf false, the flow will return an action no_match that you can use to transition to another state.Optional. Default: true
error_messageA message sent to the user if the input was not a location.

Error messages are only shown if require_match is true.

Note: the Google Assistant will handle non-location responses by itself and reprompt the user. You only need to set an error_message if the bot will be connected to other integrations as well.
Optional. Default: Sorry, I don't understand. Try again.
encryptIf sensitive, will encrypt the input in the bot logs as well as at the /messages API endpoint.Optional. Default: None

The data is stored to the user scope DB. You can access the information found in the table below.

DatastoreDescriptionPermission required
user.postal_codeThe postal code or zip code of the location.coarse or precise
user.cityThe city of the location.coarse or precise
user.countryThe country of the location.precise
user.latThe latitude of the location.precise
user.lngThe longitude of the location.precise
user.timezoneThe timezone of the location.precise
user.stateThe state or province of the location.precise

Here are three examples of a meya.input_location component.

states:
    # For Actions on Google, it's recommended to have `require_match` set to
    # `false` so that you can handle the case where the user declines to give 
    # location permssions.
    input_location_state:
        component: meya.input_location
        properties:
            text: "Where are you?"
            require_match: false
            precision: coarse
            opt_context: "To recommend stores near you" # Optional
        transitions:
            next: done
            no_match: no_match
    no_match:
        component: meya.text
        properties:
            text: "I couldn't find your location."
        return: true
    done:
        component: meya.text
        properties:
            text: "Your zip code/postal code is: {{ user.postal_code }}"
states:
    # For Actions on Google, it's recommended to have `require_match` set to
    # `false` so that you can handle the case where the user declines to give 
    # location permssions.
    input_location_state:
        component: meya.input_location
        properties:
            text: "Where are you?"
            require_match: false
            # precision: precise # Optional, since default is `precise`
            opt_context: "To ship your order" # Optional
        transitions:
            next: done
            no_match: no_match
    no_match:
        component: meya.text
        properties:
            text: "I couldn't find your location."
        return: true
    done:
        component: meya.text
        properties:
            text: "You lat/lng is ({{ user.lat }}, {{ user.lng }})"
states:
    # When `require_match` is set to `true` (which is the default), the bot will
    # reply with a standard error message instead of accepting a `no_match`
    # intent.
    input_location_state:
        component: meya.input_location
        properties:
            text: "Where are you?"
            precision: precise # Optional, since default is `precise`
            opt_context: "To ship your order" # Optional
    # The user will only reach this state if they enter a valid location.
    done:
        component: meya.text
        properties:
            text: " Your lat/lng is: ({{ user.lat }}, {{ user.lng }})"