OpenClawSkills
GitHub
Automatización • 5 min de lectura

Gmail Pub/Sub

Entregar Gmail Pub/Sub a webhooks de OpenClaw vía gogcli.

Objetivo: Gmail watch → Pub/Sub push → '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog gmail watch serve'</code>' → webhook de OpenClaw.

Tutorial.step

Requisitos previos

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gcloud'</code>' instalado y con sesión iniciada ('<a href="https://docs.cloud.google.com/sdk/docs/install-sdk" className="text-emerald-400 hover:text-emerald-300 transition-colors">'guía de instalación'</a>').

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog'</code>' (gogcli) instalado y autorizado para tu cuenta Gmail ('<a href="https://gogcli.sh/" className="text-emerald-400 hover:text-emerald-300 transition-colors">'gogcli.sh'</a>').

- Hooks de OpenClaw habilitados (ver '<a href="/automation/webhook" className="text-emerald-400 hover:text-emerald-300 transition-colors">'Webhooks'</a>').

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'tailscale'</code>' con sesión iniciada ('<a href="https://tailscale.com/" className="text-emerald-400 hover:text-emerald-300 transition-colors">'tailscale.com'</a>'). La configuración soportada usa Tailscale Funnel como endpoint HTTPS público.

Otros servicios de túnel funcionan pero son DIY/no soportados y requieren cableado manual.

Actualmente, soportamos Tailscale.

Ejemplo de configuración de hook (habilita mapeo preset de Gmail):

Json5
{
  hooks: {
    enabled: true,
    token: "OPENCLAW_HOOK_TOKEN",
    path: "/hooks",
    presets: ["gmail"],
  },
}

Para entregar resúmenes de Gmail al chat, usa mapeo para sobrescribir preset

Establece '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver'</code>' + opcional '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>'/'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>':

Json5
{
  hooks: {
    enabled: true,
    token: "OPENCLAW_HOOK_TOKEN",
    presets: ["gmail"],
    mappings: [
      {
        match: { path: "gmail" },
        action: "agent",
        wakeMode: "now",
        name: "Gmail",
        sessionKey: "hook:gmail:{{messages[0].id}}",
        messageTemplate: "New email from {{messages[0].from}}
Subject: {{messages[0].subject}}
{{messages[0].snippet}}
{{messages[0].body}}",
        model: "openai/gpt-5.2-mini",
        deliver: true,
        channel: "last",
        // to: "+15551234567"
      },
    ],
  },
}

Si quieres un canal fijo, establece '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>' + '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>'. De lo contrario '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel: "last"'</code>'

usa la última ruta de entrega (retrocede a WhatsApp).

Para forzar Gmail a usar un modelo más barato, establece '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>' en mapeo

('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'provider/model'</code>' o alias). Si aplicas '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agents.defaults.models'</code>', inclúyelo allí.

Para establecer modelo por defecto y nivel de thinking específicamente para hooks de Gmail, añade

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.model'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.thinking'</code>' en config:

Json5
{
  hooks: {
    gmail: {
      model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
      thinking: "off",
    },
  },
}

Notas:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>'/'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'thinking'</code>' por hook en mapeo aún sobrescribe estos valores por defecto.

- Orden de fallback: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.model'</code>' → '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agents.defaults.model.fallbacks'</code>' → primario (auth/rate limit/timeout).

- Si '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agents.defaults.models'</code>' está establecido, el modelo de Gmail debe estar en lista permitida.

- Por defecto, el contenido de hook de Gmail se envuelve con límite de seguridad de contenido externo.

Para deshabilitar (peligroso), establece '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.allowUnsafeExternalContent: true'</code>'.

Para personalizar más el manejo de payload, añade '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.mappings'</code>' o módulos de transformación JS/TS

bajo '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.transformsDir'</code>' (ver '<a href="/automation/webhook" className="text-emerald-400 hover:text-emerald-300 transition-colors">'Webhooks'</a>').

Tutorial.step

Asistente (recomendado)

Usa el asistente de OpenClaw para conectar todo (instala dependencias vía brew en macOS):

Bash
openclaw webhooks gmail setup   --account [email protected]

Valores por defecto:

- Usa Tailscale Funnel como endpoint push público.

- Escribe config de '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail'</code>' para '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw webhooks gmail run'</code>'.

- Habilita preset de hook de Gmail ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.presets: ["gmail"]'</code>').

