Agent skill
GREEN-API Webhooks Skill
Receive and verify GREEN-API (green-api.com WhatsApp API gateway) webhooks. Use when setting up a GREEN-API Webhook Endpoint, validating the webhookUrlToken Authorization header, or handling typeWebhook notifications like incomingMessageReceived, outgoingMessageStatus, outgoingAPIMessageReceived, and stateInstanceChanged.
Install this skill
npx skills add hookdeck/webhook-skills --skill green-api-webhooks
GREEN-API is a WhatsApp API gateway. With the Webhook Endpoint technology, the GREEN-API server POSTs a JSON notification to your webhookUrl for every incoming message, outgoing message status, instance state change, call, and so on. The notification type is in the body's typeWebhook field.
When to Use This Skill
- How do I receive GREEN-API WhatsApp webhooks?
- How do I verify GREEN-API webhooks / check the
webhookUrlToken? - How do I handle
incomingMessageReceivedoroutgoingMessageStatusnotifications? - Why does my GREEN-API webhook get 401 when I set a Webhook URL Token?
- Why am I receiving the same GREEN-API notification more than once?
Verification (core)
GREEN-API webhooks have no signature: there is no HMAC, no timestamp, and no Standard Webhooks headers. The only authentication is the optional webhookUrlToken instance setting.
Caveat: when
webhookUrlTokenis set, GREEN-API sends it as the fullAuthorizationheader value, including the scheme:Bearer <token>(default) orBasic <token>. Compare the whole header value, scheme included, with a constant-time compare. Don't stripBearerand compare only the token.
const crypto = require('crypto');
// webhookUrlToken as entered in GREEN-API: "Bearer abc", "Basic abc", or bare "abc" (sent as "Bearer abc")
function expectedAuthorization(token) {
return /^(Bearer|Basic) /.test(token) ? token : `Bearer ${token}`;
}
function verifyGreenApiAuthorization(header, token) {
if (!header || !token) return false;
const a = Buffer.from(header);
const b = Buffer.from(expectedAuthorization(token));
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Return 401 on a mismatch. Return 200 quickly on success: GREEN-API retries undelivered notifications every minute for up to 24 hours, so make handlers idempotent (dedupe on idMessage where present).
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
Dispatch on the body's typeWebhook field:
typeWebhook | Description |
|---|---|
incomingMessageReceived | Incoming message or file (messageData.typeMessage gives the kind: textMessage, imageMessage, ...) |
outgoingMessageReceived | Message sent from the phone |
outgoingAPIMessageReceived | Message sent via the API |
outgoingMessageStatus | Status of a sent message (sent, delivered, read, failed, noAccount, ...) |
stateInstanceChanged | Instance authorization state (authorized, notAuthorized, blocked, ...) |
statusInstanceChanged | Instance socket state (online, offline) |
incomingCall | Incoming call |
For the full list, see GREEN-API incoming webhook types.
Environment Variables
# Exactly what you entered as webhookUrlToken, e.g. "Bearer my-secret" or "Basic dXNlcjpwYXNz".
# A bare token without a scheme is treated as "Bearer <token>".
GREEN_API_WEBHOOK_URL_TOKEN=Bearer your-long-random-secret
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 green-api --path /webhooks/green-api
Reference Materials
- references/overview.md - GREEN-API notification types and payload structure
- references/setup.md - Set
webhookUrl/webhookUrlTokenin the console or with SetSettings - references/verification.md - Authorization header details, IP allowlist, and gotchas