whatsapp-gotify-relay
v1.0.0Use when operating or extending this WhatsApp Gotify relay as the bridge to OpenClaw. Prefer Unix tools for Docker, logs, Gotify queue checks, webhook valida...
Like a lobster shell, security has layers — review code before you run it.
Runtime requirements
OpenClaw
Use this skill when working on this repository as the WhatsApp bridge for OpenClaw.
Purpose
This project sits between WhatsApp and OpenClaw.
It does two directions of communication:
- OpenClaw sends outbound WhatsApp jobs through Gotify.
- The relay sends inbound WhatsApp events and connection status back to OpenClaw through webhooks.
Bridge model
Outbound path
OpenClaw posts JSON into the Gotify outbox application:
{
"type": "send",
"to": "+12025550101",
"text": "hello from openclaw"
}
The relay polls that outbox, sends to WhatsApp, deletes the queue item on success, and emits a send_result.
Inbound path
OpenClaw receives webhook JSON from the relay.
Webhook event types:
conversationsend_resultstatus
Only meaningful WhatsApp activity should produce conversation events. History sync, protocol chatter, and other Baileys internals should stay filtered out.
Payload shape
The relay should keep payloads flat and readable.
Conversation
{
"type": "conversation",
"relay": "whatsapp-gotify-relay",
"direction": "inbound",
"jid": "12025550101@s.whatsapp.net",
"senderJid": "12025550101@s.whatsapp.net",
"pushName": "John",
"timestamp": 1776948451,
"messageId": "ABC123",
"text": "hello",
"contentType": "text"
}
Send result
{
"type": "send_result",
"relay": "whatsapp-gotify-relay",
"status": "sent",
"requestId": 5544,
"to": "12025550101@s.whatsapp.net",
"messageId": "3EB0...",
"error": null,
"timestamp": "2026-04-23T12:48:56.415Z"
}
Status
{
"type": "status",
"relay": "whatsapp-gotify-relay",
"connection": "open",
"phase": "connected",
"qr": null,
"statusCode": null,
"details": null,
"timestamp": "2026-04-23T12:48:56.415Z"
}
If WhatsApp remains disconnected, the relay sends a status reminder every 3 hours by default.
Public relay env vars
The relay runtime env surface is:
PORTAPP_LOG_LEVELWHATSAPP_AUTH_DIRWHATSAPP_PAIRING_NUMBERWHATSAPP_SYNC_FULL_HISTORYGOTIFY_BASE_URLGOTIFY_EVENTS_APP_TOKENGOTIFY_OUTBOX_TOKENGOTIFY_OUTBOX_APPLICATION_IDGOTIFY_POLL_INTERVAL_MSGOTIFY_EVENTS_PRIORITYGOTIFY_RESULTS_PRIORITYWEBHOOK_URLWEBHOOK_BEARER_TOKENWEBHOOK_TIMEOUT_MSWEBHOOK_DISCONNECTED_INTERVAL_MSRELAY_NAME
OpenClaw-side env concepts
On the OpenClaw side, the important configuration concepts are:
- Gotify base URL
- Gotify outbox application id
- Gotify outbox write token
- webhook shared secret or bearer token expected from the relay
- relay name if multiple relays exist
Keep the names OpenClaw already uses if they exist. Do not rename OpenClaw env vars just to match the relay.
Preferred tools
Prefer Unix tools and simple shell commands:
rgsed -nnpm testdocker compose psdocker compose logs --tail=... connectordocker compose up -d --build connectorcurlgit status --short
Common operations
Run tests
npm test
Rebuild the relay
docker compose up -d --build connector
Follow relay logs
docker compose logs -f connector
Inspect the outbox queue
curl -sS "${GOTIFY_BASE_URL}/application/${GOTIFY_OUTBOX_APPLICATION_ID}/message?token=${GOTIFY_OUTBOX_TOKEN}&limit=10"
Post a manual outbox send
curl -sS \
-H 'Content-Type: application/json' \
-d '{"title":"smoke-test","message":"{\"type\":\"send\",\"to\":\"447550002572\",\"text\":\"smoke test\"}","priority":5}' \
"${GOTIFY_BASE_URL}/message?token=${GOTIFY_OUTBOX_APP_TOKEN}"
GOTIFY_OUTBOX_APP_TOKEN is an operator-side token for manually writing to the outbox app. It is not required by the relay runtime.
Guardrails
- Keep Gotify and webhook payloads lean.
- Do not dump raw Baileys payloads into Gotify.
- Keep webhook and Gotify contracts aligned.
- Update
.env.example,README.md, and tests together when the contract changes.
Comments
Loading comments...
