Post to Google Chat from an agent
The gchat_post_message tool posts a message to a Google Chat space, optionally
with rich link cards, and gchat_dm_user sends a direct message to one person.
Both authenticate as a Chat app. Use them for proactive notifications, scheduled
reports, and task updates, rather than only replying when the agent is
mentioned.
Before you begin
The tool authenticates as a Google Chat app using a service account, so:
- The service account must be configured as a Google Chat app, and the Google Chat API must be enabled for its Google Cloud project.
- The Chat app must already be a member of the target space. There is no API to join a space, so a person has to add the app to the space, or the app must have created it. Posting to a space the app does not belong to fails.
Posting to a space, and messaging a person by Chat user id, both use the
https://www.googleapis.com/auth/chat.bot scope, which the app grants itself.
Neither requires Google Workspace administrator approval.
Messaging a person by email address is the exception. It reads the Google Workspace directory to turn the address into a Chat user id, which requires two things an administrator has to set up. See Message a person by email address.
Credentials
The tool takes its credentials from one of two places, and the agent never sees them: both are filled by configuration, not chosen by the model.
A gchat_service_account_key agent secret. Store the full service account
JSON key under that name and the tool picks it up automatically. No connector is
needed.
STORE A GOOGLE CHAT SERVICE ACCOUNT KEY
Code example with bash syntax.1
An attached Google Chat connector. A connector of type gchat carries the
same service account key and also lets the agent receive Chat events. Create one
with the service account JSON key:
CREATE A GOOGLE CHAT CONNECTOR
Code example with bash syntax.1
The service account key is encrypted at rest and never returned. The read view
of the connector returns client_email and project_id, parsed out of the key,
plus an audience_url. To receive inbound events, set the Chat app's HTTP
endpoint URL and Authentication audience to that audience_url in the
Google Cloud console: inbound Google Chat ID tokens are accepted only when their
aud matches it.
Credential precedence
When the tool runs, credentials resolve in this order:
- An explicit service account key argument. The shipped configuration fills
this from the
gchat_service_account_keyagent secret. - An explicit connector ID argument. The shipped configuration fills this from
session.metadata.connector_id, which the connector sets on sessions it triggers. A connector ID that resolves to a non-Google connector (a Slack-triggered session cross-posting to Chat, for example) falls through to the steps below; one that resolves to nothing is an error. - The connector that triggered the current loop, if it carries Google credentials.
- The first Google connector attached to the agent, ordered by connector ID.
If none of these produce credentials, the tool call fails with an error naming
the gchat_service_account_key secret.
gchat_post_message
Posts a message to a space or thread.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
space_name | string | Yes | The resource name of the space, such as spaces/AAAAAqas8kM. This is not the space's display name. |
text | string | Required unless cards is set | The message text, 1 to 32,000 characters. |
cards | array | Required unless text is set | Rich cards appended below the message text. |
thread_name | string | No | The resource name of an existing thread to reply in, such as spaces/AAAAAqas8kM/threads/UWknXX-lIB4. Omit to start a new thread. |
A message with neither text nor cards is rejected before any request is sent.
The whole message, text plus cards, is limited to 32,000 bytes.
Message text uses Google Chat text formatting: *bold*, _italic_,
~strikethrough~, `code`, ```code blocks```,
<https://example.com|link text> links, and <users/USER_ID> mentions. Use
<users/all> to mention everyone.
Response
| Field | Type | Description |
|---|---|---|
ok | boolean | Whether the message was posted. Always present. |
message_name | string | The resource name of the posted message, such as spaces/AAAAAqas8kM/messages/UWknXX-lIB4.UWknXX-lIB4. |
thread_name | string | The resource name of the message's thread. |
error | string | The error message when the post failed. |
When the Chat API rejects the post, the tool returns ok: false with error
set, rather than failing the agent's turn.
Threading
Pass the thread_name returned by an earlier post, or observed on an incoming
message, to reply in that thread. If the thread does not exist, the post fails
instead of silently starting a new one. Spaces that do not use threading, such
as direct messages and group chats, ignore thread_name.
Cards
Each entry in cards renders as a framed panel below the message text, with an
optional header and one or more sections. Cards suit content with links the user
should open: reports, alerts, and digests.
| Field | Type | Required | Description |
|---|---|---|---|
title | string | No | Card header title, rendered at the top of the card. |
subtitle | string | No | Card header subtitle. Ignored unless title is set. |
sections | array | Yes | The card body, rendered top to bottom. At least one section. |
Each section takes an optional header, a text body, and a list of links,
and must have text, links, or both. Sections are separated by a divider.
| Field | Type | Required | Description |
|---|---|---|---|
header | string | No | A small heading above the section content. |
text | string | Required unless links is set | Section body text. |
links | array | Required unless text is set | Link buttons rendered in a row below the section text. |
Each link is a button with a text label and a url, which must be http or
https. Clicking it opens the URL in the user's browser, so no card
interactivity support is needed in the Chat app.
Section text uses HTML-style formatting rather than Chat text markup:
<b>bold</b>, <i>italic</i>, <s>strikethrough</s>, <u>underline</u>,
<a href="https://example.com">inline links</a>, and <br> for line breaks.
{
"space_name": "spaces/AAAAAqas8kM",
"text": "*Nightly index run finished.*",
"cards": [
{
"title": "Index run 4821",
"subtitle": "Completed in 12m",
"sections": [
{
"header": "Summary",
"text": "<b>18,204</b> documents indexed, <b>3</b> failures.",
"links": [
{ "text": "Open report", "url": "https://example.com/runs/4821" }
]
}
]
}
]
}
Chat-triggered agents
When a Google Chat connector triggers an agent, the connector already posts the
agent's final reply to the triggering space and thread. An agent that also calls
gchat_post_message with the same content posts the message twice. Instruct
such agents to use the tool only for messages beyond the final reply: posts to
other spaces or threads, and mid-run progress updates.
gchat_dm_user
Sends a direct message to one person. The tool resolves that person's direct message space and posts to it.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user | string | Yes | The person to message, as a Workspace email address or a Chat user resource name such as users/123456789. |
text | string | Yes | The message text, 1 to 32,000 characters. |
The tool sends text. To send rich cards to a person, take the space_name it
returns and call gchat_post_message with that space.
The direct message space must already exist
A Chat app cannot open a direct message conversation. A space exists once the person has messaged or added the app, or once an administrator has installed the app for the organization through the Google Workspace Marketplace.
When no space exists, the tool returns ok: false with reachable: false and
sends nothing. That result is settled rather than temporary: retrying returns
the same answer. Instruct agents to report that the person has not installed the
Chat app instead of trying again.
Message a person by email address
A Chat user resource name needs no configuration beyond the Chat app itself. An email address needs two more things, because Chat's app authentication does not accept email addresses and the tool has to read the Google Workspace directory to turn one into a Chat user id.
- Enable the Admin SDK API for the service account's Google Cloud project, under APIs and services, then Library.
- Give the service account a Workspace administrator role that can read users. In the Google Workspace Admin console, under Account, then Admin roles, assign the service account a role holding the Admin API privilege Users, then Read.
Both are separate from the Chat app's Marketplace SDK scopes, which do not affect this. Until both are in place, an email address returns an error naming the missing configuration, and a Chat user resource name still works.