Notas de ruta: Cuando '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'tailscale.mode'</code>' está habilitado, OpenClaw automáticamente establece

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.serve.path'</code>' a '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/'</code>' y mantiene ruta pública en

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.tailscale.path'</code>' (por defecto '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/gmail-pubsub'</code>') porque Tailscale

elimina el prefijo set-path antes del proxy.

Si el backend necesita recibir ruta con prefijo, establece

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.tailscale.target'</code>' (o '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--tailscale-target'</code>') a URL completa, ej.

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'http://127.0.0.1:8788/gmail-pubsub'</code>' y coincide con '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.serve.path'</code>'.

¿Quieres endpoint personalizado? Usa '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--push-endpoint &lt;url&gt;'</code>' o '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--tailscale off'</code>'.

Notas de plataforma: En macOS, el asistente instala '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gcloud'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gogcli'</code>' y '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'tailscale'</code>'

vía homebrew; en Linux instálalos manualmente primero.

Auto-inicio del Gateway (recomendado):

- Cuando '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.enabled=true'</code>' y '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.account'</code>' están establecidos, el gateway inicia

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog gmail watch serve'</code>' y auto-actualiza watch.

- Establece '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'OPENCLAW_SKIP_GMAIL_WATCHER=1'</code>' para optar por no participar (útil si ejecutas el daemon tú mismo).

- No ejecutes daemon manual concurrentemente o obtendrás

'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'listen tcp 127.0.0.1:8788: bind: address already in use'</code>'.

Daemon manual (iniciar '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog gmail watch serve'</code>' + auto-renovación):

Bash
openclaw webhooks gmail run
Tutorial.step

Configuración única

1. Selecciona proyecto GCP que posee el cliente OAuth usado por '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog'</code>'.

Bash
gcloud auth login
gcloud config set project <project-id>

Nota: Gmail watch requiere que el tópico Pub/Sub esté en el mismo proyecto que el cliente OAuth.

2. Habilitar APIs:

Bash
gcloud services enable gmail.googleapis.com pubsub.googleapis.com

3. Crear tópico:

Bash
gcloud pubsub topics create gog-gmail-watch

4. Permitir push de Gmail para publicar:

Bash
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch   --member=serviceAccount:[email protected]   --role=roles/pubsub.publisher
Tutorial.step

Iniciar watch

Bash
gog gmail watch start   --account [email protected]   --label INBOX   --topic projects/<project-id>/topics/gog-gmail-watch

Guarda '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'history_id'</code>' de la salida (para depuración).

Tutorial.step

Ejecutar manejador push

Ejemplo local (auth de token compartido):

Bash
gog gmail watch serve   --account [email protected]   --bind 127.0.0.1   --port 8788   --path /gmail-pubsub   --token <shared>   --hook-url http://127.0.0.1:18789/hooks/gmail   --hook-token OPENCLAW_HOOK_TOKEN   --include-body   --max-bytes 20000

Notas:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--token'</code>' protege endpoint push ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'x-gog-token'</code>' o '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'?token='</code>').

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--hook-url'</code>' apunta a '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/hooks/gmail'</code>' de OpenClaw (mapeo; ejecución aislada + resumen al principal).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--include-body'</code>' y '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--max-bytes'</code>' controlan fragmento de cuerpo enviado a OpenClaw.

Recomendado: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw webhooks gmail run'</code>' envuelve el mismo flujo y auto-actualiza watch.

Tutorial.step

Exponer manejador (avanzado, no soportado)

Si necesitas túnel no-Tailscale, cablea manualmente y usa URL pública en suscripción

push (no soportado, sin barreras de protección):

Bash
cloudflared tunnel --url http://127.0.0.1:8788 --no-autoupdate

Usa URL generada como endpoint push:

Bash
gcloud pubsub subscriptions create gog-gmail-watch-push   --topic gog-gmail-watch   --push-endpoint "https://<public-url>/gmail-pubsub?token=<shared>"

Producción: Usa endpoint HTTPS estable y configura Pub/Sub OIDC JWT, luego ejecuta:

Bash
gog gmail watch serve --verify-oidc --oidc-email <svc@...>
Tutorial.step

Prueba

Envía mensaje a inbox vigilado:

Bash
gog gmail send   --account [email protected]   --to [email protected]   --subject "watch test"   --body "ping"

Verifica estado de watch e historial:

Bash
gog gmail watch status --account [email protected]
gog gmail history --account [email protected] --since <historyId>
Tutorial.step

Solución de problemas

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'Invalid topicName'</code>': desajuste de proyecto (tópico no está en proyecto del cliente OAuth).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'User not authorized'</code>': al tópico le falta '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'roles/pubsub.publisher'</code>'.

- Mensajes vacíos: Gmail push solo proporciona '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'historyId'</code>'; obtén vía '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'gog gmail history'</code>'.

Tutorial.step

Limpieza

Bash
gog gmail watch stop --account [email protected]
gcloud pubsub subscriptions delete gog-gmail-watch-push
gcloud pubsub topics delete gog-gmail-watch