Files
openclaw/docs/plugins/google-meet.md
2026-04-25 02:18:08 +01:00

31 KiB

summary, read_when, title
summary read_when title
Google Meet plugin: join explicit Meet URLs through Chrome or Twilio with realtime voice defaults
You want an OpenClaw agent to join a Google Meet call
You want an OpenClaw agent to create a new Google Meet call
You are configuring Chrome, Chrome node, or Twilio as a Google Meet transport
Google Meet plugin

Google Meet participant support for OpenClaw — the plugin is explicit by design:

  • It only joins an explicit https://meet.google.com/... URL.
  • It can create a new Meet space through the Google Meet API, then join the returned URL.
  • realtime voice is the default mode.
  • Realtime voice can call back into the full OpenClaw agent when deeper reasoning or tools are needed.
  • Agents choose the join behavior with mode: use realtime for live listen/talk-back, or transcribe to join/control the browser without the realtime voice bridge.
  • Auth starts as personal Google OAuth or an already signed-in Chrome profile.
  • There is no automatic consent announcement.
  • The default Chrome audio backend is BlackHole 2ch.
  • Chrome can run locally or on a paired node host.
  • Twilio accepts a dial-in number plus optional PIN or DTMF sequence.
  • The CLI command is googlemeet; meet is reserved for broader agent teleconference workflows.

Quick start

Install the local audio dependencies and configure a backend realtime voice provider. OpenAI is the default; Google Gemini Live also works with realtime.provider: "google":

brew install blackhole-2ch sox
export OPENAI_API_KEY=sk-...
# or
export GEMINI_API_KEY=...

blackhole-2ch installs the BlackHole 2ch virtual audio device. Homebrew's installer requires a reboot before macOS exposes the device:

sudo reboot

After reboot, verify both pieces:

system_profiler SPAudioDataType | grep -i BlackHole
command -v rec play

Enable the plugin:

{
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {},
      },
    },
  },
}

Check setup:

openclaw googlemeet setup

The setup output is meant to be agent-readable. It reports Chrome profile, audio bridge, node pinning, delayed realtime intro, and, when Twilio delegation is configured, whether the voice-call plugin and Twilio credentials are ready. Treat any ok: false check as a blocker before asking an agent to join. Use openclaw googlemeet setup --json for scripts or machine-readable output.

Join a meeting:

openclaw googlemeet join https://meet.google.com/abc-defg-hij

Or let an agent join through the google_meet tool:

{
  "action": "join",
  "url": "https://meet.google.com/abc-defg-hij",
  "transport": "chrome-node",
  "mode": "realtime"
}

Create a new meeting and join it:

openclaw googlemeet create --transport chrome-node --mode realtime

Create only the URL without joining:

openclaw googlemeet create --no-join

googlemeet create has two paths:

  • API create: used when Google Meet OAuth credentials are configured. This is the most deterministic path and does not depend on browser UI state.
  • Browser fallback: used when OAuth credentials are absent. OpenClaw uses the pinned Chrome node, opens https://meet.google.com/new, waits for Google to redirect to a real meeting-code URL, then returns that URL. This path requires the OpenClaw Chrome profile on the node to already be signed in to Google. Browser automation handles Meet's own first-run microphone prompt; that prompt is not treated as a Google login failure.

The command/tool output includes a source field (api or browser) so agents can explain which path was used. create joins the new meeting by default and returns joined: true plus the join session. To only mint the URL, use create --no-join on the CLI or pass "join": false to the tool.

Or tell an agent: "Create a Google Meet, join it with realtime voice, and send me the link." The agent should call google_meet with action: "create" and then share the returned meetingUri.

{
  "action": "create",
  "transport": "chrome-node",
  "mode": "realtime"
}

For an observe-only/browser-control join, set "mode": "transcribe". That does not start the duplex realtime model bridge, so it will not talk back into the meeting.

Chrome joins as the signed-in Chrome profile. In Meet, pick BlackHole 2ch for the microphone/speaker path used by OpenClaw. For clean duplex audio, use separate virtual devices or a Loopback-style graph; a single BlackHole device is enough for a first smoke test but can echo.

Local Gateway + Parallels Chrome

You do not need a full OpenClaw Gateway or model API key inside a macOS VM just to make the VM own Chrome. Run the Gateway and agent locally, then run a node host in the VM. Enable the bundled plugin on the VM once so the node advertises the Chrome command:

What runs where:

  • Gateway host: OpenClaw Gateway, agent workspace, model/API keys, realtime provider, and the Google Meet plugin config.
  • Parallels macOS VM: OpenClaw CLI/node host, Google Chrome, SoX, BlackHole 2ch, and a Chrome profile signed in to Google.
  • Not needed in the VM: Gateway service, agent config, OpenAI/GPT key, or model provider setup.

Install the VM dependencies:

brew install blackhole-2ch sox

Reboot the VM after installing BlackHole so macOS exposes BlackHole 2ch:

sudo reboot

After reboot, verify the VM can see the audio device and SoX commands:

system_profiler SPAudioDataType | grep -i BlackHole
command -v rec play

Install or update OpenClaw in the VM, then enable the bundled plugin there:

openclaw plugins enable google-meet

Start the node host in the VM:

openclaw node run --host <gateway-host> --port 18789 --display-name parallels-macos

If <gateway-host> is a LAN IP and you are not using TLS, the node refuses the plaintext WebSocket unless you opt in for that trusted private network:

OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos

Use the same environment variable when installing the node as a 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 is process environment, not an openclaw.json setting. openclaw node install stores it in the LaunchAgent environment when it is present on the install command.

Approve the node from the Gateway host:

openclaw devices list
openclaw devices approve <requestId>

Confirm the Gateway sees the node and that it advertises both googlemeet.chrome and browser capability/browser.proxy:

openclaw nodes status

Route Meet through that node on the Gateway host:

{
  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",
          },
        },
      },
    },
  },
}

Now join normally from the Gateway host:

openclaw googlemeet join https://meet.google.com/abc-defg-hij

or ask the agent to use the google_meet tool with transport: "chrome-node".

For a one-command smoke test that creates or reuses a session, speaks a known phrase, and prints session health:

openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij

During join, OpenClaw browser automation fills the guest name, clicks Join/Ask to join, and accepts Meet's first-run "Use microphone" choice when that prompt appears. During browser-only meeting creation, it can also continue past the same prompt without microphone if Meet does not expose the use-microphone button. If the browser profile is not signed in, Meet is waiting for host admission, Chrome needs microphone/camera permission, or Meet is stuck on a prompt automation could not resolve, the join/test-speech result reports manualActionRequired: true with manualActionReason and manualActionMessage. Agents should stop retrying the join, report that exact message plus the current browserUrl/browserTitle, and retry only after the manual browser action is complete.

If chromeNode.node is omitted, OpenClaw auto-selects only when exactly one connected node advertises both googlemeet.chrome and browser control. If several capable nodes are connected, set chromeNode.node to the node id, display name, or remote IP.

Common failure checks:

  • No connected Google Meet-capable node: start openclaw node run in the VM, approve pairing, and make sure openclaw plugins enable google-meet and openclaw plugins enable browser were run in the VM. Also confirm the Gateway host allows both node commands with gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"].
  • BlackHole 2ch audio device not found on the node: install blackhole-2ch in the VM and reboot the VM.
  • Chrome opens but cannot join: sign in to the browser profile inside the VM, or keep chrome.guestName set for guest join. Guest auto-join uses OpenClaw browser automation through the node browser proxy; make sure the node browser config points at the profile you want, for example browser.defaultProfile: "user" or a named existing-session profile.
  • Duplicate Meet tabs: leave chrome.reuseExistingTab: true enabled. OpenClaw activates an existing tab for the same Meet URL before opening a new one, and browser meeting creation reuses an in-progress https://meet.google.com/new or Google account prompt tab before opening another one.
  • No audio: in Meet, route microphone/speaker through the virtual audio device path used by OpenClaw; use separate virtual devices or Loopback-style routing for clean duplex audio.

Install notes

The Chrome realtime default uses two external tools:

  • sox: command-line audio utility. The plugin uses its rec and play commands for the default 8 kHz G.711 mu-law audio bridge.
  • blackhole-2ch: macOS virtual audio driver. It creates the BlackHole 2ch audio device that Chrome/Meet can route through.

OpenClaw does not bundle or redistribute either package. The docs ask users to install them as host dependencies through Homebrew. SoX is licensed as LGPL-2.0-only AND GPL-2.0-only; BlackHole is GPL-3.0. If you build an installer or appliance that bundles BlackHole with OpenClaw, review BlackHole's upstream licensing terms or get a separate license from Existential Audio.

Transports

Chrome

Chrome transport opens the Meet URL in Google Chrome and joins as the signed-in Chrome profile. On macOS, the plugin checks for BlackHole 2ch before launch. If configured, it also runs an audio bridge health command and startup command before opening Chrome. Use chrome when Chrome/audio live on the Gateway host; use chrome-node when Chrome/audio live on a paired node such as a Parallels macOS VM.

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

Route Chrome microphone and speaker audio through the local OpenClaw audio bridge. If BlackHole 2ch is not installed, the join fails with a setup error instead of silently joining without an audio path.

Twilio

Twilio transport is a strict dial plan delegated to the Voice Call plugin. It does not parse Meet pages for phone numbers.

Use this when Chrome participation is not available or you want a phone dial-in fallback. Google Meet must expose a phone dial-in number and PIN for the meeting; OpenClaw does not discover those from the Meet page.

Enable the Voice Call plugin on the Gateway host, not on the Chrome node:

{
  plugins: {
    allow: ["google-meet", "voice-call"],
    entries: {
      "google-meet": {
        enabled: true,
        config: {
          defaultTransport: "chrome-node",
          // or set "twilio" if Twilio should be the default
        },
      },
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio",
        },
      },
    },
  },
}

Provide Twilio credentials through environment or config. Environment keeps secrets out of openclaw.json:

export TWILIO_ACCOUNT_SID=AC...
export TWILIO_AUTH_TOKEN=...
export TWILIO_FROM_NUMBER=+15550001234

Restart or reload the Gateway after enabling voice-call; plugin config changes do not appear in an already running Gateway process until it reloads.

Then verify:

openclaw config validate
openclaw plugins list | grep -E 'google-meet|voice-call'
openclaw googlemeet setup

When Twilio delegation is wired, googlemeet setup includes successful twilio-voice-call-plugin and twilio-voice-call-credentials checks.

openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --pin 123456

Use --dtmf-sequence when the meeting needs a custom sequence:

openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --dtmf-sequence ww123456#

OAuth and preflight

OAuth is optional for creating a Meet link because googlemeet create can fall back to browser automation. Configure OAuth when you want official API create, space resolution, or Meet Media API preflight checks.

Google Meet API access uses a personal OAuth client first. Configure oauth.clientId and optionally oauth.clientSecret, then run:

openclaw googlemeet auth login --json

The command prints an oauth config block with a refresh token. It uses PKCE, localhost callback on http://localhost:8085/oauth2callback, and a manual copy/paste flow with --manual.

The OAuth consent includes Meet space creation, Meet space read access, and Meet conference media read access. If you authenticated before meeting creation support existed, rerun openclaw googlemeet auth login --json so the refresh token has the meetings.space.created scope.

No OAuth credentials are needed for the browser fallback. In that mode, Google auth comes from the signed-in Chrome profile on the selected node, not from OpenClaw config.

These environment variables are accepted as fallbacks:

  • OPENCLAW_GOOGLE_MEET_CLIENT_ID or GOOGLE_MEET_CLIENT_ID
  • OPENCLAW_GOOGLE_MEET_CLIENT_SECRET or GOOGLE_MEET_CLIENT_SECRET
  • OPENCLAW_GOOGLE_MEET_REFRESH_TOKEN or GOOGLE_MEET_REFRESH_TOKEN
  • OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN or GOOGLE_MEET_ACCESS_TOKEN
  • OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT or GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT
  • OPENCLAW_GOOGLE_MEET_DEFAULT_MEETING or GOOGLE_MEET_DEFAULT_MEETING
  • OPENCLAW_GOOGLE_MEET_PREVIEW_ACK or GOOGLE_MEET_PREVIEW_ACK

Resolve a Meet URL, code, or spaces/{id} through spaces.get:

openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij

Run preflight before media work:

openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij

Create a fresh Meet space:

openclaw googlemeet create

The command prints the new meeting uri, source, and join session. With OAuth credentials it uses the official Google Meet API. Without OAuth credentials it uses the pinned Chrome node's signed-in browser profile as a fallback. Agents can use the google_meet tool with action: "create" to create and join in one step. For URL-only creation, pass "join": false.

