With the Google Chat API, you can asynchronously create, read, update, or delete a message in Google Chat by calling corresponding methods. This guide explains how to call the following methods:
- Create a message with
spaces.messages.create
. - Read a message with
spaces.messages.get
. - Update a message with
spaces.messages.update
. - Delete a message with
spaces.messages.delete
.
Chat apps can respond to Chat events, like messages and getting added to a space, without asynchronously calling the Chat API. To build a Chat app that synchronously responds to Chat events, see Build a Chat app. A Chat app can work with Chat API synchronously and asynchronously.
To asynchronously create a message in a Chat space without a Chat app, set up a webhook.
Prerequisites
To run the examples in this guide, you need the following prerequisites:
Python
- Python 3.6 or greater
- The pip package management tool
The Google client libraries for Python. To install them, run the following command in your command line interface:
pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib oauth2client
A published Chat app with membership in a Chat space:
- To create and publish a Chat app, see Build a Google Chat app with Cloud Functions.
- To add a Chat app to a Chat space, see Add apps to spaces or conversations in Google Chat.
Authorization configured for the Chat app:
- Service account authentication is fully supported. To set up a service account, see Authenticate and authorize as a service account.
- Google Workspace Developer Preview Program, which grants early access to certain features. To set up user authentication, see Authenticate and authorize users (Developer Preview). The
spaces.messages.update
method does not support user authentication yet.
Developer Preview: User authentication is supported as part of the
Create a message
To asynchronously create a message in Google Chat, call the create
method on the Message
resource. You can create a text or a card message. To start or reply to a thread, specify a threadKey
or thread.name
.
Make note of the name
of a message you create so you can reference it later if you need to read, update, or delete it. Alternatively, consider naming messages.
Create a text message
Here's how to create a text message:
Python
- In your working directory, create a file named
chat_create_text_message.py
. Include the following code in
chat_create_text_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={'text': 'Hello, world!'} ).execute() print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In your working directory, build and run the sample:
python3 chat_create_text_message.py
Create a card message
Here's how to create a card message, like the one shown below:

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 Chat API, or from a space's URL.In your working directory, build and run the sample:
python3 chat_create_card_message.py
Start or reply to a message thread
To start a message thread, create a message and leave thread.name
empty; Google Chat will populate it when creating the thread. Optionally, to customize the name of the thread, specify thread.threadKey
as the name of the thread.
To reply to a message thread, specify the thread.threadKey
or thread.name
as the name of the thread. Subsequent messages with the same thread.threadKey
or thread.name
post into the same thread as replies.
Each thread.threadKey
is unique to the Chat app or webhook that sets it. If two different apps or webhooks set the same thread.threadKey
, the messages don't thread. Instead, two different threads start. Two different apps or webhooks can post replies in the same thread by specifying thread.name
instead.
Here's how to start or reply to a thread with the thread.threadKey
"nameOfThread":
Python
- In your working directory, create a file named
chat_create_message_thread.py
. Include the following code in
chat_create_message_thread.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. # # REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD replies to an existing thread # if one exists, otherwise it starts a new one. # # 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', # Whether to start a thread or reply to an existing one. # # Required when threading is enabled in a space unless starting a # thread. Ignored in other space types. Threading is enabled when # space.spaceThreadingState is THREADED_MESSAGES. messageReplyOption='REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD', # The message body. body={ # The message to create. 'text': 'Start or reply to another message in a thread!', # The thread to start or reply to. 'thread': { 'threadKey': 'nameOfThread' } } ).execute() print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In your working directory, build and run the sample:
python3 chat_create_message_thread.py
Create and name a message
To facilitate later operations on a created message, assign it a custom name
. Assigning a custom name lets a Chat app quickly recall the message without saving saving the message name
from the response body returned when creating the message.
Assigning a custom name lets a Chat app recall the message without saving the message name
from the response body returned when creating the message.
Assigning a custom name doesn't replace the generated name
field, the message's resource name. Instead, it sets the custom name as the clientAssignedMessageId
field, which can then be referenced while processing later operations, like updating or deleting the message.
Specifying a used custom name while creating a message returns an error, but other methods like update
and delete
work as expected.
Custom name requirements:
- Begin with
client-
. For example,client-custom-name
is a valid custom name, butcustom-name
is not. - Contain only lowercase letters, numbers, and hyphens.
- No more than 63 characters in length.
Here's how to create and name a message:
Python
- In your working directory, create a file named
chat_create_named_message.py
. Include the following code in
chat_create_named_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 with a custom name. 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', # Custom name for the message used to facilitate later operations. messageId='client-custom-name', # The message to create. body={'text': 'Hello, world!'} ).execute() print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In your working directory, build and run the sample:
python3 chat_create_named_message.py
Read a message
To asynchronously read a message in Google Chat, call the get
method on the Message
resource, and pass the name
of the message to read.
Here's how to read a message:
Python
- In your working directory, create a file named
chat_read_message.py
. Include the following code in
chat_read_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())) # Get a Chat message. result = chat.spaces().messages().get( # The message to read. # # Replace SPACE with a space name. # Obtain the space name from the spaces resource of Chat API, # or from a space's URL. # # Replace MESSAGE with a message name. # Obtain the message name from the response body returned # after creating a message asynchronously with Chat REST API. name='spaces/SPACE/messages/MESSAGE' ).execute() # Print Chat API's response in your command line interface. print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In the code, replace
MESSAGE
with a message name, which you can obtain from the response body returned after creating a message asynchronously with Chat API, or with the custom name assigned to the message at creation.In your working directory, build and run the sample:
python3 chat_read_message.py
Update a message
To asynchronously update an existing message in Google Chat, call the update
method on the Message
resource, and pass the name
of the message to update, as well as an updateMask
and a body
that specifies the updated message.
Update a text message, or prepend a text message to a card message
To update a text message, pass:
- The
name
of the message to update. updateMask='text'
- A
body
that specifies the updated message.
If the updated message is a card message, then the text message prepends to the card message (which continues to display).
Here's how to update a text message to a text message, or prepends a text message to a card message:
Python
- In your working directory, create a file named
chat_update_text_message.py
. Include the following code in
chat_update_text_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())) # Update a Chat message. result = chat.spaces().messages().update( # The message to update, and the updated message. # # Replace SPACE with a space name. # Obtain the space name from the spaces resource of Chat API, # or from a space's URL. # # Replace MESSAGE with a message name. # Obtain the message name from the response body returned # after creating a message asynchronously with Chat REST API. name='spaces/SPACE/messages/MESSAGE', updateMask='text', body={'text': 'Updated message!'} ).execute() # Print Chat API's response in your command line interface. print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In the code, replace
MESSAGE
with a message name, which you can obtain from the response body returned after creating a message asynchronously with Chat API, or with the custom name assigned to the message at creation.In your working directory, build and run the sample:
python3 chat_update_text_message.py
Update a card message, or append a card message to a text message
To update a card message, pass:
- The
name
of the message to update updateMask='cardsV2'
- A
body
that specifies the updated message.
If the updated message is a text message, then a card appends to the text message (which continues to display). If the updated message is itself a card, then the displayed card gets updated.
Here's how to update a message to a card message:
Python
- In your working directory, create a file named
chat_update_card_message.py
. Include the following code in
chat_update_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())) # Update a Chat message. result = chat.spaces().messages().update( # The message to update, and the updated message. # # Replace SPACE with a space name. # Obtain the space name from the spaces resource of Chat API, # or from a space's URL. # # Replace MESSAGE with a message name. # Obtain the message name from the response body returned # after creating a message asynchronously with Chat REST API. name='spaces/SPACE/messages/MESSAGE', updateMask='cardsV2', body= { 'cardsV2': [{ 'cardId': 'updateCardMessage', 'card': { 'header': { 'title': 'An Updated Card Message!', 'subtitle': 'Updated 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 Chat API's response in your command line interface. print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In the code, replace
MESSAGE
with a message name, which you can obtain from the response body returned after creating a message asynchronously with Chat API, or with the custom name assigned to the message at creation.In your working directory, build and run the sample:
python3 chat_update_card_message.py
Delete a message
To asynchronously delete an existing message in Google Chat, call the delete
method on the Message
resource, and pass the name
of the message to delete.
Here's how to delete a message:
Python
- In your working directory, create a file named
chat_delete_message.py
. Include the following code in
chat_delete_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())) # Delete a Chat message. result = chat.spaces().messages().delete( # The message to delete. # # Replace SPACE with a space name. # Obtain the space name from the spaces resource of Chat API, # or from a space's URL. # # Replace MESSAGE with a message name. # Obtain the message name from the response body returned # after creating a message asynchronously with Chat REST API. name='spaces/SPACE/messages/MESSAGE' ).execute() # Print Chat API's response in your command line interface. # When deleting a message, the response body is empty. print(result)
In the code, replace
SPACE
with a space name, which you can obtain from thespaces.list()
method in Chat API, or from a space's URL.In the code, replace
MESSAGE
with a message name, which you can obtain from the response body returned after creating a message asynchronously with Chat API, or with the custom name assigned to the message at creation.In your working directory, build and run the sample:
python3 chat_delete_message.py
Limits and considerations
- The only way to get the
name
of a message in Google Chat is from the response body returned when creating the message. Make sure to note thename
of a message you create so you can reference it later if you need to read, update, or delete it. Alternatively, consider naming messages. - When authenticating as an app with a service account, Chat apps can only read, update, and delete their own messages.
- user authentication, Google Chat might display an attribution message that tells users the name of the app that performed the action on behalf of the user who authorized it. Developer Preview: When an app performs an action with