In addition to text messages, Google Chat apps can create card messages when using app authentication. Cards support a defined layout, interactive UI elements like buttons, and rich media like images.
Use card messages to do the following:
- Present detailed information
- Gather information from users
- Guide users to take a next step
This guide describes how to create card messages synchronously (a realtime response to a Google Chat event, like receiving a message from a user or getting added to a space) and asynchronously (sending a message from the app to a space or user without a prompt using the Google Chat API).
Prerequisites
To create the card messages in this guide, you need the following:
Node.js
- A Google Workspace account with access to Google Chat.
- A Chat app. To build a Chat app, follow this quickstart.
Note: The Node.js code samples in this guide are written to run as a Google Cloud Function.
Python
- A Google Workspace account with access to Google Chat.
- A Chat app. To build a Chat app, follow this quickstart.
Note: The Python code samples in this guide are written to run as a Google Cloud Function, using Python 3.9.
Apps Script
- A Google Workspace account with access to Google Chat.
- A Chat app. To build a Chat app, follow this quickstart.
Anatomy of a card message
Each card, whether it is a dialog or a message, is a JSON object on the
spaces.messages
resource
in the Google Chat API.
The card JSON object consists of the following:
- An array called
cardsV2[]
which contains one or moreCardWithId
objects. - A
cardId
, used to identify the card and scoped within a given message. (Cards in different messages can have the same ID.) A
card
object, which consists of the following:- A
header
object that specifies things like a title, subtitle, and avatar-style image. - One or more
section
objects that each contain at least one widget. - One or more
widget
objects. Each widget is a composite object that can represent text, images, buttons, and other object types.
- A
As an example, observe the header
, section
, and widget
objects in the following card message:
The following code represents the JSON of the card message:
JSON
{
"cardsV2": [
{
"cardId": "unique-card-id",
"card": {
"header": {
"title": "Sasha",
"subtitle": "Software Engineer",
"imageUrl":
"https://developers.google.com/chat/images/quickstart-app-avatar.png",
"imageType": "CIRCLE",
"imageAltText": "Avatar for Sasha",
},
"sections": [
{
"header": "Contact Info",
"collapsible": true,
"uncollapsibleWidgetsCount": 1,
"widgets": [
{
"decoratedText": {
"startIcon": {
"knownIcon": "EMAIL",
},
"text": "sasha@example.com",
}
},
{
"decoratedText": {
"startIcon": {
"knownIcon": "PERSON",
},
"text": "<font color=\"#80e27e\">Online</font>",
},
},
{
"decoratedText": {
"startIcon": {
"knownIcon": "PHONE",
},
"text": "+1 (555) 555-1234",
}
},
{
"buttonList": {
"buttons": [
{
"text": "Share",
"onClick": {
"openLink": {
"url": "https://example.com/share",
}
}
},
{
"text": "Edit",
"onClick": {
"action": {
"function": "goToView",
"parameters": [
{
"key": "viewType",
"value": "EDIT",
}
],
}
}
},
],
}
},
],
},
],
},
}
],
}
Create a synchronous card message
In this example, a user creates the Chat app a message in Chat and the app responds by sending a simple synchronous card message showing the sender's name and avatar image:
In the following code samples, the Node.js and Python apps are hosted on Google Cloud Functions. The Apps Script example is hosted on Google Apps Script.
For full instructions describing how to build and deploy a Chat app, see Build a Chat app.
Node.js
Python
Apps Script
Create an asynchronous card message with the Chat API
This example asynchronously creates a message with the Chat API and sends it to a space that the Chat app is added to:

