Help us shape the future of Go! Take the 2026 Go Developer Survey

googlechat

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package googlechat implements the Google Chat adapter for the orb chat gateway: an HTTP-endpoint Chat app with bearer-JWT-verified ingress, service-account authenticated delivery, and authenticated media download.

Inbound interaction events are verified against Google's published JWKS (issuer chat@system.gserviceaccount.com, audience = the numeric project number) before parsing; New refuses to construct without the audience or the service-account key, so neither trust boundary is skippable. Replies are always asynchronous via spaces.messages.create — the synchronous 200-body reply is deliberately never used. Final messages use client-assigned ids derived from the inbound event, making delivery idempotent and crash-safe. Google Chat has no typing indicator, so Typing is a no-op; D28 also keeps Preview final-only.

Index

Constants

View Source
const DefaultBaseURL = "https://chat.googleapis.com"

DefaultBaseURL is the production Chat API endpoint.

View Source
const DefaultCertURL = "https://www.googleapis.com/service_accounts/v1/jwk/chat@system.gserviceaccount.com"

DefaultCertURL serves the JWKS Google signs inbound app events with.

View Source
const DefaultTokenURL = "https://oauth2.googleapis.com/token"

DefaultTokenURL is the production OAuth2 token endpoint.

Variables

This section is empty.

Functions

func ChunkText

func ChunkText(text string, limit int) []string

ChunkText splits text into chunks of at most limit characters, preferring line boundaries and never splitting inside a code fence: the fence is closed at the chunk edge and reopened in the next chunk. A single line longer than the budget is hard-cut. Empty input yields no chunks.

func FormatText

func FormatText(markdown string) string

FormatText converts common markdown to Google Chat's dialect: **b**/__b__ → *b*, *i* → _i_, ~~s~~ → ~s~, [text](url) → <url|text>, headings → *bold* lines. Fenced code blocks are kept as triple-backtick blocks; the language token on the opening fence is dropped because Chat would display it literally. Lists, quotes, inline code, and plain underscores pass through unchanged (Chat renders them natively).

ponytail: line/regex transform, not a goldmark AST walk; markup inside inline code spans is rewritten too — accepted ceiling, matching the WhatsApp adapter.

Types

type APIError

type APIError struct {
	// HTTPStatus is the HTTP status code of the response.
	HTTPStatus int
	// Code is the numeric code from the error envelope (matches HTTPStatus
	// in practice).
	Code int
	// Status is the canonical gRPC status name, e.g. "NOT_FOUND",
	// "ALREADY_EXISTS", "RESOURCE_EXHAUSTED".
	Status string
	// Message is the server-provided description.
	Message string
	// RetryAfter is the Retry-After header delay when the server sent one.
	RetryAfter time.Duration
}

APIError is one Chat API error envelope ({"error":{"code":...,"message":...,"status":...}}).

func (*APIError) Error

func (e *APIError) Error() string

Error implements error.

type Adapter

type Adapter struct {
	// contains filtered or unexported fields
}

Adapter is the Google Chat implementation of chat.Adapter. Final and notification writes are serialized per space at the Chat API's 1/s quota.

func New

func New(opts Options) (*Adapter, error)

New builds the adapter. It refuses to construct without ProjectNumber (inbound events could not be verified) or a parseable service-account key (outbound calls could not be authenticated). It performs no network calls.

func (*Adapter) Account

func (a *Adapter) Account() string

Account returns the numeric project number — the Chat app's identity — matching the Account set on every normalized message.

func (*Adapter) Download

func (a *Adapter) Download(ctx context.Context, ref chat.AttachmentRef) (io.ReadCloser, string, error)

Download implements chat.Adapter: an authenticated GET /v1/media/{resourceName}?alt=media for UPLOADED_CONTENT attachments (the only kind ingress emits refs for; Drive-sourced files are not downloadable with the chat.bot scope and are surfaced as text notes).

func (*Adapter) NewDelivery

func (a *Adapter) NewDelivery(key chat.ConversationKey, replyTo string, resumePreviewID string) chat.Delivery

NewDelivery implements chat.Adapter. replyTo is the inbound message.name; the first final-message id is derived from it, so a crashed turn's retry addresses the same client-assigned message. Google Chat is final-only, so resumePreviewID is ignored.

func (*Adapter) Platform

func (a *Adapter) Platform() string

Platform implements chat.Adapter.

func (*Adapter) Webhook

func (a *Adapter) Webhook(publish func(chat.Message) error) http.Handler

Webhook returns the interaction-event endpoint handler. Every POST is authenticated by its bearer JWT (401 on failure) before the body is trusted. MESSAGE events are normalized and published; every other event type is acknowledged and ignored. The success response is always an empty 200 — replies happen asynchronously. A publish failure answers 500 so Google redelivers (the message.name EventID dedupes downstream).

type Options

type Options struct {
	// ProjectNumber is the numeric GCP project number (NOT the project id).
	// It is the required audience of every inbound event JWT. Required.
	ProjectNumber string
	// CredentialsJSON is the downloaded service-account key file
	// (client_email + private_key). It signs the outbound JWT-bearer
	// assertion for the chat.bot scope. Required.
	CredentialsJSON []byte
	// BaseURL overrides the Chat API endpoint (tests). Default
	// [DefaultBaseURL].
	BaseURL string
	// TokenURL overrides the OAuth2 token endpoint (tests). It is also the
	// aud claim of the signed assertion. Default [DefaultTokenURL].
	TokenURL string
	// CertURL overrides where the inbound-event JWKS is fetched from
	// (tests). Default [DefaultCertURL].
	CertURL string
	// HTTPClient overrides the HTTP client. Default: 30s timeout.
	HTTPClient *http.Client
	// Logger receives non-fatal diagnostics. Optional.
	Logger *slog.Logger
}

Options configures New.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL