| name | gws-chat |
| description | Google Chat CLI operations via gws. Use when users need to list/create/manage chat spaces, read/send messages, manage members, track read state, handle attachments, or monitor space events. Triggers: google chat, gchat, chat spaces, chat messages. |
| metadata | {"short-description":"Google Chat CLI operations","compatibility":"claude-code, codex-cli"} |
Google Chat (gws chat)
gws chat provides CLI access to Google Chat with structured JSON output.
Disclaimer: gws is not the official Google CLI. This is an independent, open-source project not endorsed by or affiliated with Google.
Dependency Check
Before executing any gws command, verify the CLI is installed:
gws version
If not found, install: go install github.com/omriariav/workspace-cli/cmd/gws@latest
Authentication
Requires OAuth2 credentials. Run gws auth status to check.
If not authenticated: gws auth login (opens browser for OAuth consent).
For initial setup, see the gws-auth skill.
Note: Google Chat API requires additional setup:
- Enable the Chat API in your Google Cloud project
- Configure the OAuth consent screen for Chat scopes
- For some operations, you may need a service account with domain-wide delegation
Quick Command Reference
| Task | Command |
|---|
| Spaces | |
| List chat spaces | gws chat list |
| List spaces (filtered) | gws chat list --filter 'spaceType = "SPACE"' |
| Get space details | gws chat get-space <space-id> |
| Create a space | gws chat create-space --display-name "Team" --type SPACE |
| Delete a space | gws chat delete-space <space-id> |
| Update a space | gws chat update-space <space-id> --display-name "New Name" |
| Search spaces (admin only) | gws chat search-spaces --query "Engineering" |
| Find DM with user | gws chat find-dm --email user@example.com |
| Create space + members | gws chat setup-space --display-name "Team" --members "users/1,users/2" |
| Create DM | gws chat setup-space --type DIRECT_MESSAGE --members "users/123" |
| Create group chat | gws chat setup-space --type GROUP_CHAT --members "users/1,users/2" |
| Build member cache | gws chat build-cache |
| Find group by members | gws chat find-group --members "user1@example.com,user2@example.com" |
| Find space by name | gws chat find-space --name "sales-skills" |
| Messages | |
| Read messages | gws chat messages <space-id> |
| Read recent messages | gws chat messages <space-id> --order-by "createTime DESC" --max 10 |
| Messages after a date | gws chat messages <space-id> --after "2026-02-17T00:00:00Z" |
| Messages in a range | gws chat messages <space-id> --after "2026-02-17T00:00:00Z" --before "2026-02-20T00:00:00Z" |
| Recap recent messages | gws chat recent --since 2h |
| Recap last 7 days | gws chat recent --since 7d --max 1000 |
| Send a message | gws chat send --space <space-id> --text "Hello" |
| Quote a message | gws chat send --space <space-id> --text "Reply" --quote <message-id> |
| Get a single message | gws chat get <message-name> |
| Update a message | gws chat update <message-name> --text "New text" |
| Delete a message | gws chat delete <message-name> |
| Members | |
| List space members | gws chat members <space-id> |
| Get member details | gws chat get-member <member-name> |
| Add a member | gws chat add-member <space-id> --user users/123 |
| Remove a member | gws chat remove-member <member-name> |
| Update member role | gws chat update-member <member-name> --role ROLE_MANAGER |
| Reactions | |
| List reactions | gws chat reactions <message-name> |
| Add a reaction | gws chat react <message-name> --emoji "๐" |
| Remove a reaction | gws chat unreact <reaction-name> |
| Read State | |
| Get read state | gws chat read-state <space-id> |
| Mark space as read | gws chat mark-read <space-id> |
| Get thread read state | gws chat thread-read-state <thread-name> |
| List unread messages | gws chat unread <space-id> |
| Attachments & Media | |
| Get attachment info | gws chat attachment <attachment-name> |
| Upload a file | gws chat upload <space-id> --file ./report.pdf |
| Download media | gws chat download <resource-name> --output ./file.pdf |
| Events | |
| List space events | gws chat events <space-id> --filter 'event_types:"google.workspace.chat.message.v1.created"' |
| Get event details | gws chat event <event-name> |
Detailed Usage
list โ List chat spaces
gws chat list [flags]
Lists all Chat spaces (rooms, DMs, group chats) you have access to. Supports filtering and pagination.
Flags:
--filter string โ Filter spaces (e.g. spaceType = "SPACE")
--page-size int โ Number of spaces per page (default 100)
messages โ List messages in a space
gws chat messages <space-id> [flags]
Flags:
--max int โ Maximum number of messages to return (default 25)
--after string โ Show messages after this time (RFC3339, e.g. 2026-02-17T00:00:00Z)
--before string โ Show messages before this time (RFC3339, e.g. 2026-02-20T00:00:00Z)
--filter string โ Filter messages (e.g. createTime > "2024-01-01T00:00:00Z")
--order-by string โ Order messages (e.g. createTime DESC)
--show-deleted โ Include deleted messages in results
--resolve-senders โ Make extra API calls to fill missing sender_display_name (via space membership listing) and add a self boolean (via People API people/me). One extra Chat call per space plus one People call per invocation.
--after and --before are convenience shortcuts for --filter. They combine with --filter using AND.
recent โ Recap recent messages across active spaces
gws chat recent --since <window> [flags]
Recaps Chat messages across every space active within --since, without iterating message history for inactive spaces. Uses spaces.list lastActiveTime as the cheap prefilter, then queries spaces.messages.list per active space with createTime > since and orderBy=createTime DESC. Results are flattened and sorted globally by newest first. Includes both sent and received messages by default.
Flags:
--since string โ Time window: a Go duration (2h, 12h, 7d) or RFC3339 timestamp (2026-04-30T09:00:00Z). Default 2h.
--max int โ Total message cap (default 500, 0 = all)
--max-per-space int โ Per-space cap (default 100, 0 = all)
--max-spaces int โ Active-space cap after sorting by lastActiveTime DESC (default 0 = all)
--resolve-senders โ Fill sender_display_name (one extra membership-list call per active space) and add self via People API
--exclude-self โ Omit messages sent by the authenticated user (best-effort self detection via People API)
Output:
{
"since": "2026-04-30T09:00:00Z",
"spaces_scanned": 123,
"active_spaces": 8,
"count": 42,
"messages": [
{
"space": "spaces/AAAA",
"space_display_name": "Team Chat",
"space_type": "SPACE",
"space_last_active_time": "2026-04-30T10:58:00Z",
"name": "spaces/AAAA/messages/msg1",
"text": "...",
"create_time": "2026-04-30T10:57:00Z",
"sender": "Alice",
"sender_resource": "users/123"
}
]
}
Examples:
gws chat recent --since 2h
gws chat recent --since 12h --resolve-senders --exclude-self
gws chat recent --since 7d --max 1000 --max-per-space 200
gws chat recent --since 2026-04-30T09:00:00Z
Sender attribution fields:
sender โ existing display-name-or-resource string. Always present when the message has a sender.
sender_type, sender_resource, sender_display_name โ additive fields populated from the Chat message payload itself. They appear in default output whenever the API returned them, with no extra calls.
self โ only populated when --resolve-senders is set and the People API self lookup succeeds. Omitted otherwise rather than guessed.
--resolve-senders only adds work for the cases the payload alone can't satisfy: filling sender_display_name when the API didn't include one, and adding self. Failures degrade gracefully โ messages stay usable.
members โ List space members
gws chat members <space-id> [flags]
Lists all members of a Chat space with display names, emails, roles, and user types.
Display names and emails are auto-resolved via the People API and cached locally at ~/.config/gws/user-cache.json. The cache grows over time, avoiding repeat API calls.
Flags:
--max int โ Maximum number of members to return (default 100)
--filter string โ Filter members (e.g. member.type = "HUMAN")
--show-groups โ Include Google Group memberships
--show-invited โ Include invited memberships
send โ Send a message
gws chat send --space <space-id> --text <message>
Flags:
--space string โ Space ID or name (required)
--text string โ Message text (required)
--quote string โ Message resource name or ID to quote; the CLI fetches the quoted message and sends its current create/update timestamp.
--quote-type string โ Quote type: reply or forward (default API behavior is reply).
--notify string โ Notification behavior: none, force, or silent (default none). force and silent are rejected until Chat app authentication is supported.
get โ Get a single message
gws chat get <message-name>
Retrieves a single message by its resource name (e.g. spaces/AAAA/messages/msg1).
Flags:
--resolve-senders โ Same additive sender attribution as on chat messages.
update โ Update a message
gws chat update <message-name> --text "New text"
Flags:
--text string โ New message text (required)
delete โ Delete a message
gws chat delete <message-name> [flags]
Flags:
--force โ Force delete even if message has replies
reactions โ List reactions on a message
gws chat reactions <message-name> [flags]
Flags:
--filter string โ Filter reactions (e.g. emoji.unicode = "๐")
--page-size int โ Number of reactions per page (default 25)
react โ Add a reaction
gws chat react <message-name> --emoji "๐"
Flags:
--emoji string โ Emoji unicode character (required)
unreact โ Remove a reaction
gws chat unreact <reaction-name>
Removes a reaction by its resource name (e.g. spaces/AAAA/messages/msg1/reactions/rxn1).
get-space โ Get space details
gws chat get-space <space>
Retrieves details about a Chat space including name, type, description.
create-space โ Create a space
gws chat create-space --display-name "Team Chat" [flags]
Flags:
--display-name string โ Space display name (required)
--type string โ Space type: SPACE or GROUP_CHAT (default SPACE)
--description string โ Space description
delete-space โ Delete a space
gws chat delete-space <space>
update-space โ Update a space
gws chat update-space <space> [flags]
Flags:
--display-name string โ New display name
--description string โ New description
search-spaces โ Search for spaces (admin only)
Requires Workspace admin privileges and chat.admin.spaces scope. Not available with regular user OAuth.
gws chat search-spaces --query "Engineering" [flags]
Flags:
--query string โ Search query (required)
--page-size int โ Results per page (default 100)
find-dm โ Find direct message space
gws chat find-dm --email user@example.com
gws chat find-dm --user users/123
Flags:
--user string โ User resource name (e.g. users/123)
--email string โ User email address (e.g. user@example.com)
setup-space โ Create space with members
gws chat setup-space --display-name "Project Team" --members "users/111,users/222"
gws chat setup-space --type DIRECT_MESSAGE --members "users/111"
gws chat setup-space --type GROUP_CHAT --members "users/111,users/222"
Flags:
--display-name string โ Space display name (required for SPACE type, forbidden for DM/GROUP_CHAT)
--type string โ Space type: SPACE, GROUP_CHAT, or DIRECT_MESSAGE (default SPACE)
--members string โ Comma-separated user resource names (required for DM/GROUP_CHAT)
get-member โ Get member details
gws chat get-member <member-name>
add-member โ Add a member to a space
gws chat add-member <space> --user users/123 [flags]
Flags:
--user string โ User resource name (required)
--role string โ Member role: ROLE_MEMBER or ROLE_MANAGER (default ROLE_MEMBER)
remove-member โ Remove a member
gws chat remove-member <member-name>
update-member โ Update member role
gws chat update-member <member-name> --role ROLE_MANAGER
Flags:
--role string โ New role: ROLE_MEMBER or ROLE_MANAGER (required)
read-state โ Get space read state
gws chat read-state <space>
Returns when you last read the space. Space ID is auto-expanded to the full read state resource name.
mark-read โ Mark space as read
gws chat mark-read <space> [flags]
Flags:
--time string โ Read time in RFC-3339 format (defaults to now)
thread-read-state โ Get thread read state
gws chat thread-read-state <thread-name>
Full resource name required (e.g. users/me/spaces/AAAA/threads/thread1/threadReadState).
unread โ List unread messages
gws chat unread <space-id> [flags]
Lists messages received after the last read time. Combines read-state lookup and message filtering.
Flags:
--max int โ Maximum number of unread messages (default: 25)
--mark-read โ Mark space as read after listing
--resolve-senders โ Same additive sender attribution as on chat messages.
attachment โ Get attachment metadata
gws chat attachment <attachment-name>
Returns metadata: name, content_name, content_type, source, download_uri, thumbnail_uri.
upload โ Upload a file
gws chat upload <space> --file ./report.pdf
Flags:
--file string โ Path to file to upload (required)
download โ Download media
gws chat download <resource-name> --output ./file.pdf
Flags:
--output string โ Output file path (required)
events โ List space events
gws chat events <space> --filter 'event_types:"google.workspace.chat.message.v1.created"' [flags]
Flags:
--filter string โ Event type filter (required โ API requires it)
--page-size int โ Events per page (default 100)
event โ Get event details
gws chat event <event-name>
build-cache โ Build space-members cache
gws chat build-cache
gws chat build-cache --type all
gws chat build-cache --type SPACE
Iterates spaces, fetches members, resolves emails via People API, and stores a local cache at ~/.config/gws/space-members-cache.json. Progress is shown on stderr.
Flags:
--type string โ Space type to cache: GROUP_CHAT (default), SPACE, DIRECT_MESSAGE, or all
find-group โ Find group chats by members
gws chat find-group --members "alice@example.com,bob@example.com"
gws chat find-group --members "alice@example.com" --refresh
Searches the local space-members cache for spaces where ALL specified emails are members. Requires build-cache to be run first (or use --refresh).
Flags:
--members string โ Comma-separated email addresses to search for (required)
--refresh โ Rebuild cache before searching
find-space โ Find spaces by display name
gws chat find-space --name "sales-skills" --refresh
gws chat find-space --name "team" --type SPACE
Searches the local space cache for spaces whose display_name contains the given query (case-insensitive substring match). DMs without a display name are skipped.
Cache scope matters. Default gws chat build-cache only caches GROUP_CHAT. To find SPACE-type rooms (most named spaces) or all types, either:
- prebuild with
gws chat build-cache --type SPACE (or --type all), or
- pass
--refresh so this command rebuilds the cache before searching.
Flags:
--name string โ Display name substring to search for (case-insensitive, required)
--type string โ Filter by space type: SPACE, GROUP_CHAT, or DIRECT_MESSAGE
--refresh โ Rebuild cache before searching (scoped to --type if set, otherwise all types)
Output Modes
gws chat list --format json
gws chat list --format yaml
gws chat list --format text
Common Mistakes
| Mistake | Correct Usage |
|---|
--limit N on messages | Use --max N โ --limit does not exist |
find-dm --user email@example.com | Use users/email@example.com format โ the --user flag requires a resource name prefix |
setup-space --display-name "X" --type DIRECT_MESSAGE | Omit --display-name for DM/GROUP_CHAT โ API rejects it |
find-group without cache | Run gws chat build-cache first, or use --refresh |
Recipe: Find a Group Chat by Member Names
Preferred method โ use the member cache:
gws chat build-cache
gws chat find-group --members "alice@example.com,bob@example.com"
gws chat messages spaces/AAAApznBCFA --after "2026-02-20T00:00:00Z" --order-by "createTime DESC" --max 25
Alternative โ manual search (no cache needed):
gws chat list --format json | jq '.spaces | map(select(.type == "GROUP_CHAT")) | .[:10]'
gws chat members spaces/AAAApznBCFA --format json
Key insight: DMs and group chats often have empty display_name โ you must check members to identify participants.
Recipe: Create a DM via Contacts
gws contacts resolve --email "user@example.com"
gws chat find-dm --user users/123456
gws chat setup-space --type DIRECT_MESSAGE --members "users/123456"
gws chat send --space spaces/DMXYZ --text "Hello!"
Tips for AI Agents
- Always use
--format json (the default) for programmatic parsing
- Use
gws chat list first to get space IDs
- Space IDs are in the format
spaces/AAAA1234
- Message names are in the format
spaces/AAAA/messages/msg1
members auto-resolves display names via People API โ first call may be slower, subsequent calls use cache
- Use
--order-by "createTime DESC" with messages to get newest first
- Use
--filter 'createTime > "YYYY-MM-DDT00:00:00Z"' to scope messages to a date range โ more reliable than relying on default ordering
read-state auto-expands bare space IDs (e.g. AAAA โ users/me/spaces/AAAA/spaceReadState)
events requires a --filter with event types โ see API docs
- Chat API requires additional GCP setup beyond standard OAuth โ see the
gws-auth skill