TaskFlow
DashboardFreewriteWhiteboardsProjectsCRMTasksNotificationsSettingsAgent TowerAPI Docs
OpenClaw Docs
?

User

Member

Caricamento in corso...

Home
Progetti
Task
Notifiche
CRM

    OpenClaw

    Documentation Mirror

    Documentation Overview

    Docs

    Auth credential semantics
    Scheduled tasks
    Hooks
    Automation & tasks
    Standing orders
    Task flow
    Background tasks
    BlueBubbles
    Broadcast groups
    Channel routing
    Discord
    Feishu
    Google Chat
    Group messages
    Groups
    iMessage
    Chat channels
    IRC
    LINE
    Channel location parsing
    Matrix
    Matrix migration
    Matrix push rules for quiet previews
    Mattermost
    Microsoft Teams
    Nextcloud Talk
    Nostr
    Pairing
    QA channel
    QQ bot
    Signal
    Slack
    Synology Chat
    Telegram
    Tlon
    Channel troubleshooting
    Twitch
    WeChat
    WhatsApp
    Yuanbao
    Zalo
    Zalo personal
    CI pipeline
    ACP
    Agent
    Agents
    Approvals
    Backup
    Browser
    Channels
    Clawbot
    `openclaw commitments`
    Completion
    Config
    Configure
    Cron
    Daemon
    Dashboard
    Devices
    Directory
    DNS
    Docs
    Doctor
    Flows (redirect)
    Gateway
    Health
    Hooks
    CLI reference
    Inference CLI
    Logs
    MCP
    Memory
    Message
    Migrate
    Models
    Node
    Nodes
    Onboard
    Pairing
    Plugins
    Proxy
    QR
    Reset
    Sandbox CLI
    Secrets
    Security
    Sessions
    Setup
    Skills
    Status
    System
    `openclaw tasks`
    TUI
    Uninstall
    Update
    Voicecall
    Webhooks
    Wiki
    Active memory
    Agent runtime
    Agent loop
    Agent runtimes
    Agent workspace
    Gateway architecture
    Channel docking
    Inferred commitments
    Compaction
    Context
    Context engine
    Delegate architecture
    Dreaming
    Experimental features
    Features
    Markdown formatting
    Memory overview
    Builtin memory engine
    Honcho memory
    QMD memory engine
    Memory search
    Messages
    Model failover
    Model providers
    Models CLI
    Multi-agent routing
    OAuth
    OpenClaw App SDK
    Presence
    QA overview
    Matrix QA
    Command queue
    Steering queue
    Retry policy
    Session management
    Session pruning
    Session tools
    SOUL.md personality guide
    Streaming and chunking
    System prompt
    Timezones
    TypeBox
    Typing indicators
    Usage tracking
    Date and time
    Node + tsx crash
    Diagnostics flags
    Authentication
    Background exec and process tool
    Bonjour discovery
    Bridge protocol
    CLI backends
    Configuration — agents
    Configuration — channels
    Configuration — tools and custom providers
    Configuration
    Configuration examples
    Configuration reference
    Diagnostics export
    Discovery and transports
    Doctor
    Gateway lock
    Health checks
    Heartbeat
    Gateway runbook
    Local models
    Gateway logging
    Multiple gateways
    Network model
    OpenAI chat completions
    OpenResponses API
    OpenShell
    OpenTelemetry export
    Gateway-owned pairing
    Prometheus metrics
    Gateway protocol
    Remote access
    Remote gateway setup
    Sandbox vs tool policy vs elevated
    Sandboxing
    Secrets management
    Secrets apply plan contract
    Security audit checks
    Security
    Tailscale
    Tools invoke API
    Troubleshooting
    Trusted proxy auth
    Debugging
    Environment variables
    FAQ
    FAQ: first-run setup
    FAQ: models and auth
    GPT-5.5 / Codex agentic parity
    GPT-5.5 / Codex parity maintainer notes
    Help
    Scripts
    Testing
    Testing: live suites
    General troubleshooting
    OpenClaw
    Ansible
    Azure
    Bun (experimental)
    ClawDock
    Release channels
    DigitalOcean
    Docker
    Docker VM runtime
    exe.dev
    Fly.io
    GCP
    Hetzner
    Hostinger
    Install
    Installer internals
    Kubernetes
    macOS VMs
    Migration guide
    Migrating from Claude
    Migrating from Hermes
    Nix
    Node.js
    Northflank
    Oracle Cloud
    Podman
    Railway
    Raspberry Pi
    Render
    Uninstall
    Updating
    Logging
    Network
    Audio and voice notes
    Camera capture
    Image and media support
    Nodes
    Location command
    Media understanding
    Talk mode
    Node troubleshooting
    Voice wake
    Pi integration architecture
    Pi development workflow
    Android app
    Platforms
    iOS app
    Linux app
    Gateway on macOS
    Canvas
    Gateway lifecycle
    macOS dev setup
    Health checks (macOS)
    Menu bar icon
    macOS logging
    Menu bar
    Peekaboo bridge
    macOS permissions
    Remote control
    macOS signing
    Skills (macOS)
    Voice overlay
    Voice wake (macOS)
    WebChat (macOS)
    macOS IPC
    macOS app
    Windows
    Plugin internals
    Plugin architecture internals
    Building plugins
    Plugin bundles
    Codex Computer Use
    Codex harness
    Community plugins
    Plugin compatibility
    Google Meet plugin
    Plugin hooks
    Plugin manifest
    Memory LanceDB
    Memory wiki
    Message presentation
    Agent harness plugins
    Building channel plugins
    Channel turn kernel
    Plugin entry points
    Plugin SDK migration
    Plugin SDK overview
    Building provider plugins
    Plugin runtime helpers
    Plugin setup and config
    Plugin SDK subpaths
    Plugin testing
    Skill workshop plugin
    Voice call plugin
    Webhooks plugin
    Zalo personal plugin
    OpenProse
    Alibaba Model Studio
    Anthropic
    Arcee AI
    Azure Speech
    Amazon Bedrock
    Amazon Bedrock Mantle
    Chutes
    Claude Max API proxy
    Cloudflare AI gateway
    ComfyUI
    Deepgram
    Deepinfra
    DeepSeek
    ElevenLabs
    Fal
    Fireworks
    GitHub Copilot
    GLM (Zhipu)
    Google (Gemini)
    Gradium
    Groq
    Hugging Face (inference)
    Provider directory
    Inferrs
    Inworld
    Kilocode
    LiteLLM
    LM Studio
    MiniMax
    Mistral
    Model provider quickstart
    Moonshot AI
    NVIDIA
    Ollama
    OpenAI
    OpenCode
    OpenCode Go
    OpenRouter
    Perplexity
    Qianfan
    Qwen
    Runway
    SGLang
    StepFun
    Synthetic
    Tencent Cloud (TokenHub)
    Together AI
    Venice AI
    Vercel AI gateway
    vLLM
    Volcengine (Doubao)
    Vydra
    xAI
    Xiaomi MiMo
    Z.AI
    Default AGENTS.md
    Release policy
    API usage and costs
    Credits
    Device model database
    Full release validation
    Memory configuration reference
    OpenClaw App SDK API design
    Prompt caching
    Rich output protocol
    RPC adapters
    SecretRef credential surface
    Session management deep dive
    AGENTS.md template
    BOOT.md template
    BOOTSTRAP.md template
    HEARTBEAT.md template
    IDENTITY template
    SOUL.md template
    TOOLS.md template
    USER template
    Tests
    Token use and costs
    Transcript hygiene
    Onboarding reference
    Contributing to the threat model
    Threat model (MITRE ATLAS)
    Formal verification (security models)
    Network proxy
    Agent bootstrapping
    Docs directory
    Getting started
    Docs hubs
    OpenClaw lore
    Onboarding (macOS app)
    Onboarding overview
    Personal assistant setup
    Setup
    Showcase
    Onboarding (CLI)
    CLI automation
    CLI setup reference
    ACP agents
    ACP agents — setup
    Agent send
    apply_patch tool
    Brave search
    Browser (OpenClaw-managed)
    Browser control API
    Browser troubleshooting
    Browser login
    WSL2 + Windows + remote Chrome CDP troubleshooting
    BTW side questions
    ClawHub
    Code execution
    Creating skills
    Diffs
    DuckDuckGo search
    Elevated mode
    Exa search
    Exec tool
    Exec approvals
    Exec approvals — advanced
    Firecrawl
    Gemini search
    Grok search
    Image generation
    Tools and plugins
    Kimi search
    LLM task
    Lobster
    Tool-loop detection
    Media overview
    MiniMax search
    Multi-agent sandbox and tools
    Music generation
    Ollama web search
    PDF tool
    Perplexity search
    Plugins
    Reactions
    SearXNG search
    Skills
    Skills config
    Slash commands
    Sub-agents
    Tavily
    Thinking levels
    Tokenjuice
    Trajectory bundles
    Text-to-speech
    Video generation
    Web search
    Web fetch
    Linux server
    Control UI
    Dashboard
    Web
    TUI
    WebChat

    OpenAPI Specs

    openapi
    TaskFlow
    docs/openclaw
    Original Docs

    Real-time Synchronized Documentation

    Last sync: 01/05/2026 07:01:44

    Note: This content is mirrored from docs.openclaw.ai and is subject to their terms and conditions.

    OpenClaw Docs

    v2.4.0 Production

    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 plugin

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

    • It only joins an explicit
      text
      https://meet.google.com/...
      URL.
    • It can create a new Meet space through the Google Meet API, then join the returned URL.
    • text
      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
      text
      mode
      : use
      text
      realtime
      for live listen/talk-back, or
      text
      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
      text
      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
      text
      googlemeet
      ;
      text
      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

    text
    realtime.provider: "google"
    :

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

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

    bash
    sudo reboot

    After reboot, verify both pieces:

    bash
    system_profiler SPAudioDataType | grep -i BlackHole command -v sox

    Enable the plugin:

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

    Check setup:

    bash
    openclaw 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

    text
    --mode transcribe
    ; that mode skips realtime audio prerequisites because it does not listen through or speak through the bridge:

    bash
    openclaw googlemeet setup --transport chrome-node --mode transcribe

    When Twilio delegation is configured, setup also reports whether the

    text
    voice-call
    plugin, Twilio credentials, and public webhook exposure are ready. Treat any
    text
    ok: false
    check as a blocker for the checked transport and mode before asking an agent to join. Use
    text
    openclaw googlemeet setup --json
    for scripts or machine-readable output. Use
    text
    --transport chrome
    ,
    text
    --transport chrome-node
    , or
    text
    --transport twilio
    to preflight a specific transport before an agent tries it.

    For Twilio, always preflight the transport explicitly when the default transport is Chrome:

    bash
    openclaw googlemeet setup --transport twilio

    That catches missing

    text
    voice-call
    wiring, Twilio credentials, or unreachable webhook exposure before the agent tries to dial the meeting.

    Join a meeting:

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

    Or let an agent join through the

    text
    google_meet
    tool:

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

    Create a new meeting and join it:

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

    Create only the URL without joining:

    bash
    openclaw googlemeet create --no-join

    text
    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
      text
      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. Join and create flows also try to reuse an existing Meet tab before opening a new one. Matching ignores harmless URL query strings such as
      text
      authuser
      , so an agent retry should focus the already-open meeting instead of creating a second Chrome tab.

    The command/tool output includes a

    text
    source
    field (
    text
    api
    or
    text
    browser
    ) so agents can explain which path was used.
    text
    create
    joins the new meeting by default and returns
    text
    joined: true
    plus the join session. To only mint the URL, use
    text
    create --no-join
    on the CLI or pass
    text
    "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

    text
    google_meet
    with
    text
    action: "create"
    and then share the returned
    text
    meetingUri
    .

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

    For an observe-only/browser-control join, set

    text
    "mode": "transcribe"
    . That does not start the duplex realtime model bridge, does not require BlackHole or SoX, and will not talk back into the meeting. Chrome joins in this mode also avoid OpenClaw's microphone/camera permission grant and avoid the Meet Use microphone path. If Meet shows an audio-choice interstitial, automation tries the no-microphone path and otherwise reports a manual action instead of opening the local microphone.

    During realtime sessions,

    text
    google_meet
    status includes browser and audio bridge health such as
    text
    inCall
    ,
    text
    manualActionRequired
    ,
    text
    providerConnected
    ,
    text
    realtimeReady
    ,
    text
    audioInputActive
    ,
    text
    audioOutputActive
    , last input/output timestamps, byte counters, and bridge closed state. If a safe Meet page prompt appears, browser automation handles it when it can. Login, host admission, and browser/OS permission prompts are reported as manual action with a reason and message for the agent to relay. Managed Chrome sessions only emit the intro or test phrase after browser health reports
    text
    inCall: true
    ; otherwise status reports
    text
    speechReady: false
    and the speech attempt is blocked instead of pretending the agent spoke into the meeting.

    Local Chrome joins through the signed-in OpenClaw browser profile. Realtime mode requires

    text
    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:

    bash
    brew install blackhole-2ch sox

    Reboot the VM after installing BlackHole so macOS exposes

    text
    BlackHole 2ch
    :

    bash
    sudo reboot

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

    bash
    system_profiler SPAudioDataType | grep -i BlackHole command -v sox

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

    bash
    openclaw plugins enable google-meet

    Start the node host in the VM:

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

    If

    text
    <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:

    bash
    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:

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

    text
    OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
    is process environment, not an
    text
    openclaw.json
    setting.
    text
    openclaw node install
    stores it in the LaunchAgent environment when it is present on the install command.

    Approve the node from the Gateway host:

    bash
    openclaw devices list openclaw devices approve <requestId>

    Confirm the Gateway sees the node and that it advertises both

    text
    googlemeet.chrome
    and browser capability/
    text
    browser.proxy
    :

    bash
    openclaw 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:

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

    or ask the agent to use the

    text
    google_meet
    tool with
    text
    transport: "chrome-node"
    .

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

    bash
    openclaw 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

    text
    manualActionRequired: true
    with
    text
    manualActionReason
    and
    text
    manualActionMessage
    . Agents should stop retrying the join, report that exact message plus the current
    text
    browserUrl
    /
    text
    browserTitle
    , and retry only after the manual browser action is complete.

    If

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

    Common failure checks:

    • text
      Configured Google Meet node ... is not usable: offline
      : the pinned node is known to the Gateway but unavailable. Agents should treat that node as diagnostic state, not as a usable Chrome host, and report the setup blocker instead of falling back to another transport unless the user asked for that.
    • text
      No connected Google Meet-capable node
      : start
      text
      openclaw node run
      in the VM, approve pairing, and make sure
      text
      openclaw plugins enable google-meet
      and
      text
      openclaw plugins enable browser
      were run in the VM. Also confirm the Gateway host allows both node commands with
      text
      gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]
      .
    • text
      BlackHole 2ch audio device not found
      : install
      text
      blackhole-2ch
      on the host being checked and reboot before using local Chrome audio.
    • text
      BlackHole 2ch audio device not found on the node
      : install
      text
      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
      text
      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
      text
      browser.defaultProfile: "user"
      or a named existing-session profile.
    • Duplicate Meet tabs: leave
      text
      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
      text
      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:

    • text
      sox
      : command-line audio utility. The plugin uses explicit CoreAudio device commands for the default 24 kHz PCM16 audio bridge.
    • text
      blackhole-2ch
      : macOS virtual audio driver. It creates the
      text
      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

    text
    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 through OpenClaw browser control and joins as the signed-in OpenClaw browser profile. On macOS, the plugin checks for

    text
    BlackHole 2ch
    before launch. If configured, it also runs an audio bridge health command and startup command before opening Chrome. Use
    text
    chrome
    when Chrome/audio live on the Gateway host; use
    text
    chrome-node
    when Chrome/audio live on a paired node such as a Parallels macOS VM. For local Chrome, choose the profile with
    text
    browser.defaultProfile
    ;
    text
    chrome.browserProfile
    is passed to
    text
    chrome-node
    hosts.

    bash
    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

    text
    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:

    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

    text
    openclaw.json
    :

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

    Restart or reload the Gateway after enabling

    text
    voice-call
    ; plugin config changes do not appear in an already running Gateway process until it reloads.

    Then verify:

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

    When Twilio delegation is wired,

    text
    googlemeet setup
    includes successful
    text
    twilio-voice-call-plugin
    ,
    text
    twilio-voice-call-credentials
    , and
    text
    twilio-voice-call-webhook
    checks.

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

    Use

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

    bash
    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

    text
    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 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

    text
    OPENCLAW_GOOGLE_MEET_*
    environment variables.

    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.

    Create Google credentials

    In Google Cloud Console:

    1. Create or select a Google Cloud project.

    2. Enable Google Meet REST API for that project.

    3. Configure the OAuth consent screen.

      • Internal is simplest for a Google Workspace organization.
      • External works for personal/test setups; while the app is in Testing, add each Google account that will authorize the app as a test user.
    4. Add the scopes OpenClaw requests:

      • text
        https://www.googleapis.com/auth/meetings.space.created
      • text
        https://www.googleapis.com/auth/meetings.space.readonly
      • text
        https://www.googleapis.com/auth/meetings.conference.media.readonly
    5. Create an OAuth client ID.

      • Application type: Web application.

      • Authorized redirect URI:

        text
        http://localhost:8085/oauth2callback
    6. Copy the client ID and client secret.

    text
    meetings.space.created
    is required by Google Meet
    text
    spaces.create
    .
    text
    meetings.space.readonly
    lets OpenClaw resolve Meet URLs/codes to spaces.
    text
    meetings.conference.media.readonly
    is for Meet Media API preflight and media work; Google may require Developer Preview enrollment for actual Media API use. If you only need browser-based Chrome joins, skip OAuth entirely.

    Mint the refresh token

    Configure

    text
    oauth.clientId
    and optionally
    text
    oauth.clientSecret
    , or pass them as environment variables, then run:

    bash
    openclaw googlemeet auth login --json

    The command prints an

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

    Examples:

    bash
    OPENCLAW_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:

    bash
    OPENCLAW_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

    text
    oauth
    object under the Google Meet plugin config:

    json5
    { 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

    text
    openclaw googlemeet auth login --json
    so the refresh token has the
    text
    meetings.space.created
    scope.

    Verify OAuth with doctor

    Run the OAuth doctor when you want a fast, non-secret health check:

    bash
    openclaw 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

    text
    ok
    ,
    text
    configured
    ,
    text
    tokenSource
    ,
    text
    expiresAt
    , and check messages; it does not print the access token, refresh token, or client secret.

    Common results:

    CheckMeaning
    text
    oauth-config
    text
    oauth.clientId
    plus
    text
    oauth.refreshToken
    , or a cached access token, is present.
    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
    check resolved an existing Meet space.
    text
    meet-spaces-create
    Optional
    text
    --create-space
    check created a new Meet space.

    To prove Google Meet API enablement and

    text
    spaces.create
    scope as well, run the side-effecting create check:

    bash
    openclaw googlemeet doctor --oauth --create-space --json openclaw googlemeet create --no-join --json

    text
    --create-space
    creates a throwaway Meet URL. Use it when you need to confirm that the Google Cloud project has the Meet API enabled and that the authorized account has the
    text
    meetings.space.created
    scope.

    To prove read access for an existing meeting space:

    bash
    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

    text
    doctor --oauth --meeting
    and
    text
    resolve-space
    prove read access to an existing space that the authorized Google account can access. A
    text
    403
    from these checks usually means the Google Meet REST API is disabled, the consented refresh token is missing the required scope, or the Google account cannot access that Meet space. A refresh-token error means rerun
    text
    openclaw googlemeet auth login --json
    and store the new
    text
    oauth
    block.

    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:

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

    Resolve a Meet URL, code, or

    text
    spaces/{id}
    through
    text
    spaces.get
    :

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

    Run preflight before media work:

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

    List meeting artifacts and attendance after Meet has created conference records:

    bash
    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

    With

    text
    --meeting
    ,
    text
    artifacts
    and
    text
    attendance
    use the latest conference record by default. Pass
    text
    --all-conference-records
    when you want every retained record for that meeting.

    Calendar lookup can resolve the meeting URL from Google Calendar before reading Meet artifacts:

    bash
    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

    text
    --today
    searches today's
    text
    primary
    calendar for a Calendar event with a Google Meet link. Use
    text
    --event <query>
    to search matching event text, and
    text
    --calendar <id>
    for a non-primary calendar. Calendar lookup requires a fresh OAuth login that includes the Calendar events readonly scope.
    text
    calendar-events
    previews the matching Meet events and marks the event that
    text
    latest
    ,
    text
    artifacts
    ,
    text
    attendance
    , or
    text
    export
    will choose.

    If you already know the conference record id, address it directly:

    bash
    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

    Write a readable report:

    bash
    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

    text
    artifacts
    returns conference record metadata plus participant, recording, transcript, structured transcript-entry, and smart-note resource metadata when Google exposes it for the meeting. Use
    text
    --no-transcript-entries
    to skip entry lookup for large meetings.
    text
    attendance
    expands participants into participant-session rows with first/last seen times, total session duration, late/early-leave flags, and duplicate participant resources merged by signed-in user or display name. Pass
    text
    --no-merge-duplicates
    to keep raw participant resources separate,
    text
    --late-after-minutes
    to tune late detection, and
    text
    --early-before-minutes
    to tune early-leave detection.

    text
    export
    writes a folder containing
    text
    summary.md
    ,
    text
    attendance.csv
    ,
    text
    transcript.md
    ,
    text
    artifacts.json
    ,
    text
    attendance.json
    , and
    text
    manifest.json
    .
    text
    manifest.json
    records the chosen input, export options, conference records, output files, counts, token source, Calendar event when one was used, and any partial retrieval warnings. Pass
    text
    --zip
    to also write a portable archive next to the folder. Pass
    text
    --include-doc-bodies
    to export linked transcript and smart-note Google Docs text through Google Drive
    text
    files.export
    ; this requires a fresh OAuth login that includes the Drive Meet readonly scope. Without
    text
    --include-doc-bodies
    , exports include Meet metadata and structured transcript entries only. If Google returns a partial artifact failure, such as a smart-note listing, transcript-entry, or Drive document-body error, the summary and manifest keep the warning instead of failing the whole export. Use
    text
    --dry-run
    to fetch the same artifact/attendance data and print the manifest JSON without creating the folder or ZIP. That is useful before writing a large export or when an agent only needs counts, selected records, and warnings.

    Agents can also create the same bundle through the

    text
    google_meet
    tool:

    json
    { "action": "export", "conferenceRecord": "conferenceRecords/abc123", "includeDocumentBodies": true, "outputDir": "meet-export", "zip": true }

    Set

    text
    "dryRun": true
    to return only the export manifest and skip file writes.

    Run the guarded live smoke against a real retained meeting:

    bash
    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

    Live smoke environment:

    • text
      OPENCLAW_LIVE_TEST=1
      enables guarded live tests.
    • text
      OPENCLAW_GOOGLE_MEET_LIVE_MEETING
      points at a retained Meet URL, code, or
      text
      spaces/{id}
      .
    • text
      OPENCLAW_GOOGLE_MEET_CLIENT_ID
      or
      text
      GOOGLE_MEET_CLIENT_ID
      provides the OAuth client id.
    • text
      OPENCLAW_GOOGLE_MEET_REFRESH_TOKEN
      or
      text
      GOOGLE_MEET_REFRESH_TOKEN
      provides the refresh token.
    • Optional:
      text
      OPENCLAW_GOOGLE_MEET_CLIENT_SECRET
      ,
      text
      OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN
      , and
      text
      OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT
      use the same fallback names without the
      text
      OPENCLAW_
      prefix.

    The base artifact/attendance live smoke needs

    text
    https://www.googleapis.com/auth/meetings.space.readonly
    and
    text
    https://www.googleapis.com/auth/meetings.conference.media.readonly
    . Calendar lookup needs
    text
    https://www.googleapis.com/auth/calendar.events.readonly
    . Drive document-body export needs
    text
    https://www.googleapis.com/auth/drive.meet.readonly
    .

    Create a fresh Meet space:

    bash
    openclaw googlemeet create

    The command prints the new

    text
    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
    text
    google_meet
    tool with
    text
    action: "create"
    to create and join in one step. For URL-only creation, pass
    text
    "join": false
    .

    Example 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

    text
    google_meet
    tool returns structured details instead of a plain string:

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

    text
    manualActionRequired: true
    , it should report the
    text
    manualActionMessage
    plus the browser node/tab context and stop opening new Meet tabs until the operator completes the browser step.

    Example 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

    text
    manualActionRequired: true
    or a browser fallback error and asks the operator to finish Google login before retrying.

    Set

    text
    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

    text
    realtime.provider: "google"
    to use Google Gemini Live:

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

    Set the plugin config under

    text
    plugins.entries.google-meet.config
    :

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

    Defaults:

    • text
      defaultTransport: "chrome"
    • text
      defaultMode: "realtime"
    • text
      chromeNode.node
      : optional node id/name/IP for
      text
      chrome-node
    • text
      chrome.audioBackend: "blackhole-2ch"
    • text
      chrome.guestName: "OpenClaw Agent"
      : name used on the signed-out Meet guest screen
    • text
      chrome.autoJoin: true
      : best-effort guest-name fill and Join Now click through OpenClaw browser automation on
      text
      chrome-node
    • text
      chrome.reuseExistingTab: true
      : activate an existing Meet tab instead of opening duplicates
    • text
      chrome.waitForInCallMs: 20000
      : wait for the Meet tab to report in-call before the realtime intro is triggered
    • text
      chrome.audioFormat: "pcm16-24khz"
      : command-pair audio format. Use
      text
      "g711-ulaw-8khz"
      only for legacy/custom command pairs that still emit telephony audio.
    • text
      chrome.audioInputCommand
      : SoX command reading from CoreAudio
      text
      BlackHole 2ch
      and writing audio in
      text
      chrome.audioFormat
    • text
      chrome.audioOutputCommand
      : SoX command reading audio in
      text
      chrome.audioFormat
      and writing to CoreAudio
      text
      BlackHole 2ch
    • text
      realtime.provider: "openai"
    • text
      realtime.toolPolicy: "safe-read-only"
    • text
      realtime.instructions
      : brief spoken replies, with
      text
      openclaw_agent_consult
      for deeper answers
    • text
      realtime.introMessage
      : short spoken readiness check when the realtime bridge connects; set it to
      text
      ""
      to join silently
    • text
      realtime.agentId
      : optional OpenClaw agent id for
      text
      openclaw_agent_consult
      ; defaults to
      text
      main

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

    text
    voiceCall.enabled
    defaults to
    text
    true
    ; with Twilio transport it delegates the actual PSTN call, DTMF, and intro greeting to the Voice Call plugin. Voice Call plays the DTMF sequence before opening the realtime media stream, then uses the saved intro text as the initial realtime greeting. If
    text
    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

    text
    google_meet
    tool:

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

    Use

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

    Use

    text
    action: "status"
    to list active sessions or inspect a session ID. Use
    text
    action: "speak"
    with
    text
    sessionId
    and
    text
    message
    to make the realtime agent speak immediately. Use
    text
    action: "test_speech"
    to create or reuse the session, trigger a known phrase, and return
    text
    inCall
    health when the Chrome host can report it.
    text
    test_speech
    always forces
    text
    mode: "realtime"
    and fails if asked to run in
    text
    mode: "transcribe"
    because observe-only sessions intentionally cannot emit speech. Its
    text
    speechOutputVerified
    result is based on realtime audio output bytes increasing during this test call, so a reused session with older audio does not count as a fresh successful speech check. Use
    text
    action: "leave"
    to mark a session ended.

    text
    status
    includes Chrome health when available:

    • text
      inCall
      : Chrome appears to be inside the Meet call
    • text
      micMuted
      : best-effort Meet microphone state
    • text
      manualActionRequired
      /
      text
      manualActionReason
      /
      text
      manualActionMessage
      : the browser profile needs manual login, Meet host admission, permissions, or browser-control repair before speech can work
    • text
      speechReady
      /
      text
      speechBlockedReason
      /
      text
      speechBlockedMessage
      : whether managed Chrome speech is allowed now.
      text
      speechReady: false
      means OpenClaw did not send the intro/test phrase into the audio bridge.
    • text
      providerConnected
      /
      text
      realtimeReady
      : realtime voice bridge state
    • text
      lastInputAt
      /
      text
      lastOutputAt
      : last audio seen from or sent to the bridge
    json
    { "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

    text
    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.

    By default, consults run against the

    text
    main
    agent. Set
    text
    realtime.agentId
    when a Meet lane should consult a dedicated OpenClaw agent workspace, model defaults, tool policy, memory, and session history.

    text
    realtime.toolPolicy
    controls the consult run:

    • text
      safe-read-only
      : expose the consult tool and limit the regular agent to
      text
      read
      ,
      text
      web_search
      ,
      text
      web_fetch
      ,
      text
      x_search
      ,
      text
      memory_search
      , and
      text
      memory_get
      .
    • text
      owner
      : expose the consult tool and let the regular agent use the normal agent tool policy.
    • text
      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:

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

    For the full join-and-speak smoke:

    bash
    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:

    bash
    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:

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

    bash
    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:

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

    Expected Twilio state:

    • text
      googlemeet setup
      includes green
      text
      twilio-voice-call-plugin
      ,
      text
      twilio-voice-call-credentials
      , and
      text
      twilio-voice-call-webhook
      checks.
    • text
      voicecall
      is available in the CLI after Gateway reload.
    • The returned session has
      text
      transport: "twilio"
      and a
      text
      twilio.voiceCallId
      .
    • text
      openclaw logs --follow
      shows DTMF TwiML served before realtime TwiML, then a realtime bridge with the initial greeting queued.
    • text
      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:

    bash
    openclaw plugins list | grep google-meet openclaw googlemeet setup

    If you just edited

    text
    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:

    bash
    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:

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

    The node must be connected and list

    text
    googlemeet.chrome
    plus
    text
    browser.proxy
    . The Gateway config must allow those node commands:

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

    If

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

    bash
    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:

    bash
    openclaw googlemeet setup openclaw nodes status --connected

    Browser opens but agent cannot join

    Run

    text
    googlemeet test-speech
    and inspect the returned Chrome health. If it reports
    text
    manualActionRequired: true
    , show
    text
    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

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

    • For API creation:
      text
      oauth.clientId
      and
      text
      oauth.refreshToken
      are configured, or matching
      text
      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
      text
      meetings.space.created
      scope; rerun
      text
      openclaw googlemeet auth login --json
      and update plugin config.
    • For browser fallback:
      text
      defaultTransport: "chrome-node"
      and
      text
      chromeNode.node
      point at a connected node with
      text
      browser.proxy
      and
      text
      googlemeet.chrome
      .
    • For browser fallback: the OpenClaw Chrome profile on that node is signed in to Google and can open
      text
      https://meet.google.com/new
      .
    • For browser fallback: retries reuse an existing
      text
      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 the tool returns
      text
      manualActionRequired: true
      , use the returned
      text
      browser.nodeId
      ,
      text
      browser.targetId
      ,
      text
      browserUrl
      , and
      text
      manualActionMessage
      to guide the operator. Do not retry in a loop until that action is complete.
    • 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
      text
      meet-audio-choice-required
      , not
      text
      google-login-required
      .

    Agent joins but does not talk

    Check the realtime path:

    bash
    openclaw googlemeet setup openclaw googlemeet doctor

    Use

    text
    mode: "realtime"
    for listen/talk-back.
    text
    mode: "transcribe"
    intentionally does not start the duplex realtime voice bridge.
    text
    googlemeet test-speech
    always checks the realtime path and reports whether bridge output bytes were observed for that invocation. If
    text
    speechOutputVerified
    is false and
    text
    speechOutputTimedOut
    is true, the realtime provider may have accepted the utterance but OpenClaw did not see new output bytes reach the Chrome audio bridge.

    Also verify:

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

    text
    googlemeet doctor [session-id]
    prints the session, node, in-call state, manual action reason, realtime provider connection,
    text
    realtimeReady
    , audio input/output activity, last audio timestamps, byte counters, and browser URL. Use
    text
    googlemeet status [session-id] --json
    when you need the raw JSON. Use
    text
    googlemeet doctor --oauth
    when you need to verify Google Meet OAuth refresh without exposing tokens; add
    text
    --meeting
    or
    text
    --create-space
    when you need a Google Meet API proof as well.

    If an agent timed out and you can see a Meet tab already open, inspect that tab without opening another one:

    bash
    openclaw googlemeet recover-tab openclaw googlemeet recover-tab https://meet.google.com/abc-defg-hij

    The equivalent tool action is

    text
    recover_current_tab
    . It focuses and inspects an existing Meet tab for the selected transport. With
    text
    chrome
    , it uses local browser control through the Gateway; with
    text
    chrome-node
    , it uses the configured Chrome node. It does not open a new tab or create a new session; it reports the current blocker, such as login, admission, permissions, or audio-choice state. The CLI command talks to the configured Gateway, so the Gateway must be running;
    text
    chrome-node
    also requires the Chrome node to be connected.

    Twilio setup checks fail

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

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

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

    text
    twilio-voice-call-webhook
    fails when
    text
    voice-call
    has no public webhook exposure, or when
    text
    publicUrl
    points at loopback or private network space. Set
    text
    plugins.entries.voice-call.config.publicUrl
    to the public provider URL or configure a
    text
    voice-call
    tunnel/Tailscale exposure.

    Loopback and private URLs are not valid for carrier callbacks. Do not use

    text
    localhost
    ,
    text
    127.0.0.1
    ,
    text
    0.0.0.0
    ,
    text
    10.x
    ,
    text
    172.16.x
    -
    text
    172.31.x
    ,
    text
    192.168.x
    ,
    text
    169.254.x
    ,
    text
    fc00::/7
    , or
    text
    fd00::/8
    as
    text
    publicUrl
    .

    For 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:

    bash
    openclaw googlemeet setup --transport twilio openclaw voicecall setup openclaw voicecall smoke

    text
    voicecall smoke
    is readiness-only by default. To dry-run a specific number:

    bash
    openclaw voicecall smoke --to "+15555550123"

    Only add

    text
    --yes
    when you intentionally want to place a live outbound notify call:

    bash
    openclaw voicecall smoke --to "+15555550123" --yes

    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:

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

    Use leading

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

    If the phone call is created but the Meet roster never shows the dial-in participant:

    • Run
      text
      openclaw voicecall status --call-id <id>
      and confirm the call is still active.
    • Run
      text
      openclaw voicecall tail
      and check that Twilio webhooks are arriving at the Gateway.
    • Run
      text
      openclaw logs --follow
      and look for the Twilio Meet sequence: Google Meet delegates the join, Voice Call stores pre-connect DTMF TwiML, serves that initial TwiML, then serves realtime TwiML and starts the realtime bridge with
      text
      initialGreeting=queued
      .
    • Re-run
      text
      openclaw googlemeet setup --transport twilio
      ; a green setup check is required but does not prove the meeting PIN sequence is correct.
    • Confirm the dial-in number belongs to the same Meet invitation and region as the PIN.
    • Increase the leading pauses in
      text
      --dtmf-sequence
      if Meet answers slowly, for example
      text
      wwww123456#
      .
    • If the participant joins but you do not hear the greeting, check
      text
      openclaw logs --follow
      for realtime TwiML, realtime bridge startup, and
      text
      initialGreeting=queued
      . The greeting is generated from the initial
      text
      voicecall.start
      message after the realtime bridge connects.

    If webhooks do not arrive, debug the Voice Call plugin first: the provider must reach

    text
    plugins.entries.voice-call.config.publicUrl
    or the configured tunnel. See Voice call troubleshooting.

    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

    text
    BlackHole 2ch
    plus either:

    • text
      chrome.audioInputCommand
      plus
      text
      chrome.audioOutputCommand
      : OpenClaw owns the realtime model bridge and pipes audio in
      text
      chrome.audioFormat
      between those commands and the selected realtime voice provider. The default Chrome path is 24 kHz PCM16; 8 kHz G.711 mu-law remains available for legacy command pairs.
    • text
      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.

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

    Related

    • Voice call plugin
    • Talk mode
    • Building plugins

    © 2024 TaskFlow Mirror

    Powered by TaskFlow Sync Engine