Skip to main content
OpenClaw 的 Google Meet 参与者支持——该插件的设计是显式的:
  • 它只加入显式的 https://meet.google.com/... URL。
  • 它可以通过 Google Meet API 创建一个新的 Meet 空间,然后加入返回的 URL。
  • agent 是默认的回话模式:实时转录监听,配置的 OpenClaw 代理作答,常规 OpenClaw TTS 将语音送入 Meet。
  • bidi 仍然作为回退的直接实时语音模型模式可用。
  • 代理通过 mode 选择加入行为:使用 agent 进行实时监听/回话,使用 bidi 作为直接实时语音回退,或使用 transcribe 在不通过回话桥的情况下加入/控制浏览器。
  • 身份验证从个人 Google OAuth 或已经登录的 Chrome 配置文件开始。
  • 没有自动的同意公告。
  • 默认的 Chrome 音频后端是 BlackHole 2ch
  • Chrome 可以在本地运行,也可以在配对的节点主机上运行。
  • Twilio 接受拨入号码以及可选的 PIN 或 DTMF 序列;它不能直接拨打 Meet URL。
  • CLI 命令是 googlemeetmeet 保留给更广泛的代理电话会议工作流。

快速开始

安装本地音频依赖,并配置实时转录提供商以及常规 OpenClaw TTS。OpenAI 是默认的转录提供商;Google Gemini Live 也可作为单独的 bidi 语音回退使用,配置项为 realtime.voiceProvider: "google"
brew install blackhole-2ch sox
export OPENAI_API_KEY=sk-...
# 仅在 bidi 模式下 realtime.voiceProvider 为 "google" 时需要
export GEMINI_API_KEY=...
blackhole-2ch 会安装 BlackHole 2ch 虚拟音频设备。Homebrew 的安装程序要求在 macOS 显示该设备之前重启:
sudo reboot
重启后,验证两部分都已就绪:
system_profiler SPAudioDataType | grep -i BlackHole
command -v sox
启用插件:
{
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {},
      },
    },
  },
}
检查设置:
openclaw googlemeet setup
设置输出旨在便于代理读取,并且与模式相关。它会报告 Chrome 配置文件、节点绑定,以及对于实时 Chrome 加入时的 BlackHole/SoX 音频 桥接和延迟的实时介绍检查。对于仅观察加入,请使用 --mode transcribe 检查相同传输;该模式会跳过实时音频前提条件, 因为它不会通过桥接监听或发言:
openclaw googlemeet setup --transport chrome-node --mode transcribe
当配置了 Twilio 委派时,设置也会报告 voice-call 插件、Twilio 凭据和公共 webhook 暴露是否已准备就绪。将任何 ok: false 检查视为该传输和模式的阻塞条件,然后再让代理加入。脚本或机器可读输出请使用 openclaw googlemeet setup --json。在代理尝试加入之前,可使用 --transport chrome--transport chrome-node--transport twilio 预检特定传输。 对于 Twilio,当默认传输是 Chrome 时,始终显式预检该传输:
openclaw googlemeet setup --transport twilio
这样可以在代理尝试拨入会议之前,捕获缺失的 voice-call 连接、Twilio 凭据或不可达的 webhook 暴露。 加入会议:
openclaw googlemeet join https://meet.google.com/abc-defg-hij
或者让代理通过 google_meet 工具加入:
{
  "action": "join",
  "url": "https://meet.google.com/abc-defg-hij",
  "transport": "chrome-node",
  "mode": "agent"
}
面向代理的 google_meet 工具在非 macOS 主机上仍可用于 artifact、calendar、setup、transcribe、Twilio 和 chrome-node 流程。由于捆绑的 Chrome 音频路径 当前依赖 macOS 的 BlackHole 2ch,本地 Chrome 回话操作在这些主机上会被阻止。在 Linux 上,请使用 mode: "transcribe"、Twilio 拨入,或在 macOS 的 chrome-node 主机上进行 Chrome 回话 参与。 创建一个新会议并加入它:
openclaw googlemeet create --transport chrome-node --mode agent
对于 API 创建的房间,当你希望房间的免敲门策略显式设置,而不是继承自 Google 账号默认值时,请使用 Google Meet 的 SpaceConfig.accessType
openclaw googlemeet create --access-type OPEN --transport chrome-node --mode agent
OPEN 允许任何拥有 Meet URL 的人无需敲门即可加入。TRUSTED 允许宿主组织的受信任用户、受邀请的外部用户和拨入用户无需敲门即可加入。RESTRICTED 将免敲门访问限制为受邀者。这些设置仅适用于官方 Google Meet API 创建路径,因此必须配置 OAuth 凭据。 如果你在此选项可用之前已经对 Google Meet 完成了身份验证,请在将 meetings.space.settings 作用域添加到你的 Google OAuth 同意屏幕后,重新运行 openclaw googlemeet auth login --json 仅创建 URL 而不加入:
openclaw googlemeet create --no-join
googlemeet create 有两条路径:
  • API 创建:在已配置 Google Meet OAuth 凭据时使用。这是最可预测的路径,并且不依赖浏览器 UI 状态。
  • 浏览器回退:在缺少 OAuth 凭据时使用。OpenClaw 会使用固定的 Chrome 节点,打开 https://meet.google.com/new,等待 Google 重定向到真实的会议代码 URL,然后返回该 URL。此路径要求节点上的 OpenClaw Chrome 配置文件已经登录 Google。浏览器自动化会处理 Meet 自己首次运行时的麦克风提示;该提示不被视为 Google 登录失败。 加入和创建流程也会尝试在打开新标签页之前复用现有的 Meet 标签页。匹配会忽略无害的 URL 查询字符串,例如 authuser,因此代理重试时应聚焦已打开的会议,而不是创建第二个 Chrome 标签页。
命令/工具输出包含一个 source 字段(apibrowser),以便代理说明使用了哪条路径。create 默认会加入新会议,并返回 joined: true 以及加入会话。若只想生成 URL,请在 CLI 上使用 create --no-join,或向工具传入 "join": false 或者告诉代理:“创建一个 Google Meet,使用代理回话模式加入,并把链接发给我。” 代理应调用 google_meet,使用 action: "create",然后共享返回的 meetingUri
{
  "action": "create",
  "transport": "chrome-node",
  "mode": "agent"
}
对于仅观察/仅浏览器控制的加入,请设置 "mode": "transcribe"。这不会 启动双工实时语音桥,不需要 BlackHole 或 SoX, 也不会在会议中回话。在该模式下通过 Chrome 加入也会避免 OpenClaw 的麦克风/摄像头权限授予,并避免 Meet 的 Use microphone 路径。如果 Meet 显示音频选择插页,自动化会尝试 无麦克风路径,否则会报告手动操作,而不是打开本地麦克风。在 transcribe 模式下,受管的 Chrome 传输还会安装一个尽力而为的 Meet 字幕观察器。googlemeet status --jsongooglemeet doctor 会显示 captioningcaptionsEnabledAttemptedtranscriptLineslastCaptionAtlastCaptionSpeakerlastCaptionText, 以及较短的 recentTranscript 末尾片段,以便操作人员判断浏览器 是否已加入通话,以及 Meet 字幕是否正在生成文本。 当你需要一个是/否探测时,请使用 openclaw googlemeet test-listen <meet-url> --transport chrome-node:它会以 transcribe 模式加入,等待新的字幕或转录变化,并返回 listenVerifiedlistenTimedOut、手动操作字段以及最新的字幕健康状态。 在实时会话期间,google_meet 状态会包含浏览器和音频桥健康信息,例如 inCallmanualActionRequiredproviderConnectedrealtimeReadyaudioInputActiveaudioOutputActive、最后输入/输出时间戳、字节计数器以及桥接关闭状态。如果出现安全的 Meet 页面提示,浏览器自动化会在可处理时予以处理。登录、主持人接纳以及浏览器/操作系统权限提示会以人工操作的形式报告,并附带原因和消息,供代理转述。受管的 Chrome 会话只有在浏览器健康状态报告 inCall: true 后才会输出介绍语或测试短语;否则状态会报告 speechReady: false,并且语音尝试会被阻止,而不是假装代理已经在会议中发言。 本地 Chrome 加入通过已登录的 OpenClaw 浏览器配置文件进行。实时模式需要 BlackHole 2ch 作为 OpenClaw 使用的麦克风/扬声器路径。要获得干净的双工音频,请使用分离的虚拟设备或类似 Loopback 的图形;单个 BlackHole 设备足以用于首次冒烟测试,但可能会回声。

本地网关 + Parallels Chrome

不需要在 macOS 虚拟机内拥有完整的 OpenClaw Gateway 或模型 API 密钥,只是为了让该虚拟机拥有 Chrome。先在本地运行 Gateway 和代理,然后在虚拟机中运行节点主机。只需在虚拟机中启用捆绑插件一次,这样节点就会公布 Chrome 命令: 运行位置说明:
  • Gateway 主机:OpenClaw Gateway、代理工作区、模型/API 密钥、实时提供商,以及 Google Meet 插件配置。
  • Parallels macOS 虚拟机:OpenClaw CLI/节点主机、Google Chrome、SoX、BlackHole 2ch,以及已登录 Google 的 Chrome 配置文件。
  • 虚拟机中不需要:Gateway 服务、代理配置、OpenAI/GPT 密钥或模型提供商设置。
安装虚拟机依赖:
brew install blackhole-2ch sox
安装 BlackHole 后重启虚拟机,以便 macOS 显示 BlackHole 2ch
sudo reboot
重启后,验证虚拟机可以看到音频设备和 SoX 命令:
system_profiler SPAudioDataType | grep -i BlackHole
command -v sox
在虚拟机中安装或更新 OpenClaw,然后在那里启用捆绑插件:
openclaw plugins enable google-meet
在虚拟机中启动节点主机:
openclaw node run --host <gateway-host> --port 18789 --display-name parallels-macos
如果 <gateway-host> 是局域网 IP 且你未使用 TLS,那么除非你为该受信任的私有网络显式允许,否则节点会拒绝明文 WebSocket:
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos
在将节点作为 LaunchAgent 安装时也使用同样的环境变量:
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node install --host <gateway-lan-ip> --port 18789 --display-name parallels-macos --force
openclaw node restart
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 是进程环境变量,不是 openclaw.json 设置。openclaw node install 会在安装命令中存在该变量时把它存入 LaunchAgent 环境。 在 Gateway 主机上批准该节点:
openclaw devices list
openclaw devices approve <requestId>
确认 Gateway 看到了该节点,并且它同时公布了 googlemeet.chrome 和浏览器能力/browser.proxy
openclaw nodes status
在 Gateway 主机上通过该节点路由 Meet:
{
  gateway: {
    nodes: {
      allowCommands: ["googlemeet.chrome", "browser.proxy"],
    },
  },
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {
          defaultTransport: "chrome-node",
          chrome: {
            guestName: "OpenClaw Agent",
            autoJoin: true,
            reuseExistingTab: true,
          },
          chromeNode: {
            node: "parallels-macos",
          },
        },
      },
    },
  },
}
现在从 Gateway 主机正常加入:
openclaw googlemeet join https://meet.google.com/abc-defg-hij
或者让代理使用带有 transport: "chrome-node"google_meet 工具。 要进行一次单命令冒烟测试,创建或复用一个会话、说出一个已知短语并打印会话健康状态:
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij
在实时加入期间,OpenClaw 浏览器自动化会填写访客姓名,点击 Join/Ask to join,并在该提示出现时接受 Meet 首次运行的 “Use microphone” 选项。在仅观察加入或仅浏览器的会议创建期间,它会在该提示之后继续前进,并在可用时不使用麦克风。如果浏览器配置文件未登录、Meet 正在等待主持人接纳、Chrome 在实时加入时需要麦克风/摄像头权限,或者 Meet 卡在自动化无法解决的提示上,加入/test-speech 结果会报告 manualActionRequired: true,并附带 manualActionReasonmanualActionMessage。代理应停止重试加入,报告该精确消息以及当前的 browserUrl/browserTitle,并且仅在手动浏览器操作完成后再重试。 如果省略了 chromeNode.node,只有在恰好一个已连接节点同时公布 googlemeet.chrome 和浏览器控制时,OpenClaw 才会自动选择。如果连接了多个可用节点,请将 chromeNode.node 设为节点 id、显示名称或远程 IP。 常见故障检查:
  • Configured Google Meet node ... is not usable: offline:固定节点已被 Gateway 识别,但不可用。代理应将该节点视为诊断状态,而不是可用的 Chrome 主机,并报告设置阻塞,而不是在用户未要求的情况下回退到其他传输方式。
  • No connected Google Meet-capable node:在虚拟机中启动 openclaw node run,批准配对,并确保在虚拟机中运行了 openclaw plugins enable google-meetopenclaw plugins enable browser。同时确认 Gateway 主机允许这两个节点命令,使用 gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]
  • BlackHole 2ch audio device not found:在被检查的主机上安装 blackhole-2ch,并在使用本地 Chrome 音频前重启。
  • BlackHole 2ch audio device not found on the node:在虚拟机中安装 blackhole-2ch 并重启虚拟机。
  • Chrome 打开了但无法加入:在虚拟机内登录浏览器配置文件,或者保持 chrome.guestName 用于访客加入。访客自动加入通过节点浏览器代理使用 OpenClaw 浏览器自动化;确保节点浏览器配置指向你想使用的配置文件,例如 browser.defaultProfile: "user" 或一个命名的现有会话配置文件。
  • 重复的 Meet 标签页:保持 chrome.reuseExistingTab: true 启用。OpenClaw 会在打开新标签页之前激活同一 Meet URL 的现有标签页,而浏览器会议创建也会在打开另一个标签页前复用一个正在进行中的 https://meet.google.com/new 或 Google 账号提示标签页。
  • 没有音频:在 Meet 中,将麦克风/扬声器路由通过 OpenClaw 使用的虚拟音频设备路径;对于干净的双工音频,请使用分离的虚拟设备或 Loopback 风格的路由。

安装说明

Chrome talk-back 的默认配置使用两个外部工具:
  • sox:命令行音频工具。该插件使用明确的 CoreAudio 设备命令,为默认的 24 kHz PCM16 音频桥提供支持。
  • blackhole-2ch:macOS 虚拟音频驱动。它会创建 BlackHole 2ch 音频设备,供 Chrome/Meet 路由音频使用。
OpenClaw 不捆绑也不转售这两个包。文档要求用户通过 Homebrew 将它们作为宿主依赖安装。SoX 的许可证是 LGPL-2.0-only AND GPL-2.0-only;BlackHole 的许可证是 GPL-3.0。若你构建的安装程序或设备将 BlackHole 与 OpenClaw 一起打包,请查阅 BlackHole 的上游许可条款,或从 Existential Audio 获取单独许可。

传输方式

Chrome

Chrome 传输会通过 OpenClaw 浏览器控制打开 Meet URL,并以已登录的 OpenClaw 浏览器配置文件身份加入会议。在 macOS 上,该插件会在启动前检查是否存在 BlackHole 2ch。如果已配置,它还会在打开 Chrome 前运行音频桥健康检查命令和启动命令。当 Chrome/音频运行在 Gateway 主机上时使用 chrome;当 Chrome/音频运行在配对节点上时(例如 Parallels macOS VM)使用 chrome-node。对于本地 Chrome,使用 browser.defaultProfile 选择配置文件;chrome.browserProfile 会传递给 chrome-node 主机。
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome-node
将 Chrome 的麦克风和扬声器音频通过本地 OpenClaw 音频桥路由。如果未安装 BlackHole 2ch,加入会失败并返回设置错误,而不会静默地在没有音频路径的情况下加入。