Python
- In your working directory, create a file named
chat_create_card_message.py
. Include the following code in
chat_create_card_message.py
:from httplib2 import Http from oauth2client.service_account import ServiceAccountCredentials from apiclient.discovery import build # Specify required scopes. SCOPES = ['https://www.googleapis.com/auth/chat.bot'] # Specify service account details. CREDENTIALS = ServiceAccountCredentials.from_json_keyfile_name( 'service_account.json', SCOPES) # Build the URI and authenticate with the service account. chat = build('chat', 'v1', http=CREDENTIALS.authorize(Http())) # Create a Chat message. result = chat.spaces().messages().create( # The space to create the message in. # # Replace SPACE with a space name. # Obtain the space name from the spaces resource of Chat API, # or from a space's URL. parent='spaces/SPACE', # The message to create. body= { 'cardsV2': [{ 'cardId': 'createCardMessage', 'card': { 'header': { 'title': 'A Card Message!', 'subtitle': 'Created with Chat REST API', 'imageUrl': 'https://developers.google.com/chat/images/chat-product-icon.png', 'imageType': 'CIRCLE' }, 'sections': [ { 'widgets': [ { 'buttonList': { 'buttons': [ { 'text': 'Read the docs!', 'onClick': { 'openLink': { 'url': 'https://developers.google.com/chat' } } } ] } } ] } ] } }] } ).execute() print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in the Chat API, or from a space's URL.In your working directory, build and run the sample:
python3 chat_create_card_message.py
To learn more about working with messages in the Chat API, see the following:
Open a dialog
Dialogs are windowed, card-based interfaces that Chat apps open to interact with users. To help users complete multi-step processes, apps can open sequential dialogs. Apps can open dialogs in response to a button click on a card message or in response to a slash command.
Dialogs are useful for many types of user interactions, including:
- Collecting information from users
- Authenticating users with Web services
- Configuring Chat app settings
In this example, a Chat app opens a dialog to help a user create a new contact for their address book:
To implement dialogs, see Open dialogs.
Card formatting
There are a few different ways to format the appearance of cards.
Card text formatting
Inside cards, most text fields support basic text formatting by using a small subset of HTML tags.
The supported tags and their purpose are shown in the following table:
Format | Example | Rendered result |
---|---|---|
Bold | "This is <b>bold</b>." |
This is bold. |
Italics | "This is <i>italics</i>." |
This is italics. |
Underline | "This is <u>underline</u>." |
This is underline. |
Strikethrough | "This is <s>strikethrough</s>." |
This is |
Font color | "This is <font color=\"#FF0000\">red font</text>." |
This is red font. |
Hyperlink | "This is a <a href=\"https://www.google.com\">hyperlink</a>." |
This is a hyperlink. |
Time | "This is a time format: <time>2023-02-16 15:00</time>." |
This is a time format: . |
Newline | "This is the first line. <br> This is a new line. " |
This is the first line. This is a new line. |
Note that the text body of a basic message is parsed using a different markup syntax which is optimized for human users. For details, see Create a text message.
Built-in icons
The
DecoratedText
and
ButtonList
widgets support the icon
element
used to specify one of the built-in icons available in Google Chat:
{ . . . "knownIcon": "TRAIN", . . . }
The following table lists the built-in icons that are available for card messages:
AIRPLANE | BOOKMARK | ||
BUS | CAR | ||
CLOCK | CONFIRMATION_NUMBER_ICON | ||
DESCRIPTION | DOLLAR | ||
EVENT_SEAT | |||
FLIGHT_ARRIVAL | FLIGHT_DEPARTURE | ||
HOTEL | HOTEL_ROOM_TYPE | ||
INVITE | MAP_PIN | ||
MEMBERSHIP | MULTIPLE_PEOPLE | ||
PERSON | PHONE | ||
RESTAURANT_ICON | SHOPPING_CART | ||
STAR | STORE | ||
TICKET | TRAIN | ||
VIDEO_CAMERA | VIDEO_PLAY |
Custom icons
The
DecoratedText
and
ButtonList
widgets let you use the built-in icons, or define your own custom icons. To
specify a custom icon, use the iconUrl
element as shown here:
{ . . . "iconUrl": "https://developers.google.com/chat/images/quickstart-app-avatar.png" . . . }