---
description: Reference for authenticated Google Chat ingress from @flue/google-chat.
title: Google Chat Channel API | Flue
image: https://flueframework.com/docs/og4.jpg
---

# Google Chat Channel API

Last updated Jun 13, 2026 [ View as Markdown](https://flueframework.com/docs/api/google-chat-channel/index.md) 

Import from `@flue/google-chat`.

## `createGoogleChatChannel()`

```
function createGoogleChatChannel<E extends Env = Env>(
  options: GoogleChatChannelOptions<E>,
): GoogleChatChannel<E>;
```

Creates authenticated Google Chat callback routes. At least one of `interactions`or `workspaceEvents` is required. Omitted surfaces do not publish routes.

## `GoogleChatChannelOptions`

```
interface GoogleChatChannelOptions<E extends Env = Env> {
  interactions?: {
    authentication: GoogleChatInteractionAuthentication;
    handler(input: GoogleChatInteractionHandlerInput<E>): GoogleChatHandlerResult;
  };
  workspaceEvents?: {
    authentication: GoogleChatPubSubAuthentication;
    handler(input: GoogleChatWorkspaceEventHandlerInput<E>): GoogleChatHandlerResult;
  };
  fetch?: typeof globalThis.fetch;
  bodyLimit?: number;
}
```

| Field           | Description                                                                                     |
| --------------- | ----------------------------------------------------------------------------------------------- |
| interactions    | Authenticates and handles provider-native Google Chat interaction payloads.                     |
| workspaceEvents | Authenticates and handles wrapped Pub/Sub push deliveries from the Google Workspace Events API. |
| fetch           | Fetch implementation used only for Google signing-key discovery.                                |
| bodyLimit       | Positive integer request-body limit in bytes. Defaults to 1 MiB.                                |

## Callback inputs

```
interface GoogleChatInteractionHandlerInput<E extends Env = Env> {
  c: Context<E>;
  payload: GoogleChatInteraction;
}

interface GoogleChatWorkspaceEventHandlerInput<E extends Env = Env> {
  c: Context<E>;
  delivery: GoogleChatWorkspaceEventDelivery;
}
```

Interaction callbacks receive `{ c, payload }`; Workspace Event callbacks receive`{ c, delivery }`. `c` is the Hono context. `payload` and `delivery` preserve the provider-native request objects, including unknown fields and future event types.

## Callback results

```
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };

type GoogleChatHandlerResult =
  | undefined
  | JsonValue
  | Response
  | Promise<undefined | JsonValue | Response>;
```

Returning `undefined` produces an empty `200` response. A `JsonValue` produces a JSON response. A Hono or Fetch `Response` passes through unchanged. Callback errors propagate to Hono error handling.

Before invoking a callback, the route returns an empty response with:

* `400` for malformed JSON or an invalid provider envelope;
* `401` for missing or invalid authentication;
* `403` when a Pub/Sub delivery names a different subscription;
* `413` when the declared or streamed body exceeds `bodyLimit`; or
* `415` unless the media type is `application/json`.

## Interaction authentication

```
type GoogleChatInteractionAuthentication =
  | {
      type: 'endpoint-url';
      audience: string;
      jwksUrl?: string;
    }
  | {
      type: 'project-number';
      projectNumber: string;
      certificatesUrl?: string;
    };
```

`endpoint-url` verifies a Google OIDC token addressed to the exact configured HTTPS endpoint URL and issued for `chat@system.gserviceaccount.com`.`project-number` verifies a Google Chat service token addressed to the configured numeric project number using the Chat service-account certificates.

`jwksUrl` and `certificatesUrl` override Google discovery endpoints for supported environments and local protocol tests.

## Pub/Sub authentication

```
interface GoogleChatPubSubAuthentication {
  subscription: string;
  audience: string;
  serviceAccountEmail: string;
  jwksUrl?: string;
}
```

`subscription` is the exact`projects/<project>/subscriptions/<subscription>` resource required in the push body. The bearer token must have the configured audience and verified service account email. `jwksUrl` overrides Google’s OIDC JWKS endpoint.

## Provider wire types

```
type GoogleChatInteractionType =
  | 'MESSAGE'
  | 'ADDED_TO_SPACE'
  | 'REMOVED_FROM_SPACE'
  | 'CARD_CLICKED'
  | 'APP_COMMAND'
  | 'APP_HOME'
  | 'SUBMIT_FORM'
  | 'WIDGET_UPDATED'
  | (string & {});

interface GoogleChatInteraction {
  type: GoogleChatInteractionType;
  eventTime?: string;
  user?: GoogleChatUser;
  space?: GoogleChatSpace;
  message?: GoogleChatMessage;
  thread?: GoogleChatThread;
  action?: GoogleChatAction;
  appCommandMetadata?: Record<string, unknown>;
  common?: Record<string, unknown>;
  [key: string]: unknown;
}
```

```
type GoogleChatSpaceType = 'SPACE' | 'GROUP_CHAT' | 'DIRECT_MESSAGE' | (string & {});

type GoogleChatDeprecatedSpaceType = 'ROOM' | 'DM' | (string & {});

interface GoogleChatSpace {
  name?: string;
  spaceType?: GoogleChatSpaceType;
  type?: GoogleChatDeprecatedSpaceType;
  [key: string]: unknown;
}

interface GoogleChatThread {
  name?: string;
  [key: string]: unknown;
}

interface GoogleChatUser {
  name?: string;
  displayName?: string;
  type?: string;
  domainId?: string;
  [key: string]: unknown;
}

interface GoogleChatMessage {
  name?: string;
  text?: string;
  argumentText?: string;
  formattedText?: string;
  space?: GoogleChatSpace;
  thread?: GoogleChatThread;
  attachment?: readonly unknown[];
  annotations?: readonly unknown[];
  [key: string]: unknown;
}

interface GoogleChatAction {
  actionMethodName?: string;
  parameters?: readonly {
    key?: string;
    value?: string;
    [key: string]: unknown;
  }[];
  [key: string]: unknown;
}
```

Workspace Events remain wrapped in the Pub/Sub push body:

```
interface GoogleChatWorkspaceEventDelivery {
  message: GoogleChatPubSubMessage;
  subscription: string;
  deliveryAttempt?: number;
  [key: string]: unknown;
}

interface GoogleChatPubSubMessage {
  attributes: GoogleChatCloudEventAttributes;
  data: string;
  messageId: string;
  publishTime?: string;
  orderingKey?: string;
  [key: string]: unknown;
}

interface GoogleChatCloudEventAttributes {
  'ce-datacontenttype': 'application/json';
  'ce-id': string;
  'ce-source': string;
  'ce-specversion': '1.0';
  'ce-subject': string;
  'ce-type': GoogleChatWorkspaceEventType;
  'ce-time'?: string;
  [key: string]: string | undefined;
}
```

```
type GoogleChatWorkspaceEventType =
  | 'google.workspace.chat.message.v1.created'
  | 'google.workspace.chat.message.v1.updated'
  | 'google.workspace.chat.message.v1.deleted'
  | 'google.workspace.chat.message.v1.batchCreated'
  | 'google.workspace.chat.message.v1.batchUpdated'
  | 'google.workspace.chat.message.v1.batchDeleted'
  | 'google.workspace.chat.membership.v1.created'
  | 'google.workspace.chat.membership.v1.updated'
  | 'google.workspace.chat.membership.v1.deleted'
  | 'google.workspace.chat.membership.v1.batchCreated'
  | 'google.workspace.chat.membership.v1.batchUpdated'
  | 'google.workspace.chat.membership.v1.batchDeleted'
  | 'google.workspace.chat.reaction.v1.created'
  | 'google.workspace.chat.reaction.v1.deleted'
  | 'google.workspace.chat.reaction.v1.batchCreated'
  | 'google.workspace.chat.reaction.v1.batchDeleted'
  | 'google.workspace.chat.space.v1.updated'
  | 'google.workspace.chat.space.v1.deleted'
  | 'google.workspace.chat.space.v1.batchUpdated'
  | 'google.workspace.events.subscription.v1.suspended'
  | 'google.workspace.events.subscription.v1.expirationReminder'
  | 'google.workspace.events.subscription.v1.expired'
  | (string & {});
```

`message.data` remains the provider’s base64-encoded JSON string; the channel validates it but does not replace it with a decoded or normalized event.

## `GoogleChatChannel`

```
interface ChannelRoute<E extends Env = Env> {
  readonly method: string;
  readonly path: string;
  readonly handler: Handler<E>;
}

interface GoogleChatChannel<E extends Env = Env> {
  readonly routes: readonly ChannelRoute<E>[];
  conversationKey(ref: GoogleChatConversationRef): string;
  parseConversationKey(id: string): GoogleChatConversationRef;
}
```

`interactions` publishes exactly `POST /interactions`; `workspaceEvents`publishes exactly `POST /events`. `routes` contains only configured surfaces. In`channels/google-chat.ts`, these become`POST /channels/google-chat/interactions` and`POST /channels/google-chat/events`, relative to the `flue()` mount.

## Conversation identity

```
interface GoogleChatConversationRef {
  space: string;
  thread?: string;
  spaceType?: GoogleChatSpaceType;
}
```

`space` must use `spaces/<id>`. `thread`, when present, must use`spaces/<id>/threads/<thread-id>` and belong to the same space. Canonical keys encode only `space` and `thread`; `spaceType` is descriptive and does not affect the key. Keys are identifiers, not authorization capabilities.

`conversationKey()` throws `InvalidGoogleChatInputError` for an invalid reference.`parseConversationKey()` accepts only canonical keys produced by`conversationKey()` and throws `InvalidGoogleChatConversationKeyError` otherwise.

## Errors

```
class InvalidGoogleChatInputError extends TypeError {
  readonly field: string;
}

class InvalidGoogleChatConversationKeyError extends TypeError {}
```

`InvalidGoogleChatInputError` reports invalid channel options and conversation references through `field`. An invalid `bodyLimit` throws `TypeError`.

## Docs Navigation

Current page: [Google Chat Channel API](https://flueframework.com/docs/api/google-chat-channel/)

### Sections

* [Guide](https://flueframework.com/docs/getting-started/quickstart/)
* [Reference](https://flueframework.com/docs/api/agent-api/)
* [CLI](https://flueframework.com/docs/cli/overview/)
* [SDK](https://flueframework.com/docs/sdk/overview/)
* [Ecosystem](https://flueframework.com/docs/ecosystem/)

### Runtime

* [ Configuration ](https://flueframework.com/docs/reference/configuration/)
* [ Errors Reference ](https://flueframework.com/docs/api/errors-reference/)
* [ Agent API ](https://flueframework.com/docs/api/agent-api/)
* [ Provider API ](https://flueframework.com/docs/api/provider-api/)
* [ Routing API ](https://flueframework.com/docs/api/routing-api/)
* [ GitHub Channel ](https://flueframework.com/docs/api/github-channel/)
* [ Stripe Channel ](https://flueframework.com/docs/api/stripe-channel/)
* [ Notion Channel ](https://flueframework.com/docs/api/notion-channel/)
* [ Resend Channel ](https://flueframework.com/docs/api/resend-channel/)
* [ Shopify Channel ](https://flueframework.com/docs/api/shopify-channel/)
* [ Intercom Channel ](https://flueframework.com/docs/api/intercom-channel/)
* [ Zendesk Channel ](https://flueframework.com/docs/api/zendesk-channel/)
* [ Salesforce Marketing Cloud Channel ](https://flueframework.com/docs/api/salesforce-marketing-cloud-channel/)
* [ Slack Channel ](https://flueframework.com/docs/api/slack-channel/)
* [ Discord Channel ](https://flueframework.com/docs/api/discord-channel/)
* [ Teams Channel ](https://flueframework.com/docs/api/teams-channel/)
* [ Google Chat Channel ](https://flueframework.com/docs/api/google-chat-channel/)
* [ Linear Channel ](https://flueframework.com/docs/api/linear-channel/)
* [ Telegram Channel ](https://flueframework.com/docs/api/telegram-channel/)
* [ WhatsApp Channel ](https://flueframework.com/docs/api/whatsapp-channel/)
* [ Twilio Channel ](https://flueframework.com/docs/api/twilio-channel/)
* [ Messenger Channel ](https://flueframework.com/docs/api/messenger-channel/)
* [ Streaming Protocol ](https://flueframework.com/docs/api/streaming-protocol/)
* [ Events Reference ](https://flueframework.com/docs/api/events-reference/)

### Advanced

* [ Sandbox Adapter API ](https://flueframework.com/docs/api/sandbox-api/)
* [ Data Persistence API ](https://flueframework.com/docs/api/data-persistence-api/)