arizuko › components › whapd
whapd is the WhatsApp channel adapter. It speaks WhatsApp Web through the Baileys socket library (TypeScript / Node, the only non-Go adapter in the core), posts inbound to gated, and sends outbound through the same socket. JID prefix is whatsapp:; per-conversation JIDs are whatsapp:<jid> where jid is the Baileys-native form (phone-number@s.whatsapp.net or group-id@g.us).
WhatsApp has no usable consumer API. The official Cloud API is partner-gated and quota-limited; everyone else uses a WhatsApp Web client. Baileys has no Go port, so whapd lives in TypeScript. Pairing credentials persist in $WHATSAPP_AUTH_DIR/creds.json with an atomic .bak rotation; a fresh install requires pairing.
WhatsApp (web.whatsapp.com socket)
| Baileys multi-device socket
v
whapd (LISTEN_ADDR=:8080, Node runtime)
| POST /v1/messages (signed by CHANNEL_SECRET)
v
gated
| POST /v1/send (callback to whapd)
v
whapd (sock.sendMessage / reactMessage / delete)
|
v
WhatsApp
Wired verbs (whapd/src/server.ts): send (sendMessage(jid, {text}), honours reply_to via Baileys quoted), send_file (image / video / audio / document by mime sniff), typing (composing / paused presence with refresher), like (reaction; emoji selectable via reaction field, default 👍), edit (own messages, 15-min window), delete (own-message redaction), forward (best-effort — synthesizes forwarded text since Baileys only gives source_msg_id). quote, repost, dislike, post are 501-with-hint — dislike redirects to like(reaction='👎').
No fetch_history: Baileys’ history sync is unreliable across the LID/JID translation Meta introduced in 2024; the gateway falls back to its local cache.
Two paths, both token-less:
--pair <phone> on the binary, or the self-service flow at /dash/channels/whatsapp/pair (shipped v0.40.2). The operator enters the bot phone number; whapd prints an 8-character code; the operator types it on the phone instead of scanning a QR. Useful for headless deploys.Lose creds.json and the device is unlinked — re-pair. whapd backs up to creds.json.bak on every save and recovers from it on a crash. The outbound queue is persisted to disk and auto-resumes on reconnect.
export ROUTER_URL=http://gated:8080
export CHANNEL_SECRET=$(grep ^CHANNEL_SECRET .env | cut -d= -f2)
export LISTEN_ADDR=:8080
export WHATSAPP_AUTH_DIR=/srv/data/store/whatsapp-auth
export DATA_DIR=/srv/data/arizuko_demo
node dist/main.js
GET /health returns 503 while waiting for QR / pairing-code scan and while the Baileys socket is disconnected. The container log carries the QR; sudo docker logs arizuko-<inst>-whapd-1 on the host.
whapd/README.md — verb table, file map, edit/delete window.