Clojure wrapper for the Google Chat API (v1).
Provides idiomatic Clojure functions for managing spaces, messages, memberships, reactions, custom emojis, attachments, space events, per-user read state, per-user notification settings, and the user's sidebar sections (custom DM groupings).
Service-class naming: the Java SDK predates the rename from Hangouts Chat to Google Chat, so the service class is HangoutsChat and the scopes class is HangoutsChatScopes. The Clojure namespace uses the modern brand name.
Auth: use csl/scoped-delegated-credentials (service account + DWD) or csl/user-credentials (OAuth) with the appropriate scope from HangoutsChatScopes. The Chat API supports two auth contexts:
All list functions return {:data [...] :next-page-token "..."}. :next-page-token is absent when there are no further pages.
Update semantics: functions named update-* use PATCH (partial update; require :update-mask); functions named replace-* use PUT (full replacement). Both return the updated resource.
Cards: Message.cardsV2 carries deeply-nested GoogleAppsCardV1* types. Pass cards as plain Clojure data on :cards-v2 in the message map — the JSON round-trip pattern in ->message-model handles the typed children transparently.
Push notifications: Chat uses inbound webhooks (event handlers), not Pub/Sub watches. This library does not include watch/stop endpoints — inbound events are received by an HTTP server outside this library.
All functions return {:data ...} on success or {:error ...} on failure.
Clojure wrapper for the Google Chat API (v1).
Provides idiomatic Clojure functions for managing spaces, messages,
memberships, reactions, custom emojis, attachments, space events,
per-user read state, per-user notification settings, and the user's
sidebar sections (custom DM groupings).
Service-class naming: the Java SDK predates the rename from Hangouts
Chat to Google Chat, so the service class is HangoutsChat and the
scopes class is HangoutsChatScopes. The Clojure namespace uses the
modern brand name.
Auth: use csl/scoped-delegated-credentials (service account + DWD) or
csl/user-credentials (OAuth) with the appropriate scope from
HangoutsChatScopes. The Chat API supports two auth contexts:
- User context — OAuth 2.0 with chat.* scopes.
- App/bot context — service account with chat.bot or chat.app.* scopes.
Both yield GoogleCredentials, so chat-client accepts either.
All list functions return {:data [...] :next-page-token "..."}.
:next-page-token is absent when there are no further pages.
Update semantics: functions named update-* use PATCH (partial update;
require :update-mask); functions named replace-* use PUT (full
replacement). Both return the updated resource.
Cards: Message.cardsV2 carries deeply-nested GoogleAppsCardV1* types.
Pass cards as plain Clojure data on :cards-v2 in the message map —
the JSON round-trip pattern in ->message-model handles the typed
children transparently.
Push notifications: Chat uses inbound webhooks (event handlers), not
Pub/Sub watches. This library does not include watch/stop endpoints —
inbound events are received by an HTTP server outside this library.
All functions return {:data ...} on success or {:error ...} on failure.(chat-client credentials)(chat-client credentials opts)Build an authenticated Chat v1 REST client.
credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials or csl/user-credentials.
opts (optional):
Per-request opts on individual call sites override the client-level defaults.
Build an authenticated Chat v1 REST client. credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials or csl/user-credentials. opts (optional): - :read-timeout-ms per-client default read timeout (default 120000 / 120s) - :connect-timeout-ms per-client default connect timeout (default 30000 / 30s) Per-request opts on individual call sites override the client-level defaults.
(complete-import-space client space-name & [opts])Finalize an import-mode space, releasing it from import state.
See the Chat import API docs for the multi-step import flow this completes.
opts:
Finalize an import-mode space, releasing it from import state. See the Chat import API docs for the multi-step import flow this completes. opts: - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(create-custom-emoji client custom-emoji & [opts])Upload an organization-scoped custom emoji.
custom-emoji — CustomEmoji map. Required: :emoji-name — short name ("party-parrot") :payload — map with :file-content (base64-encoded bytes) and :filename
opts:
Upload an organization-scoped custom emoji.
custom-emoji — CustomEmoji map. Required:
:emoji-name — short name ("party-parrot")
:payload — map with :file-content (base64-encoded bytes) and :filename
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(create-membership client space-name membership & [opts])Add a user or group as a member of a space.
space-name — parent space resource name ("spaces/{space}"). membership — Membership map. Required: :member — map with :name (e.g., "users/123") and :type ("HUMAN" or "BOT") OR :group-member — for group memberships
opts:
Add a user or group as a member of a space.
space-name — parent space resource name ("spaces/{space}").
membership — Membership map. Required:
:member — map with :name (e.g., "users/123") and :type ("HUMAN" or "BOT")
OR :group-member — for group memberships
opts:
- :use-admin-access — boolean; act as a Workspace admin
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(create-message client space-name message & [opts])Post a message to a space.
space-name — parent space resource name ("spaces/{space}"). message — Message map. Common keys: :text — plain-text body :cards-v2 — vector of cards (see Card v1 reference); each {:card-id :card} :thread — {:name "..." :thread-key "..."} to reply in a thread
opts:
Post a message to a space.
space-name — parent space resource name ("spaces/{space}").
message — Message map. Common keys:
:text — plain-text body
:cards-v2 — vector of cards (see Card v1 reference); each {:card-id :card}
:thread — {:name "..." :thread-key "..."} to reply in a thread
opts:
- :message-id — caller-supplied custom message ID
- :message-reply-option — "REPLY_MESSAGE_OR_FAIL" | "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
- :request-id — caller-supplied dedup key for idempotent retries
- :thread-key — caller-supplied thread key for new threads
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(create-reaction client message-name reaction & [opts])Add an emoji reaction to a message.
message-name — parent message resource name. reaction — Reaction map. Required: :emoji — {:unicode "🎉"} OR {:custom-emoji {:uid "..."}}
opts:
Add an emoji reaction to a message.
message-name — parent message resource name.
reaction — Reaction map. Required:
:emoji — {:unicode "🎉"} OR {:custom-emoji {:uid "..."}}
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(create-section client parent section & [opts])Create a sidebar section under a user.
parent — "users/{user}". "users/me" is allowed. section — Section map. Common keys: :display-name — section title
opts:
Create a sidebar section under a user.
parent — "users/{user}". "users/me" is allowed.
section — Section map. Common keys:
:display-name — section title
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(create-space client space & [opts])Create a named space.
space — map with kebab-case keys. Required: :display-name — display title (omit for direct messages) :space-type — "SPACE" | "GROUP_CHAT" | "DIRECT_MESSAGE"
opts:
Create a named space. space — map with kebab-case keys. Required: :display-name — display title (omit for direct messages) :space-type — "SPACE" | "GROUP_CHAT" | "DIRECT_MESSAGE" opts: - :request-id — caller-supplied dedup key for idempotent retries - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(delete-custom-emoji client custom-emoji-name & [opts])Delete a custom emoji.
opts:
Delete a custom emoji. opts: - :read-timeout-ms — int, override the HTTP client's default read timeout
(delete-membership client membership-name & [opts])Remove a member from a space.
opts:
Remove a member from a space. opts: - :use-admin-access — boolean; act as a Workspace admin - :read-timeout-ms — int, override the HTTP client's default read timeout
(delete-message client message-name & [opts])Delete a message.
opts:
Delete a message.
opts:
- :force — boolean; if true, delete the thread along with the
starting message when this message starts a thread
- :read-timeout-ms — int, override the HTTP client's default read timeout(delete-reaction client reaction-name & [opts])Remove a reaction by resource name.
opts:
Remove a reaction by resource name. opts: - :read-timeout-ms — int, override the HTTP client's default read timeout
(delete-section client section-name & [opts])Delete a section.
opts:
Delete a section. opts: - :read-timeout-ms — int, override the HTTP client's default read timeout
(delete-space client space-name & [opts])Delete a space (cascades to all memberships and messages).
opts:
Delete a space (cascades to all memberships and messages). opts: - :use-admin-access — boolean; act as a Workspace admin - :read-timeout-ms — int, override the HTTP client's default read timeout
(download-media client resource-name & [opts])Download attachment content as a byte[].
resource-name — attachment data ref resource name, taken from a message's :attachments [{:attachment-data-ref {:resource-name "..."}}] or :attachment-data-ref :resource-name on a get-attachment response.
Returns {:data <byte[]>} on success.
opts:
Download attachment content as a byte[].
resource-name — attachment data ref resource name, taken from a message's
:attachments [{:attachment-data-ref {:resource-name "..."}}] or
:attachment-data-ref :resource-name on a get-attachment response.
Returns {:data <byte[]>} on success.
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(find-direct-message client user-resource-name & [opts])Look up the direct-message space with a single specified human user.
user-resource-name — "users/{user}" — the human user the DM is with.
opts:
Look up the direct-message space with a single specified human user.
user-resource-name — "users/{user}" — the human user the DM is with.
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(find-group-chats client & [opts])Find group-chat spaces that include a specified set of human users.
opts:
Find group-chat spaces that include a specified set of human users.
opts:
- :users — vector of user resource names ("users/{user}")
- :page-size — max spaces per page (1–1000; default 100)
- :page-token — token from a previous response
- :space-view — "FULL" | "BASIC" view of returned spaces
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(get-attachment client attachment-name & [opts])Get attachment metadata by resource name ("spaces/{space}/messages/{message}/attachments/{attachment}").
Returns the metadata only (download URL, MIME, etc.); use download-media with the attachment's :attachment-data-ref :resource-name to fetch bytes.
opts:
Get attachment metadata by resource name
("spaces/{space}/messages/{message}/attachments/{attachment}").
Returns the metadata only (download URL, MIME, etc.); use download-media
with the attachment's :attachment-data-ref :resource-name to fetch bytes.
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(get-custom-emoji client custom-emoji-name & [opts])Get a custom emoji by resource name ("customEmojis/{emoji}").
Get a custom emoji by resource name ("customEmojis/{emoji}").
(get-membership client membership-name & [opts])Get a membership by resource name ("spaces/{space}/members/{member}").
Get a membership by resource name ("spaces/{space}/members/{member}").
(get-message client message-name & [opts])Get a message by resource name ("spaces/{space}/messages/{message}").
Get a message by resource name ("spaces/{space}/messages/{message}").
(get-space client space-name & [opts])Get a space by resource name.
space-name — resource name (e.g., "spaces/AAAA1234").
opts:
Get a space by resource name. space-name — resource name (e.g., "spaces/AAAA1234"). opts: - :use-admin-access — boolean; act as a Workspace admin (chat.admin.spaces*) - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(get-space-event client event-name & [opts])Get a space event by resource name ("spaces/{space}/spaceEvents/{event}").
opts:
Get a space event by resource name
("spaces/{space}/spaceEvents/{event}").
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(get-space-notification-setting client name & [opts])Get a user's notification setting for a space.
name — "users/{user}/spaces/{space}/spaceNotificationSetting".
opts:
Get a user's notification setting for a space.
name — "users/{user}/spaces/{space}/spaceNotificationSetting".
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(get-space-read-state client name & [opts])Get a user's read state for a space.
name — "users/{user}/spaces/{space}/spaceReadState". "users/me" is allowed.
opts:
Get a user's read state for a space.
name — "users/{user}/spaces/{space}/spaceReadState". "users/me" is allowed.
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(get-thread-read-state client name & [opts])Get a user's read state for a thread (3-level chain).
name — "users/{user}/spaces/{space}/threads/{thread}/threadReadState".
opts:
Get a user's read state for a thread (3-level chain).
name — "users/{user}/spaces/{space}/threads/{thread}/threadReadState".
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(list-custom-emojis client & [opts])List organization-scoped custom emojis.
opts:
List organization-scoped custom emojis. opts: - :filter — server-side filter, e.g. "creator = \"users/me\"" - :page-size — max emojis per page (1–200; default 25) - :page-token — token from a previous response - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(list-memberships client space-name & [opts])List members of a space.
space-name — parent space resource name.
opts:
List members of a space. space-name — parent space resource name. opts: - :filter — server-side filter, e.g. "role = \"ROLE_MANAGER\"" - :page-size — max members per page (1–1000; default 100) - :page-token — token from a previous response - :show-groups — boolean; include group memberships - :show-invited — boolean; include invited members - :use-admin-access — boolean; act as a Workspace admin - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(list-messages client space-name & [opts])List messages in a space.
opts:
List messages in a space. opts: - :filter — server-side filter, e.g. "createTime > \"2026-01-01T00:00:00Z\"" - :order-by — "createTime" (default) or "createTime DESC" - :page-size — max messages per page (1–1000; default 25) - :page-token — token from a previous response - :show-deleted — boolean; include deleted/tombstoned messages - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(list-reactions client message-name & [opts])List reactions on a message.
opts:
List reactions on a message. opts: - :filter — server-side filter, e.g. "emoji.unicode = \"🎉\"" - :page-size — max reactions per page (1–200; default 25) - :page-token — token from a previous response - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(list-section-items client parent & [opts])List items in a sidebar section (3-level chain).
parent — "users/{user}/sections/{section}".
opts:
List items in a sidebar section (3-level chain).
parent — "users/{user}/sections/{section}".
opts:
- :filter — server-side filter
- :page-size — max items per page
- :page-token — token from a previous response
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(list-sections client parent & [opts])List a user's sidebar sections.
parent — "users/{user}".
opts:
List a user's sidebar sections.
parent — "users/{user}".
opts:
- :page-size — max sections per page
- :page-token — token from a previous response
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(list-space-events client space-name & [opts])List space events (audit/replay stream).
space-name — parent space resource name.
opts:
List space events (audit/replay stream). space-name — parent space resource name. opts: - :filter — REQUIRED server-side filter (event_types and start_time) - :page-size — max events per page (1–100; default 25) - :page-token — token from a previous response - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(list-spaces client & [opts])List spaces the authenticated user is a member of.
opts:
RESPONSE SHAPE — :space-type vs :type (consumers, please read):
Each Space in the response carries BOTH :space-type (current
Chat API enum: "DIRECT_MESSAGE" / "SPACE" / "GROUP_CHAT")
and :type (legacy enum: "DM" / "ROOM"). Filter on
:space-type for new code; :type is preserved for backward
compatibility with pre-migration callers. Picking the wrong key
yields a silent zero-match bug.
List spaces the authenticated user is a member of. opts: - :filter — server-side filter, e.g. "spaceType = \"SPACE\"" - :page-size — max spaces per page (1–1000; API default 100) - :page-token — token from a previous response - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout RESPONSE SHAPE — `:space-type` vs `:type` (consumers, please read): Each Space in the response carries BOTH `:space-type` (current Chat API enum: `"DIRECT_MESSAGE"` / `"SPACE"` / `"GROUP_CHAT"`) and `:type` (legacy enum: `"DM"` / `"ROOM"`). Filter on `:space-type` for new code; `:type` is preserved for backward compatibility with pre-migration callers. Picking the wrong key yields a silent zero-match bug.
(move-section-item client section-item-name request & [opts])Move an item to another section.
request — MoveSectionItemRequest map. Required: :target-section — destination section resource name ("users/{user}/sections/{section}")
opts:
Move an item to another section.
request — MoveSectionItemRequest map. Required:
:target-section — destination section resource name
("users/{user}/sections/{section}")
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(position-section client section-name request & [opts])Reorder a section in the user's sidebar.
request — PositionSectionRequest map. Required: :relative-position — "BEFORE" | "AFTER" | "FIRST" | "LAST" :sort-order — int sort order (used with :relative-position)
opts:
Reorder a section in the user's sidebar. request — PositionSectionRequest map. Required: :relative-position — "BEFORE" | "AFTER" | "FIRST" | "LAST" :sort-order — int sort order (used with :relative-position) opts: - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(replace-message client message-name message & [opts])Fully replace a message (PUT). Like update-message but omitted fields are cleared. :update-mask is required.
opts: identical to update-message.
Fully replace a message (PUT). Like update-message but omitted fields are cleared. :update-mask is required. opts: identical to update-message.
(search-spaces client & [opts])Search spaces across the Workspace organization (admin-only).
opts:
Search spaces across the Workspace organization (admin-only). opts: - :query — search query string (Chat search syntax) - :order-by — sort expression, e.g. "membershipCount.joinedDirectHumanUserCount desc" - :page-size — max spaces per page (1–1000; default 100) - :page-token — token from a previous response - :use-admin-access — boolean; required for search across the org - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(setup-space client request & [opts])Create a space and add initial members in one call.
request — map with kebab-case keys. Required: :space — Space map (display-name, space-type, etc.) :memberships — vector of Membership maps (each has :member {:name :type})
opts:
Create a space and add initial members in one call.
request — map with kebab-case keys. Required:
:space — Space map (display-name, space-type, etc.)
:memberships — vector of Membership maps (each has :member {:name :type})
opts:
- :fields — partial response field mask string
- :read-timeout-ms — int, override the HTTP client's default read timeout(update-membership client membership-name membership & [opts])Partially update a membership (PATCH). :update-mask is required. Allowed mask values: "role".
opts:
Partially update a membership (PATCH). :update-mask is required. Allowed mask values: "role". opts: - :update-mask — comma-separated field-path string (required) - :use-admin-access — boolean; act as a Workspace admin - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(update-message client message-name message & [opts])Partially update a message (PATCH). :update-mask is required. Allowed mask values: "text", "attachment", "cards", "cards_v2", "accessory_widgets".
opts:
Partially update a message (PATCH). :update-mask is required. Allowed mask values: "text", "attachment", "cards", "cards_v2", "accessory_widgets". opts: - :update-mask — comma-separated field-path string (required) - :allow-missing — boolean; if true, create the message when missing (upsert) - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(update-section client section-name section & [opts])Partially update a section (PATCH). :update-mask is required. Allowed mask values: "display_name", "items".
opts:
Partially update a section (PATCH). :update-mask is required. Allowed mask values: "display_name", "items". opts: - :update-mask — comma-separated field-path string (required) - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(update-space client space-name space & [opts])Partially update a space (PATCH). The :update-mask opt is REQUIRED — Chat's PATCH does not infer the mask from body fields. Common mask values: "displayName", "spaceDetails", "spaceType", "spaceHistoryState", "accessSettings.audience", "permissionSettings".
opts:
Partially update a space (PATCH). The :update-mask opt is REQUIRED — Chat's PATCH does not infer the mask from body fields. Common mask values: "displayName", "spaceDetails", "spaceType", "spaceHistoryState", "accessSettings.audience", "permissionSettings". opts: - :update-mask — comma-separated field-path string (required) - :use-admin-access — boolean; act as a Workspace admin - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(update-space-notification-setting client name setting & [opts])Partially update a user's notification setting for a space (PATCH). :update-mask is required. Allowed mask values: "notification_setting", "mute_setting".
opts:
Partially update a user's notification setting for a space (PATCH). :update-mask is required. Allowed mask values: "notification_setting", "mute_setting". opts: - :update-mask — comma-separated field-path string (required) - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(update-space-read-state client name space-read-state & [opts])Update a user's read state for a space (PATCH). :update-mask is required. Allowed mask values: "last_read_time".
opts:
Update a user's read state for a space (PATCH). :update-mask is required. Allowed mask values: "last_read_time". opts: - :update-mask — comma-separated field-path string (required) - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
(upload-media client space-name request content mime-type & [opts])Upload an attachment to a space for later inclusion in a message.
space-name — parent space resource name. request — UploadAttachmentRequest map. Required: :filename — filename for the attachment content — content to upload (java.io.File, InputStream, byte[], String). mime-type — content MIME type (required for InputStream and byte[]).
opts:
Upload an attachment to a space for later inclusion in a message. space-name — parent space resource name. request — UploadAttachmentRequest map. Required: :filename — filename for the attachment content — content to upload (java.io.File, InputStream, byte[], String). mime-type — content MIME type (required for InputStream and byte[]). opts: - :fields — partial response field mask string - :read-timeout-ms — int, override the HTTP client's default read timeout
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |