Caricamento in corso...
Caricamento in corso...
Last synced: Today, 22:00
Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.
Use this file to discover all available pages before exploring further.
Google Meet participant support for OpenClaw — the plugin is explicit by design:
https://meet.google.com/...realtimemoderealtimetranscribeBlackHole 2chgooglemeetmeetInstall the local audio dependencies and configure a backend realtime voice provider. OpenAI is the default; Google Gemini Live also works with
realtime.provider: "google"bashbrew install blackhole-2ch sox export OPENAI_API_KEY=sk-... # or export GEMINI_API_KEY=...
blackhole-2chBlackHole 2chbashsudo reboot
After reboot, verify both pieces:
bashsystem_profiler SPAudioDataType | grep -i BlackHole command -v sox
Enable the plugin:
json5{ plugins: { entries: { "google-meet": { enabled: true, config: {}, }, }, }, }
Check setup:
bashopenclaw googlemeet setup
The setup output is meant to be agent-readable and mode-aware. It reports Chrome profile, node pinning, and, for realtime Chrome joins, the BlackHole/SoX audio bridge and delayed realtime intro checks. For observe-only joins, check the same transport with
--mode transcribebashopenclaw googlemeet setup --transport chrome-node --mode transcribe
When Twilio delegation is configured, setup also reports whether the
voice-callok: falseopenclaw googlemeet setup --json--transport chrome--transport chrome-node--transport twilioFor Twilio, always preflight the transport explicitly when the default transport is Chrome:
bashopenclaw googlemeet setup --transport twilio
That catches missing
voice-callJoin a meeting:
bashopenclaw googlemeet join https://meet.google.com/abc-defg-hij
Or let an agent join through the
google_meetjson{ "action": "join", "url": "https://meet.google.com/abc-defg-hij", "transport": "chrome-node", "mode": "realtime" }
Create a new meeting and join it:
bashopenclaw googlemeet create --transport chrome-node --mode realtime
Create only the URL without joining:
bashopenclaw googlemeet create --no-join
googlemeet createhttps://meet.google.com/newauthuserThe command/tool output includes a
sourceapibrowsercreatejoined: truecreate --no-join"join": falseOr tell an agent: "Create a Google Meet, join it with realtime voice, and send me the link." The agent should call
google_meetaction: "create"meetingUrijson{ "action": "create", "transport": "chrome-node", "mode": "realtime" }
For an observe-only/browser-control join, set
"mode": "transcribe"During realtime sessions,
google_meetinCallmanualActionRequiredproviderConnectedrealtimeReadyaudioInputActiveaudioOutputActiveinCall: truespeechReady: falseLocal Chrome joins through the signed-in OpenClaw browser profile. Realtime mode requires
BlackHole 2chYou 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:
Install the VM dependencies:
bashbrew install blackhole-2ch sox
Reboot the VM after installing BlackHole so macOS exposes
BlackHole 2chbashsudo reboot
After reboot, verify the VM can see the audio device and SoX commands:
bashsystem_profiler SPAudioDataType | grep -i BlackHole command -v sox
Install or update OpenClaw in the VM, then enable the bundled plugin there:
bashopenclaw plugins enable google-meet
Start the node host in the VM:
bashopenclaw node run --host <gateway-host> --port 18789 --display-name parallels-macos
If
<gateway-host>bashOPENCLAW_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:
bashOPENCLAW_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=1openclaw.jsonopenclaw node installApprove the node from the Gateway host:
bashopenclaw devices list openclaw devices approve <requestId>
Confirm the Gateway sees the node and that it advertises both
googlemeet.chromebrowser.proxybashopenclaw nodes status
Route Meet through that node on the Gateway host:
json5{ 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:
bashopenclaw googlemeet join https://meet.google.com/abc-defg-hij
or ask the agent to use the
google_meettransport: "chrome-node"For a one-command smoke test that creates or reuses a session, speaks a known phrase, and prints session health:
bashopenclaw googlemeet test-speech https://meet.google.com/abc-defg-hij
During realtime 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 observe-only join or browser-only meeting creation, it continues past the same prompt without microphone when that choice is available. If the browser profile is not signed in, Meet is waiting for host admission, Chrome needs microphone/camera permission for a realtime join, or Meet is stuck on a prompt automation could not resolve, the join/test-speech result reports
manualActionRequired: truemanualActionReasonmanualActionMessagebrowserUrlbrowserTitleIf
chromeNode.nodegooglemeet.chromechromeNode.nodeCommon failure checks:
Configured Google Meet node ... is not usable: offlineNo connected Google Meet-capable nodeopenclaw node runopenclaw plugins enable google-meetopenclaw plugins enable browsergateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]BlackHole 2ch audio device not foundblackhole-2chBlackHole 2ch audio device not found on the nodeblackhole-2chchrome.guestNamebrowser.defaultProfile: "user"chrome.reuseExistingTab: truehttps://meet.google.com/newThe Chrome realtime default uses two external tools:
soxblackhole-2chBlackHole 2chOpenClaw 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-onlyChrome transport opens the Meet URL through OpenClaw browser control and joins as the signed-in OpenClaw browser profile. On macOS, the plugin checks for
BlackHole 2chchromechrome-nodebrowser.defaultProfilechrome.browserProfilechrome-nodebashopenclaw 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 2chTwilio 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:
json5{ 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.jsonbashexport TWILIO_ACCOUNT_SID=AC... export TWILIO_AUTH_TOKEN=... export TWILIO_FROM_NUMBER=+15550001234
Restart or reload the Gateway after enabling
voice-callThen verify:
bashopenclaw config validate openclaw plugins list | grep -E 'google-meet|voice-call' openclaw googlemeet setup
When Twilio delegation is wired,
googlemeet setuptwilio-voice-call-plugintwilio-voice-call-credentialstwilio-voice-call-webhookbashopenclaw googlemeet join https://meet.google.com/abc-defg-hij \ --transport twilio \ --dial-in-number +15551234567 \ --pin 123456
Use
--dtmf-sequencebashopenclaw googlemeet join https://meet.google.com/abc-defg-hij \ --transport twilio \ --dial-in-number +15551234567 \ --dtmf-sequence ww123456#
OAuth is optional for creating a Meet link because
googlemeet createGoogle Meet API access uses user OAuth: create a Google Cloud OAuth client, request the required scopes, authorize a Google account, then store the resulting refresh token in the Google Meet plugin config or provide the
OPENCLAW_GOOGLE_MEET_*OAuth does not replace the Chrome join path. Chrome and Chrome-node transports still join through a signed-in Chrome profile, BlackHole/SoX, and a connected node when you use browser participation. OAuth is only for the official Google Meet API path: create meeting spaces, resolve spaces, and run Meet Media API preflight checks.
In Google Cloud Console:
Create or select a Google Cloud project.
Enable Google Meet REST API for that project.
Configure the OAuth consent screen.
Add the scopes OpenClaw requests:
https://www.googleapis.com/auth/meetings.space.createdhttps://www.googleapis.com/auth/meetings.space.readonlyhttps://www.googleapis.com/auth/meetings.conference.media.readonlyCreate an OAuth client ID.
Application type: Web application.
Authorized redirect URI:
texthttp://localhost:8085/oauth2callback
Copy the client ID and client secret.
meetings.space.createdspaces.createmeetings.space.readonlymeetings.conference.media.readonlyConfigure
oauth.clientIdoauth.clientSecretbashopenclaw googlemeet auth login --json
The command prints an
oauthhttp://localhost:8085/oauth2callback--manualExamples:
bashOPENCLAW_GOOGLE_MEET_CLIENT_ID="your-client-id" \ OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \ openclaw googlemeet auth login --json
Use manual mode when the browser cannot reach the local callback:
bashOPENCLAW_GOOGLE_MEET_CLIENT_ID="your-client-id" \ OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \ openclaw googlemeet auth login --json --manual
The JSON output includes:
json{ "oauth": { "clientId": "your-client-id", "clientSecret": "your-client-secret", "refreshToken": "refresh-token", "accessToken": "access-token", "expiresAt": 1770000000000 }, "scope": "..." }
Store the
oauthjson5{ plugins: { entries: { "google-meet": { enabled: true, config: { oauth: { clientId: "your-client-id", clientSecret: "your-client-secret", refreshToken: "refresh-token", }, }, }, }, }, }
Prefer environment variables when you do not want the refresh token in config. If both config and environment values are present, the plugin resolves config first and then environment fallback.
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 --jsonmeetings.space.createdRun the OAuth doctor when you want a fast, non-secret health check:
bashopenclaw googlemeet doctor --oauth --json
This does not load the Chrome runtime or require a connected Chrome node. It checks that OAuth config exists and that the refresh token can mint an access token. The JSON report includes only status fields such as
okconfiguredtokenSourceexpiresAtCommon results:
| Check | Meaning |
|---|---|
text oauth-config | text oauth.clientIdtext oauth.refreshToken |
text oauth-token | The cached access token is still valid, or the refresh token minted a new access token. |
text meet-spaces-get | Optional text --meeting |
text meet-spaces-create | Optional text --create-space |
To prove Google Meet API enablement and
spaces.createbashopenclaw googlemeet doctor --oauth --create-space --json openclaw googlemeet create --no-join --json
--create-spacemeetings.space.createdTo prove read access for an existing meeting space:
bashopenclaw 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-space403openclaw googlemeet auth login --jsonoauthNo 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_IDGOOGLE_MEET_CLIENT_IDOPENCLAW_GOOGLE_MEET_CLIENT_SECRETGOOGLE_MEET_CLIENT_SECRETOPENCLAW_GOOGLE_MEET_REFRESH_TOKENGOOGLE_MEET_REFRESH_TOKENOPENCLAW_GOOGLE_MEET_ACCESS_TOKENGOOGLE_MEET_ACCESS_TOKENOPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_ATGOOGLE_MEET_ACCESS_TOKEN_EXPIRES_ATOPENCLAW_GOOGLE_MEET_DEFAULT_MEETINGGOOGLE_MEET_DEFAULT_MEETINGOPENCLAW_GOOGLE_MEET_PREVIEW_ACKGOOGLE_MEET_PREVIEW_ACKResolve a Meet URL, code, or
spaces/{id}spaces.getbashopenclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
Run preflight before media work:
bashopenclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
List meeting artifacts and attendance after Meet has created conference records:
bashopenclaw 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
With
--meetingartifactsattendance--all-conference-recordsCalendar lookup can resolve the meeting URL from Google Calendar before reading Meet artifacts:
bashopenclaw googlemeet latest --today openclaw googlemeet calendar-events --today --json openclaw googlemeet artifacts --event "Weekly sync" openclaw googlemeet attendance --today --format csv --output attendance.csv
--todayprimary--event <query>--calendar <id>calendar-eventslatestartifactsattendanceexportIf you already know the conference record id, address it directly:
bashopenclaw 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
Write a readable report:
bashopenclaw 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--no-transcript-entriesattendance--no-merge-duplicates--late-after-minutes--early-before-minutesexportsummary.mdattendance.csvtranscript.mdartifacts.jsonattendance.jsonmanifest.jsonmanifest.json--zip--include-doc-bodiesfiles.export--include-doc-bodies--dry-runAgents can also create the same bundle through the
google_meetjson{ "action": "export", "conferenceRecord": "conferenceRecords/abc123", "includeDocumentBodies": true, "outputDir": "meet-export", "zip": true }
Set
"dryRun": trueRun the guarded live smoke against a real retained meeting:
bashOPENCLAW_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
Live smoke environment:
OPENCLAW_LIVE_TEST=1OPENCLAW_GOOGLE_MEET_LIVE_MEETINGspaces/{id}OPENCLAW_GOOGLE_MEET_CLIENT_IDGOOGLE_MEET_CLIENT_IDOPENCLAW_GOOGLE_MEET_REFRESH_TOKENGOOGLE_MEET_REFRESH_TOKENOPENCLAW_GOOGLE_MEET_CLIENT_SECRETOPENCLAW_GOOGLE_MEET_ACCESS_TOKENOPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_ATOPENCLAW_The base artifact/attendance live smoke needs
https://www.googleapis.com/auth/meetings.space.readonlyhttps://www.googleapis.com/auth/meetings.conference.media.readonlyhttps://www.googleapis.com/auth/calendar.events.readonlyhttps://www.googleapis.com/auth/drive.meet.readonlyCreate a fresh Meet space:
bashopenclaw googlemeet create
The command prints the new
meeting urigoogle_meetaction: "create""join": falseExample JSON output from the browser fallback:
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" } } }
If the browser fallback hits Google login or a Meet permission blocker before it can create the URL, the Gateway method returns a failed response and the
google_meetjson{ "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" } }
When an agent sees
manualActionRequired: truemanualActionMessageExample JSON output from API create:
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" } } }
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: trueSet
preview.enrollmentAcknowledged: trueThe 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"bashbrew install blackhole-2ch sox export OPENAI_API_KEY=sk-... # or export GEMINI_API_KEY=...
Set the plugin config under
plugins.entries.google-meet.configjson5{ plugins: { entries: { "google-meet": { enabled: true, config: {}, }, }, }, }
Defaults:
defaultTransport: "chrome"defaultMode: "realtime"chromeNode.nodechrome-nodechrome.audioBackend: "blackhole-2ch"chrome.guestName: "OpenClaw Agent"chrome.autoJoin: truechrome-nodechrome.reuseExistingTab: truechrome.waitForInCallMs: 20000chrome.audioFormat: "pcm16-24khz""g711-ulaw-8khz"chrome.audioInputCommandBlackHole 2chchrome.audioFormatchrome.audioOutputCommandchrome.audioFormatBlackHole 2chrealtime.provider: "openai"realtime.toolPolicy: "safe-read-only"realtime.instructionsopenclaw_agent_consultrealtime.introMessage""realtime.agentIdopenclaw_agent_consultmainOptional overrides:
json5{ defaults: { meeting: "https://meet.google.com/abc-defg-hij", }, browser: { defaultProfile: "openclaw", }, chrome: { guestName: "OpenClaw Agent", waitForInCallMs: 30000, }, chromeNode: { node: "parallels-macos", }, realtime: { provider: "google", agentId: "jay", 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:
json5{ defaultTransport: "twilio", twilio: { defaultDialInNumber: "+15551234567", defaultPin: "123456", }, voiceCall: { gatewayUrl: "ws://127.0.0.1:18789", }, }
voiceCall.enabledtruevoice-callAgents can use the
google_meetjson{ "action": "join", "url": "https://meet.google.com/abc-defg-hij", "transport": "chrome-node", "mode": "realtime" }
Use
transport: "chrome"transport: "chrome-node"openclaw_agent_consultUse
action: "status"action: "speak"sessionIdmessageaction: "test_speech"inCalltest_speechmode: "realtime"mode: "transcribe"speechOutputVerifiedaction: "leave"statusinCallmicMutedmanualActionRequiredmanualActionReasonmanualActionMessagespeechReadyspeechBlockedReasonspeechBlockedMessagespeechReady: falseproviderConnectedrealtimeReadylastInputAtlastOutputAtjson{ "action": "speak", "sessionId": "meet_...", "message": "Say exactly: I'm here and listening." }
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_consultThe 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.
By default, consults run against the
mainrealtime.agentIdrealtime.toolPolicysafe-read-onlyreadweb_searchweb_fetchx_searchmemory_searchmemory_getownernoneThe 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:
bashopenclaw googlemeet speak meet_... "Say exactly: I'm here and listening."
For the full join-and-speak smoke:
bashopenclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \ --transport chrome-node \ --message "Say exactly: I'm here and listening."
Use this sequence before handing a meeting to an unattended agent:
bashopenclaw 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 setupgooglemeet setupchrome-node-connectednodes statusgooglemeet.chromebrowser.proxytest-speechinCall: trueFor a remote Chrome host such as a Parallels macOS VM, this is the shortest safe check after updating the Gateway or the VM:
bashopenclaw 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:
bashopenclaw googlemeet setup openclaw googlemeet join https://meet.google.com/abc-defg-hij \ --transport twilio \ --dial-in-number +15551234567 \ --pin 123456
Expected Twilio state:
googlemeet setuptwilio-voice-call-plugintwilio-voice-call-credentialstwilio-voice-call-webhookvoicecalltransport: "twilio"twilio.voiceCallIdopenclaw logs --followgooglemeet leave <sessionId>Confirm the plugin is enabled in the Gateway config and reload the Gateway:
bashopenclaw plugins list | grep google-meet openclaw googlemeet setup
If you just edited
plugins.entries.google-meetOn the node host, run:
bashopenclaw 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:
bashopenclaw devices list openclaw devices approve <requestId> openclaw nodes status
The node must be connected and list
googlemeet.chromebrowser.proxyjson5{ gateway: { nodes: { allowCommands: ["browser.proxy", "googlemeet.chrome"], }, }, }
If
googlemeet setupchrome-node-connectedgateway token mismatchbashOPENCLAW_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:
bashopenclaw googlemeet setup openclaw nodes status --connected
Run
googlemeet test-speechmanualActionRequired: truemanualActionMessageCommon manual actions:
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.
googlemeet createspaces.createoauth.clientIdoauth.refreshTokenOPENCLAW_GOOGLE_MEET_*meetings.space.createdopenclaw googlemeet auth login --jsondefaultTransport: "chrome-node"chromeNode.nodebrowser.proxygooglemeet.chromehttps://meet.google.com/newhttps://meet.google.com/newmanualActionRequired: truebrowser.nodeIdbrowser.targetIdbrowserUrlmanualActionMessagemeet-audio-choice-requiredgoogle-login-requiredCheck the realtime path:
bashopenclaw googlemeet setup openclaw googlemeet doctor
Use
mode: "realtime"mode: "transcribe"googlemeet test-speechspeechOutputVerifiedspeechOutputTimedOutAlso verify:
OPENAI_API_KEYGEMINI_API_KEYBlackHole 2chsoxgooglemeet doctor [session-id]realtimeReadygooglemeet status [session-id] --jsongooglemeet doctor --oauth--meeting--create-spaceIf an agent timed out and you can see a Meet tab already open, inspect that tab without opening another one:
bashopenclaw googlemeet recover-tab openclaw googlemeet recover-tab https://meet.google.com/abc-defg-hij
The equivalent tool action is
recover_current_tabchromechrome-nodechrome-nodetwilio-voice-call-pluginvoice-callplugins.allowplugins.entries.voice-calltwilio-voice-call-credentialsbashexport TWILIO_ACCOUNT_SID=AC... export TWILIO_AUTH_TOKEN=... export TWILIO_FROM_NUMBER=+15550001234
twilio-voice-call-webhookvoice-callpublicUrlplugins.entries.voice-call.config.publicUrlvoice-callLoopback and private URLs are not valid for carrier callbacks. Do not use
localhost127.0.0.10.0.0.010.x172.16.x172.31.x192.168.x169.254.xfc00::/7fd00::/8publicUrlFor a stable public URL:
json5{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", fromNumber: "+15550001234", publicUrl: "https://voice.example.com/voice/webhook", }, }, }, }, }
For local development, use a tunnel or Tailscale exposure instead of a private host URL:
json5{ plugins: { entries: { "voice-call": { config: { tunnel: { provider: "ngrok" }, // or tailscale: { mode: "funnel", path: "/voice/webhook" }, }, }, }, }, }
Then restart or reload the Gateway and run:
bashopenclaw googlemeet setup --transport twilio openclaw voicecall setup openclaw voicecall smoke
voicecall smokebashopenclaw voicecall smoke --to "+15555550123"
Only add
--yesbashopenclaw voicecall smoke --to "+15555550123" --yes
Confirm the Meet event exposes phone dial-in details. Pass the exact dial-in number and PIN or a custom DTMF sequence:
bashopenclaw googlemeet join https://meet.google.com/abc-defg-hij \ --transport twilio \ --dial-in-number +15551234567 \ --dtmf-sequence ww123456#
Use leading
w--dtmf-sequenceIf the phone call is created but the Meet roster never shows the dial-in participant:
openclaw voicecall status --call-id <id>openclaw voicecall tailopenclaw logs --followinitialGreeting=queuedopenclaw googlemeet setup --transport twilio--dtmf-sequencewwww123456#openclaw logs --followinitialGreeting=queuedvoicecall.startIf webhooks do not arrive, debug the Voice Call plugin first: the provider must reach
plugins.entries.voice-call.config.publicUrlGoogle 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
BlackHole 2chchrome.audioInputCommandchrome.audioOutputCommandchrome.audioFormatchrome.audioBridgeCommandFor 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 speakgooglemeet leaveleave© 2024 TaskFlow Mirror
Powered by TaskFlow Sync Engine