Example JSON output from the browser fallback:

{
  "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"
    }
  }
}

Example JSON output from API create:

{
  "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"
    }
  }
}

Creating a Meet joins by default. The Chrome or Chrome-node transport still needs a signed-in Google Chrome profile to join through the browser. If the profile is signed out, OpenClaw reports manualActionRequired: true or a browser fallback error and asks the operator to finish Google login before retrying.

Set preview.enrollmentAcknowledged: true only after confirming your Cloud project, OAuth principal, and meeting participants are enrolled in the Google Workspace Developer Preview Program for Meet media APIs.

Config

The common Chrome realtime path only needs the plugin enabled, BlackHole, SoX, and a backend realtime voice provider key. OpenAI is the default; set realtime.provider: "google" to use Google Gemini Live:

brew install blackhole-2ch sox
export OPENAI_API_KEY=sk-...
# or
export GEMINI_API_KEY=...

Set the plugin config under plugins.entries.google-meet.config:

{
  plugins: {
    entries: {
      "google-meet": {
        enabled: true,
        config: {},
      },
    },
  },
}

Defaults:

  • defaultTransport: "chrome"
  • defaultMode: "realtime"
  • chromeNode.node: optional node id/name/IP for chrome-node
  • chrome.audioBackend: "blackhole-2ch"
  • chrome.guestName: "OpenClaw Agent": name used on the signed-out Meet guest screen
  • chrome.autoJoin: true: best-effort guest-name fill and Join Now click through OpenClaw browser automation on chrome-node
  • chrome.reuseExistingTab: true: activate an existing Meet tab instead of opening duplicates
  • chrome.waitForInCallMs: 20000: wait for the Meet tab to report in-call before the realtime intro is triggered
  • chrome.audioInputCommand: SoX rec command writing 8 kHz G.711 mu-law audio to stdout
  • chrome.audioOutputCommand: SoX play command reading 8 kHz G.711 mu-law audio from stdin
  • realtime.provider: "openai"
  • realtime.toolPolicy: "safe-read-only"
  • realtime.instructions: brief spoken replies, with openclaw_agent_consult for deeper answers
  • realtime.introMessage: short spoken readiness check when the realtime bridge connects; set it to "" to join silently

Optional overrides:

{
  defaults: {
    meeting: "https://meet.google.com/abc-defg-hij",
  },
  chrome: {
    browserProfile: "Default",
    guestName: "OpenClaw Agent",
    waitForInCallMs: 30000,
  },
  chromeNode: {
    node: "parallels-macos",
  },
  realtime: {
    provider: "google",
    toolPolicy: "owner",
    introMessage: "Say exactly: I'm here.",
    providers: {
      google: {
        model: "gemini-2.5-flash-native-audio-preview-12-2025",
        voice: "Kore",
      },
    },
  },
}

Twilio-only config:

{
  defaultTransport: "twilio",
  twilio: {
    defaultDialInNumber: "+15551234567",
    defaultPin: "123456",
  },
  voiceCall: {
    gatewayUrl: "ws://127.0.0.1:18789",
  },
}

voiceCall.enabled defaults to true; with Twilio transport it delegates the actual PSTN call and DTMF to the Voice Call plugin. If voice-call is not enabled, Google Meet can still validate and record the dial plan, but it cannot place the Twilio call.

Tool

Agents can use the google_meet tool:

{
  "action": "join",
  "url": "https://meet.google.com/abc-defg-hij",
  "transport": "chrome-node",
  "mode": "realtime"
}

Use transport: "chrome" when Chrome runs on the Gateway host. Use transport: "chrome-node" when Chrome runs on a paired node such as a Parallels VM. In both cases the realtime model and openclaw_agent_consult run on the Gateway host, so model credentials stay there.

Use action: "status" to list active sessions or inspect a session ID. Use action: "speak" with sessionId and message to make the realtime agent speak immediately. Use action: "test_speech" to create or reuse the session, trigger a known phrase, and return inCall health when the Chrome host can report it. Use action: "leave" to mark a session ended.