Twilio

Twilio 传输是一个由 Voice Call 插件托管的严格拨号计划。它不会解析 Meet 页面中的电话号码。 当无法使用 Chrome 参会,或者你希望通过电话拨入作为备用方案时,请使用此方式。Google Meet 必须为该会议公开电话拨入号码和 PIN;OpenClaw 不会从 Meet 页面中自动发现这些信息。 在 Gateway 主机上启用 Voice Call 插件,而不是在 Chrome 节点上启用:
{
  plugins: {
    allow: ["google-meet", "voice-call", "google"],
    entries: {
      "google-meet": {
        enabled: true,
        config: {
          defaultTransport: "chrome-node",
          // 或者设置为 "twilio" 作为默认值
        },
      },
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio",
          inboundPolicy: "allowlist",
          realtime: {
            enabled: true,
            provider: "google",
            instructions: "Join this Google Meet as an OpenClaw agent. Be brief.",
            toolPolicy: "safe-read-only",
            providers: {
              google: {
                silenceDurationMs: 500,
                startSensitivity: "high",
              },
            },
          },
        },
      },
      google: {
        enabled: true,
      },
    },
  },
}
通过环境变量或配置提供 Twilio 凭据。使用环境变量可以避免将密钥写入 openclaw.json
export TWILIO_ACCOUNT_SID=AC...
export TWILIO_AUTH_TOKEN=...
export TWILIO_FROM_NUMBER=+15550001234
export GEMINI_API_KEY=...
如果你的实时语音提供方是 OpenAI,请改用 OpenAI provider 插件和 OPENAI_API_KEY,并设置 realtime.provider: "openai" 启用 voice-call 后,请重启或重新加载 Gateway;插件配置变更在现有运行中的 Gateway 进程重新加载前不会生效。 然后验证:
openclaw config validate
openclaw plugins list | grep -E 'google-meet|voice-call'
openclaw googlemeet setup
当 Twilio 委派已连接时,googlemeet setup 会包含成功的 twilio-voice-call-plugintwilio-voice-call-credentialstwilio-voice-call-webhook 检查。
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --pin 123456
当会议需要自定义序列时,使用 --dtmf-sequence
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --dtmf-sequence ww123456#

## OAuth 和预检

创建 Meet 链接时,OAuth 不是必需的,因为 `googlemeet create` 可以回退到浏览器自动化。若你希望使用官方 API 创建、空间解析或 Meet Media API 预检检查,则配置 OAuth。

Google Meet API 访问使用用户 OAuth:创建 Google Cloud OAuth 客户端,申请所需作用域,授权一个 Google 账号,然后将生成的刷新令牌存储在 Google Meet 插件配置中,或者提供 `OPENCLAW_GOOGLE_MEET_*` 环境变量。

OAuth 并不会替代 Chrome 加入路径。当你使用浏览器参会时,Chrome Chrome-node 传输仍会通过已登录的 Chrome 配置文件、BlackHole/SoX 以及连接的节点加入。OAuth 仅用于官方 Google Meet API 路径:创建会议空间、解析空间以及运行 Meet Media API 预检检查。

### 创建 Google 凭据

 Google Cloud Console 中:

1. 创建或选择一个 Google Cloud 项目。
2. 为该项目启用 **Google Meet REST API**。
3. 配置 OAuth 同意屏幕。
   - Google Workspace 组织而言,**Internal** 最简单。
   - **External** 适用于个人/测试环境;在应用处于 Testing 期间,将每个会授权该应用的 Google 账号添加为测试用户。
4. 添加 OpenClaw 请求的作用域:
   - `https://www.googleapis.com/auth/meetings.space.created`
   - `https://www.googleapis.com/auth/meetings.space.readonly`
   - `https://www.googleapis.com/auth/meetings.space.settings`
   - `https://www.googleapis.com/auth/meetings.conference.media.readonly`
