Gmail Pub/Sub -> OpenClaw

Objetivo: Gmail watch -> push de Pub/Sub -> gog gmail watch serve -> webhook de OpenClaw.

Requisitos previos

  • gcloud instalado y con sesión iniciada (guía de instalación).
  • gog (gogcli) instalado y autorizado para la cuenta de Gmail (gogcli.sh).
  • Hooks de OpenClaw habilitados (consulta Webhooks).
  • tailscale con sesión iniciada (tailscale.com). La configuración soportada usa Tailscale Funnel para el endpoint HTTPS público. Otros servicios de túnel pueden funcionar, pero no están soportados oficialmente y requieren configuración manual. Por ahora, Tailscale es lo que soportamos.

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

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

Para entregar el resumen de Gmail a una superficie de chat, sobreescribe el preset con un mapeo que configure deliver + opcionales channel/to:

{
  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}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}\n{{messages[0].body}}",
        model: "openai/gpt-5.2-mini",
        deliver: true,
        channel: "last",
        // to: "+15551234567"
      },
    ],
  },
}

Si quieres un canal fijo, configura channel + to. De lo contrario, channel: "last" usa la última ruta de entrega (recurre a WhatsApp).

Para forzar un modelo más económico para las ejecuciones de Gmail, configura model en el mapeo (provider/model o alias). Si aplicas agents.defaults.models, inclúyelo ahí.

Para establecer un modelo y nivel de razonamiento predeterminados específicamente para los hooks de Gmail, agrega hooks.gmail.model / hooks.gmail.thinking en tu configuración:

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

Notas:

  • El model/thinking por hook en el mapeo sigue sobreescribiendo estos valores predeterminados.
  • Orden de prioridad: hooks.gmail.modelagents.defaults.model.fallbacks → primario (auth/rate-limit/timeouts).
  • Si agents.defaults.models está configurado, el modelo de Gmail debe estar en la lista permitida.
  • El contenido del hook de Gmail se envuelve con límites de seguridad de contenido externo por defecto. Para deshabilitarlo (peligroso), configura hooks.gmail.allowUnsafeExternalContent: true.

Para personalizar aún más el manejo del payload, agrega hooks.mappings o un módulo de transformación JS/TS bajo ~/.openclaw/hooks/transforms (consulta Webhooks).

Asistente (recomendado)

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

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

Valores predeterminados:

  • Usa Tailscale Funnel para el endpoint público de push.
  • Escribe la configuración hooks.gmail para openclaw webhooks gmail run.
  • Habilita el preset del hook de Gmail (hooks.presets: ["gmail"]).

Nota sobre rutas: cuando tailscale.mode está habilitado, OpenClaw configura automáticamente hooks.gmail.serve.path en / y mantiene la ruta pública en hooks.gmail.tailscale.path (por defecto /gmail-pubsub) porque Tailscale elimina el prefijo set-path antes del proxying. Si necesitas que el backend reciba la ruta con prefijo, configura hooks.gmail.tailscale.target (o --tailscale-target) con una URL completa como http://127.0.0.1:8788/gmail-pubsub y haz coincidir hooks.gmail.serve.path.

¿Quieres un endpoint personalizado? Usa --push-endpoint <url> o --tailscale off.

Nota de plataforma: en macOS el asistente instala gcloud, gogcli y tailscale vía Homebrew; en Linux instálalos manualmente primero.

Auto-inicio del gateway (recomendado):

  • Cuando hooks.enabled=true y hooks.gmail.account está configurado, el Gateway inicia gog gmail watch serve al arrancar y renueva automáticamente el watch.
  • Configura OPENCLAW_SKIP_GMAIL_WATCHER=1 para excluirte (útil si ejecutas el daemon tú mismo).
  • No ejecutes el daemon manual al mismo tiempo, o tendrás listen tcp 127.0.0.1:8788: bind: address already in use.

Daemon manual (inicia gog gmail watch serve + auto-renovación):

openclaw webhooks gmail run

Configuración única

  1. Selecciona el proyecto de GCP que posee el cliente OAuth usado por gog.
gcloud auth login
gcloud config set project <project-id>

Nota: Gmail watch requiere que el tema de Pub/Sub esté en el mismo proyecto que el cliente OAuth.

  1. Habilita las APIs:
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
  1. Crea un tema:
gcloud pubsub topics create gog-gmail-watch
  1. Permite que el push de Gmail publique:
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \
  --member=serviceAccount:[email protected] \
  --role=roles/pubsub.publisher

Iniciar el watch

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

Guarda el history_id de la salida (para depuración).

Ejecutar el manejador de push

Ejemplo local (auth con token compartido):

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:

  • --token protege el endpoint de push (x-gog-token o ?token=).
  • --hook-url apunta a OpenClaw /hooks/gmail (mapeado; ejecución aislada + resumen a principal).
  • --include-body y --max-bytes controlan el fragmento del cuerpo enviado a OpenClaw.

Recomendado: openclaw webhooks gmail run envuelve el mismo flujo y renueva automáticamente el watch.

Exponer el manejador (avanzado, sin soporte)

Si necesitas un túnel que no sea Tailscale, conéctalo manualmente y usa la URL pública en la suscripción push (sin soporte, sin garantías):

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

Usa la URL generada como el endpoint de push:

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

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

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

Prueba

Envía un mensaje a la bandeja monitoreada:

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

Verifica el estado del watch y el historial:

gog gmail watch status --account [email protected]
gog gmail history --account [email protected] --since <historyId>

Solución de problemas

  • Invalid topicName: discrepancia de proyecto (el tema no está en el proyecto del cliente OAuth).
  • User not authorized: falta roles/pubsub.publisher en el tema.
  • Mensajes vacíos: el push de Gmail solo proporciona historyId; obtén los datos vía gog gmail history.

Limpieza

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