status includes Chrome health when available:

  • inCall: Chrome appears to be inside the Meet call
  • micMuted: best-effort Meet microphone state
  • manualActionRequired / manualActionReason / manualActionMessage: the browser profile needs manual login, Meet host admission, permissions, or browser-control repair before speech can work
  • providerConnected / realtimeReady: realtime voice bridge state
  • lastInputAt / lastOutputAt: last audio seen from or sent to the bridge
{
  "action": "speak",
  "sessionId": "meet_...",
  "message": "Say exactly: I'm here and listening."
}

Realtime agent consult

Chrome realtime mode is optimized for a live voice loop. The realtime voice provider hears the meeting audio and speaks through the configured audio bridge. When the realtime model needs deeper reasoning, current information, or normal OpenClaw tools, it can call openclaw_agent_consult.

The consult tool runs the regular OpenClaw agent behind the scenes with recent meeting transcript context and returns a concise spoken answer to the realtime voice session. The voice model can then speak that answer back into the meeting. It uses the same shared realtime consult tool as Voice Call.

realtime.toolPolicy controls the consult run:

  • safe-read-only: expose the consult tool and limit the regular agent to read, web_search, web_fetch, x_search, memory_search, and memory_get.
  • owner: expose the consult tool and let the regular agent use the normal agent tool policy.
  • none: do not expose the consult tool to the realtime voice model.

The consult session key is scoped per Meet session, so follow-up consult calls can reuse prior consult context during the same meeting.

To force a spoken readiness check after Chrome has fully joined the call:

openclaw googlemeet speak meet_... "Say exactly: I'm here and listening."

For the full join-and-speak smoke:

openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
  --transport chrome-node \
  --message "Say exactly: I'm here and listening."

Live test checklist

Use this sequence before handing a meeting to an unattended agent:

openclaw googlemeet setup
openclaw nodes status
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
  --transport chrome-node \
  --message "Say exactly: Google Meet speech test complete."

Expected Chrome-node state:

  • googlemeet setup is all green.
  • googlemeet setup includes chrome-node-connected when Chrome-node is the default transport or a node is pinned.
  • nodes status shows the selected node connected.
  • The selected node advertises both googlemeet.chrome and browser.proxy.
  • The Meet tab joins the call and test-speech returns Chrome health with inCall: true.

For a remote Chrome host such as a Parallels macOS VM, this is the shortest safe check after updating the Gateway or the VM:

openclaw googlemeet setup
openclaw nodes status --connected
openclaw nodes invoke \
  --node parallels-macos \
  --command googlemeet.chrome \
  --params '{"action":"setup"}'

That proves the Gateway plugin is loaded, the VM node is connected with the current token, and the Meet audio bridge is available before an agent opens a real meeting tab.

For a Twilio smoke, use a meeting that exposes phone dial-in details:

openclaw googlemeet setup
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --pin 123456

Expected Twilio state:

  • googlemeet setup includes green twilio-voice-call-plugin and twilio-voice-call-credentials checks.
  • voicecall is available in the CLI after Gateway reload.
  • The returned session has transport: "twilio" and a twilio.voiceCallId.
  • googlemeet leave <sessionId> hangs up the delegated voice call.

Troubleshooting

Agent cannot see the Google Meet tool

Confirm the plugin is enabled in the Gateway config and reload the Gateway:

openclaw plugins list | grep google-meet
openclaw googlemeet setup

If you just edited plugins.entries.google-meet, restart or reload the Gateway. The running agent only sees plugin tools registered by the current Gateway process.

No connected Google Meet-capable node

On the node host, run:

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

On the Gateway host, approve the node and verify commands:

openclaw devices list
openclaw devices approve <requestId>
openclaw nodes status

The node must be connected and list googlemeet.chrome plus browser.proxy. The Gateway config must allow those node commands:

{
  gateway: {
    nodes: {
      allowCommands: ["browser.proxy", "googlemeet.chrome"],
    },
  },
}

If googlemeet setup fails chrome-node-connected or the Gateway log reports gateway token mismatch, reinstall or restart the node with the current Gateway token. For a LAN Gateway this usually means:

OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
  openclaw node install \
  --host <gateway-lan-ip> \
  --port 18789 \
  --display-name parallels-macos \
  --force

Then reload the node service and re-run:

openclaw googlemeet setup
openclaw nodes status --connected

Browser opens but agent cannot join

Run googlemeet test-speech and inspect the returned Chrome health. If it reports manualActionRequired: true, show manualActionMessage to the operator and stop retrying until the browser action is complete.