5. 创建一个 OAuth 客户端 ID。
   - 应用类型:**Web application**。
   - 授权重定向 URI:

     ```text
     http://localhost:8085/oauth2callback
  1. 复制客户端 ID 和客户端密钥。
meetings.space.created 是 Google Meet spaces.create 所需的权限。 meetings.space.readonly 允许 OpenClaw 将 Meet URL/代码解析为空间。 meetings.space.settings 允许 OpenClaw 在通过 API 创建房间时传递 accessTypeSpaceConfig 设置。 meetings.conference.media.readonly 用于 Meet Media API 预检和媒体 相关工作;Google 在实际使用 Media API 时可能要求加入 Developer Preview。 如果你只需要基于浏览器的 Chrome 加入,可完全跳过 OAuth。

获取刷新令牌

配置 oauth.clientId,并可选地配置 oauth.clientSecret,或者将它们作为环境变量传入,然后运行:
openclaw googlemeet auth login --json
该命令会输出一个包含刷新令牌的 oauth 配置块。它使用 PKCE、http://localhost:8085/oauth2callback 的本地回调,以及 --manual 的手动复制/粘贴流程。 示例:
OPENCLAW_GOOGLE_MEET_CLIENT_ID="your-client-id" \
OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \
openclaw googlemeet auth login --json
当浏览器无法访问本地回调时,使用手动模式:
OPENCLAW_GOOGLE_MEET_CLIENT_ID="your-client-id" \
OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \
openclaw googlemeet auth login --json --manual
JSON 输出包含:
{
  "oauth": {
    "clientId": "your-client-id",
    "clientSecret": "your-client-secret",
    "refreshToken": "refresh-token",
    "accessToken": "access-token",
    "expiresAt": 1770000000000
  },
  "scope": "..."
}
oauth 对象存储到 Google Meet 插件配置下:
{
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {
          oauth: {
            clientId: "your-client-id",
            clientSecret: "your-client-secret",
            refreshToken: "refresh-token",
          },
        },
      },
    },
  },
}
当你不希望将刷新令牌写入配置时,优先使用环境变量。 如果配置和值两者都存在,插件会先解析配置,然后再使用环境变量作为回退。 OAuth 同意包含 Meet 空间创建、Meet 空间读取以及 Meet 会议媒体读取权限。如果你是在支持会议创建之前完成授权的,请重新运行 openclaw googlemeet auth login --json,以使刷新令牌具备 meetings.space.created 作用域。

使用 doctor 验证 OAuth

当你需要快速、非敏感的健康检查时,运行 OAuth doctor:
openclaw googlemeet doctor --oauth --json
这不会加载 Chrome 运行时,也不需要连接的 Chrome 节点。它会检查 OAuth 配置是否存在,以及刷新令牌是否可以生成访问令牌。JSON 报告仅包含诸如 okconfiguredtokenSourceexpiresAt 和检查消息等状态字段;不会打印访问令牌、刷新令牌或客户端密钥。 常见结果:
检查含义
oauth-config存在 oauth.clientIdoauth.refreshToken,或存在缓存的访问令牌。
oauth-token缓存的访问令牌仍然有效,或刷新令牌已生成新的访问令牌。
meet-spaces-get可选的 --meeting 检查已解析一个现有 Meet 空间。
meet-spaces-create可选的 --create-space 检查已创建一个新的 Meet 空间。
要同时证明 Google Meet API 已启用以及 spaces.create 作用域可用,请运行会产生副作用的创建检查:
openclaw googlemeet doctor --oauth --create-space --json
openclaw googlemeet create --no-join --json
--create-space 会创建一个一次性的 Meet URL。当你需要确认 Google Cloud 项目已启用 Meet API,并且已授权的账号具备 meetings.space.created 作用域时,可使用此项。 要证明对现有会议空间的读取权限:
openclaw googlemeet doctor --oauth --meeting https://meet.google.com/abc-defg-hij --json
openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
doctor --oauth --meetingresolve-space 可证明已授权的 Google 账号对现有空间拥有读取权限。这些检查返回 403,通常意味着 Google Meet REST API 被禁用、已同意的刷新令牌缺少所需作用域,或者该 Google 账号无法访问该 Meet 空间。刷新令牌错误则表示需要重新运行 openclaw googlemeet auth login --json 并保存新的 oauth 块。 浏览器回退模式不需要 OAuth 凭据。在该模式下,Google 认证来自所选节点上已登录的 Chrome 配置文件,而不是来自 OpenClaw 配置。 接受以下环境变量作为回退:
  • OPENCLAW_GOOGLE_MEET_CLIENT_IDGOOGLE_MEET_CLIENT_ID
  • OPENCLAW_GOOGLE_MEET_CLIENT_SECRETGOOGLE_MEET_CLIENT_SECRET
  • OPENCLAW_GOOGLE_MEET_REFRESH_TOKENGOOGLE_MEET_REFRESH_TOKEN
  • OPENCLAW_GOOGLE_MEET_ACCESS_TOKENGOOGLE_MEET_ACCESS_TOKEN
  • OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_ATGOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT
  • OPENCLAW_GOOGLE_MEET_DEFAULT_MEETINGGOOGLE_MEET_DEFAULT_MEETING
  • OPENCLAW_GOOGLE_MEET_PREVIEW_ACKGOOGLE_MEET_PREVIEW_ACK
通过 spaces.get 解析 Meet URL、代码或 spaces/{id}
openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
在媒体工作之前运行预检:
openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
在 Meet 创建会议记录后,列出会议工件和出席情况:
openclaw googlemeet artifacts --meeting https://meet.google.com/abc-defg-hij
openclaw googlemeet attendance --meeting https://meet.google.com/abc-defg-hij
openclaw googlemeet export --meeting https://meet.google.com/abc-defg-hij --output ./meet-export
使用 --meeting 时,artifactsattendance 默认使用最新的会议记录。当你希望获取该会议保留的每一条记录时,传入 --all-conference-records 在读取 Meet 工件之前,日历查询可以先从 Google Calendar 解析会议 URL:
openclaw googlemeet latest --today
openclaw googlemeet calendar-events --today --json
openclaw googlemeet artifacts --event "Weekly sync"
openclaw googlemeet attendance --today --format csv --output attendance.csv
--today 会在今天的 primary 日历中搜索带有 Google Meet 链接的日历事件。使用 --event <query> 搜索匹配的事件文本,使用 --calendar <id> 指定非主日历。日历查询需要一次包含 Calendar events readonly 作用域的最新 OAuth 登录。 calendar-events 会预览匹配的 Meet 事件,并标记 latestartifactsattendanceexport 将会选择的事件。 如果你已经知道会议记录 ID,可以直接指定:
openclaw googlemeet latest --meeting https://meet.google.com/abc-defg-hij
openclaw googlemeet artifacts --conference-record conferenceRecords/abc123 --json
openclaw googlemeet attendance --conference-record conferenceRecords/abc123 --json
在通话结束后,要关闭通过 API 创建的空间中的活动会议,请结束活动会议:
openclaw googlemeet end-active-conference https://meet.google.com/abc-defg-hij
这会调用 Google Meet spaces.endActiveConference,并要求 OAuth 具备 meetings.space.created 作用域,且该空间可由已授权账号管理。 OpenClaw 接受 Meet URL、会议代码或 spaces/{id} 输入,并在结束活动会议前将其解析为 API 空间资源。 这与 googlemeet leave 是分开的:leave 会停止 OpenClaw 的本地/会话参与,而 end-active-conference 则请求 Google Meet 结束该空间的活动会议。 编写一份可读报告:
openclaw googlemeet artifacts --conference-record conferenceRecords/abc123 \
  --format markdown --output meet-artifacts.md
openclaw googlemeet attendance --conference-record conferenceRecords/abc123 \
  --format markdown --output meet-attendance.md
openclaw googlemeet attendance --conference-record conferenceRecords/abc123 \
  --format csv --output meet-attendance.csv
openclaw googlemeet export --conference-record conferenceRecords/abc123 \
  --include-doc-bodies --zip --output meet-export
openclaw googlemeet export --conference-record conferenceRecords/abc123 \
  --include-doc-bodies --dry-run
artifacts 会返回会议记录元数据,以及参与者、录制、转录、结构化转录条目和智能笔记资源元数据(如果 Google 对该会议提供了这些内容)。对于大型会议,使用 --no-transcript-entries 可跳过条目查询。attendance 会将参与者展开为 participant-session 行,包含首次/最后出现时间、总会话时长、迟到/早退标记,以及按已登录用户或显示名称合并的重复参与者资源。传入 --no-merge-duplicates 可保留原始参与者资源,传入 --late-after-minutes 可调整迟到检测,传入 --early-before-minutes 可调整早退检测。 export 会写入一个文件夹,内含 summary.mdattendance.csvtranscript.mdartifacts.jsonattendance.jsonmanifest.jsonmanifest.json 会记录所选输入、导出选项、会议记录、输出文件、计数、令牌来源、所用的 Calendar 事件(如果有),以及任何部分获取警告。传入 --zip 还会在文件夹旁边生成一个便携式压缩包。传入 --include-doc-bodies 会通过 Google Drive files.export 导出关联的转录和智能笔记 Google Docs 文本;这需要一次包含 Drive Meet readonly 作用域的最新 OAuth 登录。不使用 --include-doc-bodies 时,导出仅包含 Meet 元数据和结构化转录条目。如果 Google 返回部分工件失败,例如智能笔记列表、转录条目或 Drive 文档正文错误,摘要和清单会保留警告,而不会导致整个导出失败。 使用 --dry-run 可获取相同的工件/出席数据并打印清单 JSON,而不创建文件夹或 ZIP。这在你需要在写出大型导出之前检查,或者代理只需要计数、所选记录和警告时非常有用。 代理也可以通过 google_meet 工具创建相同的捆绑包:
{
  "action": "export",
  "conferenceRecord": "conferenceRecords/abc123",
  "includeDocumentBodies": true,
  "outputDir": "meet-export",
  "zip": true
}
设置 "dryRun": true 可仅返回导出清单并跳过文件写入。 代理还可以创建一个带显式访问策略的 API 支持会议室:
{
  "action": "create",
  "transport": "chrome-node",
  "mode": "agent",
  "accessType": "OPEN"
}
并且可以结束已知会议室的活动会议:
{
  "action": "end_active_conference",
  "meeting": "https://meet.google.com/abc-defg-hij"
}
对于先监听再验证的场景,代理在声明会议可用之前应先使用 test_listen
{
  "action": "test_listen",
  "url": "https://meet.google.com/abc-defg-hij",
  "transport": "chrome-node",
  "timeoutMs": 30000
}
对真实保留会议运行受保护的 live smoke 测试:
OPENCLAW_LIVE_TEST=1 \
OPENCLAW_GOOGLE_MEET_LIVE_MEETING=https://meet.google.com/abc-defg-hij \
pnpm test:live -- extensions/google-meet/google-meet.live.test.ts
对一个有人发言且可用 Meet 字幕的会议运行 live listen-first 浏览器探测:
openclaw googlemeet setup --transport chrome-node --mode transcribe
openclaw googlemeet test-listen https://meet.google.com/abc-defg-hij --transport chrome-node --timeout-ms 30000
Live smoke 环境:
  • OPENCLAW_LIVE_TEST=1 启用受保护的 live 测试。
  • OPENCLAW_GOOGLE_MEET_LIVE_MEETING 指向一个保留的 Meet URL、代码或 spaces/{id}
  • OPENCLAW_GOOGLE_MEET_CLIENT_IDGOOGLE_MEET_CLIENT_ID 提供 OAuth 客户端 ID。
  • OPENCLAW_GOOGLE_MEET_REFRESH_TOKENGOOGLE_MEET_REFRESH_TOKEN 提供 刷新令牌。
  • 可选:OPENCLAW_GOOGLE_MEET_CLIENT_SECRETOPENCLAW_GOOGLE_MEET_ACCESS_TOKEN 以及 OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT 使用与 OPENCLAW_ 前缀相同的回退名称。
基础的工件/出席 live smoke 需要 https://www.googleapis.com/auth/meetings.space.readonlyhttps://www.googleapis.com/auth/meetings.conference.media.readonly。日历 查询需要 https://www.googleapis.com/auth/calendar.events.readonly。Drive 文档正文导出需要 https://www.googleapis.com/auth/drive.meet.readonly 创建一个新的 Meet 空间:
openclaw googlemeet create
该命令会输出新的 meeting uri、来源和加入会话。使用 OAuth 凭据时,它会使用官方 Google Meet API。没有 OAuth 凭据时,它会回退到已固定的 Chrome 节点中已登录的浏览器配置文件。代理可以使用 google_meet 工具并设置 action: "create" 来一步完成创建和加入。若只需创建 URL,不加入,请传入 "join": false 浏览器回退的 JSON 输出示例:
{
  "source": "browser",
  "meetingUri": "https://meet.google.com/abc-defg-hij",
  "joined": true,
  "browser": {
    "nodeId": "ba0f4e4bc...",
    "targetId": "tab-1"
  },
  "join": {
    "session": {
      "id": "meet_...",
      "url": "https://meet.google.com/abc-defg-hij"
    }
  }
}
如果浏览器回退在创建 URL 之前遇到 Google 登录或 Meet 权限阻塞,Gateway 方法会返回失败响应,而 google_meet 工具会返回结构化详情,而不是简单字符串:
{
  "source": "browser",
  "error": "google-login-required: Sign in to Google in the OpenClaw browser profile, then retry meeting creation.",
  "manualActionRequired": true,
  "manualActionReason": "google-login-required",
  "manualActionMessage": "Sign in to Google in the OpenClaw browser profile, then retry meeting creation.",
  "browser": {
    "nodeId": "ba0f4e4bc...",
    "targetId": "tab-1",
    "browserUrl": "https://accounts.google.com/signin",
    "browserTitle": "Sign in - Google Accounts"
  }
}
当代理看到 manualActionRequired: true 时,应报告 manualActionMessage 以及浏览器节点/标签页上下文,并在操作员完成浏览器步骤之前停止打开新的 Meet 标签页。 API 创建的 JSON 输出示例:
{
  "source": "api",
  "meetingUri": "https://meet.google.com/abc-defg-hij",
  "joined": true,
  "space": {
    "name": "spaces/abc-defg-hij",
    "meetingCode": "abc-defg-hij",
    "meetingUri": "https://meet.google.com/abc-defg-hij"
  },
  "join": {
    "session": {
      "id": "meet_...",
      "url": "https://meet.google.com/abc-defg-hij"
    }
  }
}
创建 Meet 时默认会加入会议。Chrome 或 Chrome-node 传输仍然需要已登录的 Google Chrome 配置文件才能通过浏览器加入。如果配置文件已退出登录,OpenClaw 会报告 manualActionRequired: true 或浏览器回退错误,并要求操作员先完成 Google 登录后再重试。 只有在确认你的 Cloud 项目、OAuth 主体以及会议参与者已加入 Google Workspace Developer Preview Program 的 Meet media APIs 后,才将 preview.enrollmentAcknowledged: true 设为 true。

配置

通用的 Chrome agent 路径只需要启用插件、BlackHole、SoX、一个实时转录提供商密钥,以及一个已配置的 OpenClaw TTS 提供商。OpenAI 是默认的转录提供商;将 realtime.voiceProvider 设置为 "google" 并将 realtime.model 设置为在 bidi 模式下使用 Google Gemini Live,而不会更改默认的 agent 模式转录提供商:
brew install blackhole-2ch sox
export OPENAI_API_KEY=sk-...
# 或者
export GEMINI_API_KEY=...
plugins.entries.google-meet.config 下设置插件配置:
{
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {},
      },
    },
  },
}
默认值:
  • defaultTransport: "chrome"
  • defaultMode: "agent" ("realtime" 仅作为 "agent" 的旧版兼容别名接受;新的工具调用应使用 "agent")
  • chromeNode.node: chrome-node 的可选节点 id/名称/IP
  • chrome.audioBackend: "blackhole-2ch"
  • chrome.guestName: "OpenClaw Agent":在未登录的 Meet 来宾界面上使用的名称
  • chrome.autoJoin: true:通过 OpenClaw 浏览器自动化在 chrome-node 上尽最大努力填充来宾名称并点击 Join Now
  • chrome.reuseExistingTab: true:激活现有的 Meet 标签页,而不是打开重复标签页
  • chrome.waitForInCallMs: 20000:在触发对话开场前,等待 Meet 标签页报告已进入通话
  • chrome.audioFormat: "pcm16-24khz":命令对命令音频格式。仅对仍输出电话音频的旧版/自定义命令对使用 "g711-ulaw-8khz"
  • chrome.audioBufferBytes: 4096:用于生成 Chrome 命令对音频命令的 SoX 处理缓冲区。这是 SoX 默认 8192 字节缓冲区的一半,在保留忙碌主机上可调高空间的同时降低默认管道延迟。低于 SoX 最小值的值会被钳制为 17 字节。
  • chrome.audioInputCommand:从 CoreAudio BlackHole 2ch 读取并以 chrome.audioFormat 写入音频的 SoX 命令
  • chrome.audioOutputCommand:以 chrome.audioFormat 读取音频并写入 CoreAudio BlackHole 2ch 的 SoX 命令
  • chrome.bargeInInputCommand:可选的本地麦克风命令,在助手播放活动时写出有符号 16 位小端单声道 PCM,用于检测人工插话。目前这适用于 Gateway 托管的 chrome 命令对桥接。
  • chrome.bargeInRmsThreshold: 650:在 chrome.bargeInInputCommand 上被视为人工打断的 RMS 电平
  • chrome.bargeInPeakThreshold: 2500:在 chrome.bargeInInputCommand 上被视为人工打断的峰值电平
  • chrome.bargeInCooldownMs: 900:重复人工打断清除之间的最小延迟
  • mode: "agent":默认的对话回传模式。参与者语音由配置的实时转录提供商转写,发送到每个会议对应的 OpenClaw agent 子代理会话,并通过常规的 OpenClaw TTS 运行时播回。
  • mode: "bidi":回退的直接双向实时模型模式。实时语音提供商直接回答参与者语音,并且可以调用 openclaw_agent_consult 获取更深入/由工具支持的答案。
  • mode: "transcribe":仅观察模式,不使用对话回传桥接。
  • realtime.provider: "openai":当下面作用域内的提供商字段未设置时使用的兼容性回退。
  • realtime.transcriptionProvider: "openai"agent 模式下用于实时转录的提供商 id。
  • realtime.voiceProviderbidi 模式下用于直接实时语音的提供商 id。将其设为 "google" 可在保持 agent 模式转录使用 OpenAI 的同时使用 Gemini Live。
  • realtime.toolPolicy: "safe-read-only"
  • realtime.instructions:简短的口头回复,并在需要更深入答案时使用 openclaw_agent_consult
  • realtime.introMessage:实时桥接连接时的简短口头就绪检查;将其设为 "" 可静默加入
  • realtime.agentId:用于 openclaw_agent_consult 的可选 OpenClaw agent id;默认值为 main
可选覆盖项:
{
  defaults: {
    meeting: "https://meet.google.com/abc-defg-hij",
  },
  browser: {
    defaultProfile: "openclaw",
  },
  chrome: {
    guestName: "OpenClaw Agent",
    waitForInCallMs: 30000,
    bargeInInputCommand: [
      "sox",
      "-q",
      "-t",
      "coreaudio",
      "External Microphone",
      "-r",
      "24000",
      "-c",
      "1",
      "-b",
      "16",
      "-e",
      "signed-integer",
      "-t",
      "raw",
      "-",
    ],
  },
  chromeNode: {
    node: "parallels-macos",
  },
  defaultMode: "agent",
  realtime: {
    provider: "openai",
    transcriptionProvider: "openai",
    voiceProvider: "google",
    model: "gemini-2.5-flash-native-audio-preview-12-2025",
    agentId: "jay",
    toolPolicy: "owner",
    introMessage: "请准确说:I'm here.",
    providers: {
      google: {
        speakerVoice: "Kore",
      },
    },
  },
}
ElevenLabs 同时用于 agent 模式的听和说:
{
  messages: {
    tts: {
      provider: "elevenlabs",
      providers: {
        elevenlabs: {
          modelId: "eleven_v3",
          speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
        },
      },
    },
  },
  plugins: {
    entries: {
      "google-meet": {
        config: {
          realtime: {
            transcriptionProvider: "elevenlabs",
            providers: {
              elevenlabs: {
                modelId: "scribe_v2_realtime",
                audioFormat: "ulaw_8000",
                sampleRate: 8000,
                commitStrategy: "vad",
              },
            },
          },
        },
      },
    },
  },
}
持久化的 Meet 声音来自 messages.tts.providers.elevenlabs.speakerVoiceId。在启用 TTS 模型覆盖时,agent 回复也可以使用按回复的 [[tts:speakerVoiceId=... model=eleven_v3]] 指令,但配置是会议的确定性默认值。加入时,日志应显示 transcriptionProvider=elevenlabs,并且每条口语回复都应记录 provider=elevenlabs model=eleven_v3 speakerVoiceId=<voiceId> 仅 Twilio 配置:
{
  defaultTransport: "twilio",
  twilio: {
    defaultDialInNumber: "+15551234567",
    defaultPin: "123456",
  },
  voiceCall: {
    gatewayUrl: "ws://127.0.0.1:18789",
  },
}
voiceCall.enabled 默认为 true;在使用 Twilio 传输时,它会将实际的 PSTN 呼叫、DTMF 以及引导问候语委托给 Voice Call 插件。Voice Call 会在打开实时媒体流之前播放 DTMF 序列,然后使用已保存的引导文本作为初始实时问候语。如果未启用 voice-call,Google Meet 仍然可以验证并记录拨号计划,但无法发起 Twilio 呼叫。

工具

Agent 可以使用 google_meet 工具:
{
  "action": "join",
  "url": "https://meet.google.com/abc-defg-hij",
  "transport": "chrome-node",
  "mode": "agent"
}
当 Chrome 运行在 Gateway 主机上时使用 transport: "chrome"。当 Chrome 运行在配对节点上(例如 Parallels 虚拟机)时使用 transport: "chrome-node"。在这两种情况下,模型提供商和 openclaw_agent_consult 都运行在 Gateway 主机上,因此模型凭据保留在那里。使用默认的 mode: "agent" 时,实时转录提供商负责监听,配置的 OpenClaw agent 生成答案,并通过常规 OpenClaw TTS 将其播入 Meet。想让实时语音模型直接回答时,使用 mode: "bidi"。原始的 mode: "realtime" 仍作为 mode: "agent" 的旧版兼容别名被接受,但不再在 agent 工具 schema 中对外宣传。Agent 模式日志会在桥接启动时包含解析后的转录提供商/模型,并在每次合成回复后包含 TTS 提供商、模型、语音、输出格式和采样率。 使用 action: "status" 可列出活动会话或检查某个会话 ID。使用 action: "speak" 并提供 sessionIdmessage,可让实时 agent 立即发言。使用 action: "test_speech" 可创建或复用会话、触发已知短语,并在 Chrome 主机能够报告时返回 inCall 健康状态。test_speech 总是强制使用 mode: "agent",如果要求在 mode: "transcribe" 下运行则会失败,因为仅观察会话本来就不能发声。其 speechOutputVerified 结果基于本次测试调用期间实时音频输出字节数是否增加,因此复用了旧音频的会话不算一次新的成功发声检查。使用 action: "leave" 可标记会话结束。 status 在可用时包含 Chrome 健康状态:
  • inCall: Chrome 看起来已进入 Meet 通话
  • micMuted: 尽力获取的 Meet 麦克风状态
  • manualActionRequired / manualActionReason / manualActionMessage: 在语音工作前,浏览器配置文件需要手动登录、Meet 主持人准入、权限或浏览器控制修复
  • speechReady / speechBlockedReason / speechBlockedMessage: 当前是否允许托管的 Chrome 语音。speechReady: false 表示 OpenClaw 没有把引导/测试短语发送到音频桥接中。
  • providerConnected / realtimeReady: 实时语音桥接状态
  • lastInputAt / lastOutputAt: 来自桥接或发送到桥接的最近音频
  • audioOutputRouted / audioOutputDeviceLabel: Meet 标签页的媒体输出是否正在主动路由到桥接使用的 BlackHole 设备
  • lastSuppressedInputAt / suppressedInputBytes: 助手播放活动时被忽略的回环输入
{
  "action": "speak",
  "sessionId": "meet_...",
  "message": "请准确说:I'm here and listening."
}

Agent 和 bidi 模式

Chrome 的 agent 模式针对“我的 agent 在会议中”的行为进行了优化。实时转录提供商监听会议音频,最终的参与者转录会被路由到配置的 OpenClaw agent,答案则通过常规 OpenClaw TTS 运行时播出。当你希望实时语音模型直接回答时,设置 mode: "bidi"。 在咨询之前,会将附近的最终转录片段合并,因此一次发言不会产生多个过时的部分答案。实时输入在排队的助手音频仍在播放时也会被抑制,而且在 agent 咨询之前会忽略最近类似助手的转录回声,这样 BlackHole 回环就不会让 agent 回答自己的语音。
模式谁决定答案语音输出路径何时使用
agent配置的 OpenClaw agent常规 OpenClaw TTS 运行时你想要“我的 agent 在会议中”的行为时
bidi实时语音模型实时语音提供商音频响应你想要最低延迟的会话式语音循环时
bidi 模式下,当实时模型需要更深层推理、当前信息或常规 OpenClaw 工具时,它可以调用 openclaw_agent_consult 咨询工具会在幕后使用常规 OpenClaw agent,并结合最近的会议转录上下文运行,然后返回简洁的口头答案。在 agent 模式下,OpenClaw 会直接将该答案发送到 TTS 运行时;在 bidi 模式下,实时语音模型可以将咨询结果播回会议中。它使用与 Voice Call 相同的共享咨询机制。 默认情况下,咨询会针对 main agent 运行。当某个 Meet 通道应咨询专用的 OpenClaw agent 工作区、模型默认值、工具策略、记忆和会话历史时,设置 realtime.agentId Agent 模式下的 consult 会使用每个会议一个的 agent:<id>:subagent:google-meet:<session> 会话 key,因此后续问题可以保留会议上下文,同时继承所配置 agent 的常规策略。 realtime.toolPolicy 控制 consult 运行:
  • safe-read-only:暴露咨询工具,并将常规 agent 限制为 readweb_searchweb_fetchx_searchmemory_searchmemory_get
  • owner:暴露咨询工具,并允许常规 agent 使用正常的 agent 工具策略。
  • none:不向实时语音模型暴露咨询工具。
咨询会话 key 按 Meet 会话进行作用域隔离,因此后续的咨询调用可以在同一会议期间复用先前的咨询上下文。 要在 Chrome 完整加入通话后强制进行一次口头就绪检查:
openclaw googlemeet speak meet_... "请准确说:I'm here and listening."
完整的加入并发言冒烟测试:
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
  --transport chrome-node \
  --message "请准确说:I'm here and listening."

实地测试清单

在把会议交给无人值守 agent 之前,使用以下顺序:
openclaw googlemeet setup
openclaw nodes status
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
  --transport chrome-node \
  --message "请准确说:Google Meet speech test complete."
预期的 Chrome-node 状态:
  • googlemeet setup 全部为绿色。
  • 当 Chrome-node 是默认传输或节点被固定时,googlemeet setup 包含 chrome-node-connected
  • nodes status 显示所选节点已连接。
  • 所选节点同时声明 googlemeet.chromebrowser.proxy
  • Meet 标签页加入通话,并且 test-speech 返回的 Chrome 健康状态包含 inCall: true
对于诸如 Parallels macOS 虚拟机之类的远程 Chrome 主机,在更新 Gateway 或虚拟机后,这是最短的安全检查:
openclaw googlemeet setup
openclaw nodes status --connected
openclaw nodes invoke \
  --node parallels-macos \
  --command googlemeet.chrome \
  --params '{"action":"setup"}'
这证明 Gateway 插件已加载、虚拟机节点已使用当前 token 连接,并且在 agent 打开真实会议标签页之前,Meet 音频桥可用。 对于 Twilio 冒烟测试,使用一个提供电话拨入详情的会议:
openclaw googlemeet setup
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --pin 123456
预期的 Twilio 状态:
  • googlemeet setup 包含绿色的 twilio-voice-call-plugintwilio-voice-call-credentialstwilio-voice-call-webhook 检查。
  • Gateway 重新加载后,CLI 中可用 voicecall
  • 返回的会话包含 transport: "twilio" 和一个 twilio.voiceCallId
  • openclaw logs --follow 显示在实时 TwiML 之前已提供 DTMF TwiML,然后是一个带有已排队初始问候语的实时桥接。
  • googlemeet leave <sessionId> 会挂断委托的语音呼叫。

故障排查

Agent 无法看到 Google Meet 工具

确认插件已在 Gateway 配置中启用,然后重新加载 Gateway:
openclaw plugins list | grep google-meet
openclaw googlemeet setup
如果你刚刚编辑了 plugins.entries.google-meet,请重启或重新加载 Gateway。 运行中的 agent 只能看到由当前 Gateway 进程注册的插件工具。 在非 macOS 的 Gateway 主机上,面向 agent 的 google_meet 工具仍然可见, 但本地 Chrome 对话回传操作会在到达音频桥之前被阻止。 本地 Chrome 对话回传音频目前依赖 macOS 的 BlackHole 2ch,因此 Linux agent 应使用 mode: "transcribe"、Twilio 拨入,或 macOS chrome-node 主机,而不是默认的本地 Chrome agent 路径。

No connected Google Meet-capable node

在节点主机上运行:
openclaw plugins enable google-meet
openclaw plugins enable browser
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos
在 Gateway 主机上,批准节点并验证命令:
openclaw devices list
openclaw devices approve <requestId>
openclaw nodes status
节点必须已连接,并列出 googlemeet.chrome 以及 browser.proxy。 Gateway 配置必须允许这些节点命令:
{
  gateway: {
    nodes: {
      allowCommands: ["browser.proxy", "googlemeet.chrome"],
    },
  },
}
如果 googlemeet setup 失败并出现 chrome-node-connected,或者 Gateway 日志报告 gateway token mismatch,请使用当前 Gateway token 重新安装或重启节点。对于 LAN Gateway,这通常意味着:
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node install \
  --host <gateway-lan-ip> \
  --port 18789 \
  --display-name parallels-macos \
  --force
然后重新加载节点服务并再次运行:
openclaw googlemeet setup
openclaw nodes status --connected

浏览器打开了,但 agent 无法加入

对仅观察加入运行 googlemeet test-listen,或对实时加入运行 googlemeet test-speech,然后检查返回的 Chrome 健康状态。如果任一探测报告 manualActionRequired: true,请向操作员展示 manualActionMessage,并在浏览器操作完成前停止重试。 常见的人工操作:
  • 登录 Chrome 配置文件。
  • 从 Meet 主持人账户中接纳来宾。
  • 当 Chrome 原生权限提示出现时,授予 Chrome 麦克风/摄像头权限。
  • 关闭或修复卡住的 Meet 权限对话框。
不要仅仅因为 Meet 显示“Do you want people to hear you in the meeting?” 就报告“未登录”。那是 Meet 的音频选择中间页;OpenClaw 在可用时会通过浏览器自动化点击 Use microphone,并继续等待真实的会议状态。对于仅创建的浏览器回退路径,OpenClaw 可能会点击 Continue without microphone,因为创建 URL 不需要实时音频路径。

创建会议失败

当配置了 OAuth 凭据时,googlemeet create 会首先使用 Google Meet API 的 spaces.create 端点。没有 OAuth 凭据时,它会回退到固定的 Chrome 节点浏览器。确认:
  • 对于 API 创建:已配置 oauth.clientIdoauth.refreshToken,或者存在匹配的 OPENCLAW_GOOGLE_MEET_* 环境变量。
  • 对于 API 创建:刷新令牌是在添加创建支持之后签发的。较旧的令牌可能缺少 meetings.space.created 作用域;请重新运行 openclaw googlemeet auth login --json 并更新插件配置。
  • 对于浏览器回退:defaultTransport: "chrome-node"chromeNode.node 指向一个已连接的节点,该节点具有 browser.proxygooglemeet.chrome
  • 对于浏览器回退:该节点上的 OpenClaw Chrome 配置文件已登录 Google,并且可以打开 https://meet.google.com/new
  • 对于浏览器回退:重试会在打开新标签页之前复用现有的 https://meet.google.com/new 或 Google 账号提示标签页。如果 agent 超时,请重试工具调用,而不是手动打开另一个 Meet 标签页。
  • 对于浏览器回退:如果工具返回 manualActionRequired: true,请使用返回的 browser.nodeIdbrowser.targetIdbrowserUrlmanualActionMessage 来指导操作员。在该操作完成之前不要循环重试。
  • 对于浏览器回退:如果 Meet 显示“Do you want people to hear you in the meeting?”,请保持标签页打开。OpenClaw 应该通过浏览器自动化点击 Use microphone,或者在仅创建回退路径中点击 Continue without microphone,并继续等待生成的 Meet URL。如果做不到,错误信息应提到 meet-audio-choice-required,而不是 google-login-required

Agent 加入了但不说话

检查实时路径:
openclaw googlemeet setup
openclaw googlemeet doctor
对于正常的 STT -> OpenClaw agent -> TTS 对话回传路径,使用 mode: "agent", 对于直接实时语音回退路径,使用 mode: "bidi"mode: "transcribe" 故意不会启动对话回传桥。对于仅观察调试, 在参与者发言后运行 openclaw googlemeet status --json <session-id>, 并检查 captioningtranscriptLineslastCaptionText。如果 inCall 为 true 但 transcriptLines 仍为 0,可能是 Meet 字幕已禁用、在观察器安装后没有人 发言、Meet UI 已更改,或者实时字幕对会议语言/账号不可用。 googlemeet test-speech 始终检查实时路径,并报告本次调用是否观察到了桥接输出字节。如果 speechOutputVerified 为 false 且 speechOutputTimedOut 为 true,实时提供方可能已经接受了该语句,但 OpenClaw 没有看到新的输出字节到达 Chrome 音频桥。 另外还要验证:
  • Gateway 主机上可用实时提供方密钥,例如 OPENAI_API_KEYGEMINI_API_KEY
  • Chrome 主机上可见 BlackHole 2ch
  • Chrome 主机上存在 sox
  • Meet 麦克风和扬声器通过 OpenClaw 使用的虚拟音频路径路由。doctor 对本地 Chrome 实时加入应显示 meet output routed: yes
googlemeet doctor [session-id] 会打印会话、节点、通话中状态、手动操作原因、实时提供方连接、realtimeReady、音频输入/输出活动、最近音频时间戳、字节计数以及浏览器 URL。需要原始 JSON 时使用 googlemeet status [session-id] --json。需要验证 Google Meet OAuth 刷新但不暴露 token 时使用 googlemeet doctor --oauth;如果还需要 Google Meet API 证明,则加上 --meeting--create-space 如果某个 agent 超时了,而你能看到一个 Meet 标签页已经打开,请检查那个标签页,不要再打开另一个:
openclaw googlemeet recover-tab
openclaw googlemeet recover-tab https://meet.google.com/abc-defg-hij
对应的工具动作是 recover_current_tab。它会为所选传输方式聚焦并检查一个已存在的 Meet 标签页。对于 chrome,它通过 Gateway 使用本地浏览器控制;对于 chrome-node,它使用已配置的 Chrome 节点。它不会打开新标签页或创建新会话;它会报告当前阻塞因素,例如登录、接纳、权限或音频选择状态。CLI 命令会与已配置的 Gateway 通信,因此 Gateway 必须正在运行;chrome-node 还要求 Chrome 节点已连接。

Twilio 设置检查失败

当未允许或未启用 voice-call 时,twilio-voice-call-plugin 会失败。将其加入 plugins.allow,启用 plugins.entries.voice-call,然后重新加载 Gateway。 当 Twilio 后端缺少 account SID、auth token 或 caller number 时,twilio-voice-call-credentials 会失败。在 Gateway 主机上设置这些变量:
export TWILIO_ACCOUNT_SID=AC...
export TWILIO_AUTH_TOKEN=...
export TWILIO_FROM_NUMBER=+15550001234
voice-call 没有公开的 webhook 暴露,或者 publicUrl 指向回环或私有网络空间时,twilio-voice-call-webhook 会失败。将 plugins.entries.voice-call.config.publicUrl 设置为公共提供方 URL,或配置 voice-call tunnel/Tailscale 暴露。 回环和私有 URL 不适用于运营商回调。不要将 localhost127.0.0.10.0.0.010.x172.16.x-172.31.x192.168.x169.254.xfc00::/7fd00::/8 用作 publicUrl 对于稳定的公共 URL:
{
  plugins: {
    entries: {
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio",
          fromNumber: "+15550001234",
          publicUrl: "https://voice.example.com/voice/webhook",
        },
      },
    },
  },
}
对于本地开发,请使用隧道或 Tailscale 暴露,而不是私有主机 URL:
{
  plugins: {
    entries: {
      "voice-call": {
        config: {
          tunnel: { provider: "ngrok" },
          // 或者
          tailscale: { mode: "funnel", path: "/voice/webhook" },
        },
      },
    },
  },
}
然后重启或重新加载 Gateway 并运行:
openclaw googlemeet setup --transport twilio
openclaw voicecall setup
openclaw voicecall smoke
voicecall smoke 默认只做就绪检查。要对特定号码进行 dry-run:
openclaw voicecall smoke --to "+15555550123"
只有在你明确要发起一次真实的外呼通知通话时,才添加 --yes
openclaw voicecall smoke --to "+15555550123" --yes

Twilio 通话已开始但从未进入会议

确认 Meet 事件暴露了电话拨入详情。传入精确的拨入号码和 PIN,或者自定义 DTMF 序列:
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --dtmf-sequence ww123456#
如果提供方在输入 PIN 之前需要暂停,请在 --dtmf-sequence 中使用前导 w 或逗号。 如果电话呼叫已创建,但 Meet 名册中始终没有出现拨入参与者:
  • 运行 openclaw googlemeet doctor <session-id>,确认委托的 Twilio 呼叫 ID、是否已排队 DTMF,以及是否请求了初始问候语。
  • 运行 openclaw voicecall status --call-id <id>,确认通话仍然 处于活动状态。
  • 运行 openclaw voicecall tail,检查 Twilio webhook 是否到达 Gateway。
  • 运行 openclaw logs --follow,并查找 Twilio Meet 序列:Google Meet 委托加入,Voice Call 存储并提供预连接 DTMF TwiML, Voice Call 为 Twilio 通话提供实时 TwiML,然后 Google Meet 通过 voicecall.speak 请求初始语音。
  • 重新运行 openclaw googlemeet setup --transport twilio;绿色的设置检查是 必需的,但不能证明会议 PIN 序列是正确的。
  • 确认拨入号码属于与 PIN 相同的 Meet 邀请和地区。
  • 如果 Meet 应答较慢,或在发送预连接 DTMF 后通话转录仍显示要求输入 PIN 的提示,请将 voiceCall.dtmfDelayMs 从默认的 12 秒增加。
  • 如果参与者加入了但你听不到问候语,请检查 openclaw logs --follow 中 post-DTMF 的 voicecall.speak 请求,以及 媒体流 TTS 播放或 Twilio <Say> 回退。如果通话 转录仍包含“enter the meeting PIN”,说明电话线路尚未加入 Meet 房间,因此会议参与者不会听到语音。
如果 webhook 没有到达,先调试 Voice Call 插件:提供方必须能够访问 plugins.entries.voice-call.config.publicUrl 或配置的隧道。参见 Voice call troubleshooting

注意事项

Google Meet 的官方媒体 API 以接收为导向,因此在 Meet 通话中发言仍然需要一个参与者路径。这个插件保持了这一边界的可见性:Chrome 负责浏览器参与和本地音频路由;Twilio 负责电话拨入参与。 Chrome 返听模式需要 BlackHole 2ch,以及以下两者之一:
  • chrome.audioInputCommand 加上 chrome.audioOutputCommand:OpenClaw 负责桥接,并在这些命令与所选提供者之间以 chrome.audioFormat 传输音频。Agent 模式使用实时转写加常规 TTS;bidi 模式使用实时语音提供者。默认的 Chrome 路径是 24 kHz PCM16,chrome.audioBufferBytes: 4096;旧版命令对仍可使用 8 kHz G.711 mu-law。
  • chrome.audioBridgeCommand:外部桥接命令负责整个本地音频路径,并且必须在启动或验证其守护进程后退出。这仅对 bidi 有效,因为 agent 模式需要直接访问命令对以进行 TTS。
当 agent 以 agent 模式调用 google_meet 工具时,会议顾问会在回答参与者语音之前分叉调用者当前的转写内容。Meet 会话仍然保持独立(agent:<agentId>:subagent:google-meet:<sessionId>),因此后续会议跟进不会直接修改调用者的转写内容。 为了获得干净的双工音频,请将 Meet 输出和 Meet 麦克风路由到分开的虚拟设备,或者路由到类似 Loopback 的虚拟设备图。单个共享的 BlackHole 设备可能会把其他参与者的声音回传到通话中。 使用命令对 Chrome 桥接时,chrome.bargeInInputCommand 可以监听一个单独的本地麦克风,并在用户开始说话时清除助手播放内容。这样即使在助手播放期间,共享的 BlackHole 回环输入会暂时被抑制,人类语音仍能优先于助手输出。和 chrome.audioInputCommandchrome.audioOutputCommand 一样,它是由操作者配置的本地命令。请使用明确可信的命令路径或参数列表,不要指向不受信任位置中的脚本。 googlemeet speak 会触发 Chrome 会话的活动返听音频桥接。googlemeet leave 会停止该桥接。对于通过语音通话插件委派的 Twilio 会话,leave 也会挂断底层语音通话。若你还想关闭 API 管理空间中的活动 Google Meet 会议,请使用 googlemeet end-active-conference

相关