跳转到内容

输入关键词开始搜索文档。

Google Chat

最后更新 查看 Markdown 源文件@flue/google-chat

快速开始

通过 Google Chat 蓝图,将经过认证的交互、可选的 Workspace 事件和项目自有的出站消息添加到现有 Flue 项目中。在终端或你选择的编码智能体中运行以下命令:

flue add channel google-chat

概述

该蓝图安装 @flue/google-chat 和 jose。它在 <source-root>/lib/google-chat-client.ts 创建一个窄范围的服务账号 Fetch 客户端,在 <source-root>/channels/google-chat.ts 创建命名的 channel 和项目自有的 client 导出。它还会创建或更新一个智能体,将消息工具绑定到可信的 Google Chat 空间。此集成用于 Google Chat API,而非 Google Workspace Events API。

src/channels/google-chat.ts(节选)
import { createGoogleChatChannel } from '@flue/google-chat';
import { dispatch, useModel } from '@flue/runtime';
import { Assistant } from '../agents/assistant.ts';
import { createGoogleChatClient } from '../lib/google-chat-client.ts';

export const client = createGoogleChatClient({
  serviceAccountKey: JSON.parse(process.env.GOOGLE_CHAT_SERVICE_ACCOUNT_KEY!),
  subject: process.env.GOOGLE_CHAT_SUBJECT,
});

export const channel = createGoogleChatChannel({
  audience: process.env.GOOGLE_CHAT_AUDIENCE!,
  async message({ event }) {
    if (event.type !== 'MESSAGE') return;
    const spaceId = event.space?.name;
    if (!spaceId) return;

    await dispatch(Assistant, {
      id: channel.instanceId(spaceId),
      message: {
        kind: 'signal',
        type: 'google-chat.message',
        body: event.message?.text ?? '',
        attributes: {
          spaceId,
          threadId: event.message?.thread?.name,
        },
      },
    });
  },
});

新消息会被接收进绑定到该空间的智能体;其他事件类型被忽略。完整的生成模块还处理卡片交互,并让绑定的智能体通过 Google Chat REST API 发布消息。Node 和 Cloudflare 目标使用相同的 Fetch 和 Web Crypto 实现。

挂载渠道

渠道仅在 app.ts 挂载的位置提供 HTTP 路由。挂载模块中命名导出的 channel:

src/app.ts
import { channel as googleChat } from './channels/google-chat.ts';

app.route('/channels/google-chat', googleChat.route());

channel.route() 是一个纯路由器工厂,相对于挂载路径提供渠道声明的路由。本指南中的 webhook 路径假定使用常规的 /channels/google-chat 挂载;不同的挂载路径会相应调整。分发目标智能体模块携带 'use agent' 指令——该指令负责注册,因此仅用于分发的智能体不需要自己的 HTTP 挂载。

配置

变量用途
GOOGLE_CHAT_SERVICE_ACCOUNT_KEY必需 — Google 服务账号 JSON 密钥。
GOOGLE_CHAT_AUDIENCE必需 — 验证入站消息的受众。
GOOGLE_CHAT_SUBJECT可选 — 模拟用户的电子邮件地址。

它安装 @flue/google-chat 和 jose。蓝图创建一个渠道模块,导出命名的 channel 和项目自有的 client。

在 Google Cloud Console 中配置服务账号:

  1. 创建或选择一个 Google Cloud 项目
  2. 启用 Google Chat API
  3. 创建服务账号并下载 JSON 密钥
  4. 在 Google Chat API 配置中设置服务账号为机器人

将 webhook URL 配置为:

https://example.com/channels/google-chat/events

服务账号密钥和受众是单独的凭据。

渠道模块

src/channels/google-chat.ts
import { createGoogleChatChannel } from '@flue/google-chat';
import { defineTool, dispatch, useModel } from '@flue/runtime';
import { Assistant } from '../agents/assistant.ts';
import { createGoogleChatClient } from '../lib/google-chat-client.ts';

export const client = createGoogleChatClient({
  serviceAccountKey: JSON.parse(process.env.GOOGLE_CHAT_SERVICE_ACCOUNT_KEY!),
  subject: process.env.GOOGLE_CHAT_SUBJECT,
});

export const channel = createGoogleChatChannel({
  audience: process.env.GOOGLE_CHAT_AUDIENCE!,

  // 路径:/channels/google-chat/events
  async message({ event }) {
    // `event.type` 是 Google Chat 事件类型。
    // 过滤是应用策略:在 Google Chat 中配置你想要的事件。
    if (event.type === 'MESSAGE') {
      const spaceId = event.space?.name;
      if (!spaceId) return;

      await dispatch(Assistant, {
        id: channel.instanceId(spaceId),
        message: {
          kind: 'signal',
          type: 'google-chat.message',
          body: event.message?.text ?? '',
          attributes: {
            spaceId,
            threadId: event.message?.thread?.name,
          },
        },
      });
      return;
    }

    if (event.type === 'CARD_CLICKED') {
      // 卡片交互可以触发操作。
      return;
    }
  },
});

export function sendMessage(ref: { spaceId: string }) {
  return defineTool({
    name: 'send_google_chat_message',
    description: '向绑定到此智能体的 Google Chat 空间发送消息。',
    input: v.object({ text: v.pipe(v.string(), v.minLength(1)) }),
    async run({ data: { text } }) {
      const result = await client.spaces.messages.create({
        parent: ref.spaceId,
        requestBody: { text },
      });
      return { output: { messageId: result.data.name } };
    },
  });
}

每个经过验证的消息都会以其原生的 Google Chat 事件结构转发。事件保留 Google 自己的字段名称和嵌套。选择对哪些事件采取行动是应用策略——在 Google Chat 中配置它们,并在处理程序中根据 event.type 进行分支。

绑定工具

src/agents/assistant.ts
'use agent';
import { useInitialData, useModel, useTool } from '@flue/runtime';
import { sendMessage } from '../channels/google-chat.ts';

const initialData = v.object({ spaceId: v.string() });

export function Assistant() {
  useModel('anthropic/claude-haiku-4-5');
  const data = useInitialData<v.InferOutput<typeof initialData>>();
  if (!data) throw new Error('此智能体由 Google Chat 渠道分发创建。');
  useTool(sendMessage(data));
  return '向绑定的 Google Chat 空间发布简洁的回答。';
}

Assistant.initialData = initialData;

模型选择消息内容。它不选择任意的 Google Chat 空间、凭据或 REST 方法。此工具创建普通的空间消息。工具接受来自可信应用代码的 spaceId。

交付和运行时行为

Google Chat 事件交付是至少一次的。该渠道是无状态的,不会对事件进行去重。在不允许重复接收时,在分发之前在应用自有的持久存储中声明事件 ID。

该包在 Node 和 Cloudflare Workers 上运行,需要 Flue 的 nodejs_compat 设置。

参阅 @flue/google-chat README。