Common manual actions:

  • Sign in to the Chrome profile.
  • Admit the guest from the Meet host account.
  • Grant Chrome microphone/camera permissions when Chrome's native permission prompt appears.
  • Close or repair a stuck Meet permission dialog.

Do not report "not signed in" just because Meet shows "Do you want people to hear you in the meeting?" That is Meet's audio-choice interstitial; OpenClaw clicks Use microphone through browser automation when available and keeps waiting for the real meeting state. For create-only browser fallback, OpenClaw may click Continue without microphone because creating the URL does not need the realtime audio path.

Meeting creation fails

googlemeet create first uses the Google Meet API spaces.create endpoint when OAuth credentials are configured. Without OAuth credentials it falls back to the pinned Chrome node browser. Confirm:

  • For API creation: oauth.clientId and oauth.refreshToken are configured, or matching OPENCLAW_GOOGLE_MEET_* environment variables are present.
  • For API creation: the refresh token was minted after create support was added. Older tokens may be missing the meetings.space.created scope; rerun openclaw googlemeet auth login --json and update plugin config.
  • For browser fallback: defaultTransport: "chrome-node" and chromeNode.node point at a connected node with browser.proxy and googlemeet.chrome.
  • For browser fallback: the OpenClaw Chrome profile on that node is signed in to Google and can open https://meet.google.com/new.
  • For browser fallback: retries reuse an existing https://meet.google.com/new or Google account prompt tab before opening a new tab. If an agent times out, retry the tool call rather than manually opening another Meet tab.
  • For browser fallback: if Meet shows "Do you want people to hear you in the meeting?", leave the tab open. OpenClaw should click Use microphone or, for create-only fallback, Continue without microphone through browser automation and continue waiting for the generated Meet URL. If it cannot, the error should mention meet-audio-choice-required, not google-login-required.

Agent joins but does not talk

Check the realtime path:

openclaw googlemeet setup
openclaw googlemeet status

Use mode: "realtime" for listen/talk-back. mode: "transcribe" intentionally does not start the duplex realtime voice bridge.

Also verify:

  • A realtime provider key is available on the Gateway host, such as OPENAI_API_KEY or GEMINI_API_KEY.
  • BlackHole 2ch is visible on the Chrome host.
  • rec and play exist on the Chrome host.
  • Meet microphone and speaker are routed through the virtual audio path used by OpenClaw.

Twilio setup checks fail

twilio-voice-call-plugin fails when voice-call is not allowed or not enabled. Add it to plugins.allow, enable plugins.entries.voice-call, and reload the Gateway.

twilio-voice-call-credentials fails when the Twilio backend is missing account SID, auth token, or caller number. Set these on the Gateway host:

export TWILIO_ACCOUNT_SID=AC...
export TWILIO_AUTH_TOKEN=...
export TWILIO_FROM_NUMBER=+15550001234

Then restart or reload the Gateway and run:

openclaw googlemeet setup

Twilio call starts but never enters the meeting

Confirm the Meet event exposes phone dial-in details. Pass the exact dial-in number and PIN or a custom DTMF sequence:

openclaw googlemeet join https://meet.google.com/abc-defg-hij \
  --transport twilio \
  --dial-in-number +15551234567 \
  --dtmf-sequence ww123456#

Use leading w or commas in --dtmf-sequence if the provider needs a pause before entering the PIN.

Notes

Google Meet's official media API is receive-oriented, so speaking into a Meet call still needs a participant path. This plugin keeps that boundary visible: Chrome handles browser participation and local audio routing; Twilio handles phone dial-in participation.

Chrome realtime mode needs either:

  • chrome.audioInputCommand plus chrome.audioOutputCommand: OpenClaw owns the realtime model bridge and pipes 8 kHz G.711 mu-law audio between those commands and the selected realtime voice provider.
  • chrome.audioBridgeCommand: an external bridge command owns the whole local audio path and must exit after starting or validating its daemon.

For clean duplex audio, route Meet output and Meet microphone through separate virtual devices or a Loopback-style virtual device graph. A single shared BlackHole device can echo other participants back into the call.

googlemeet speak triggers the active realtime audio bridge for a Chrome session. googlemeet leave stops that bridge. For Twilio sessions delegated through the Voice Call plugin, leave also hangs up the underlying voice call.