Skip to content

WhatsApp Channel

Agentcy talks to WhatsApp through a local Node.js gateway (Baileys). The gateway handles the long-lived websocket to Meta; Agentcy handles the LLM side. Pairing uses the standard QR-code "Linked devices" flow — no WhatsApp Business API application required.

Prerequisites

  • Node.js ≥ 18 on the host running the API.
  • A WhatsApp account you control (the gateway pairs as a linked device).
  • Enough disk space for the gateway's session state (~/.openfang/whatsapp-gateway/).

Configure

From the UI (/channels → WhatsApp → Configure) or the API:

bash
curl -X POST http://localhost:8080/api/v1/channels/whatsapp/configure \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"fields":{"display_name":"Agentcy Assistant"}}'

Configure auto-activates. The gateway is auto-extracted and started on the host.

Pair with QR

bash
# 1. Start a pairing session
curl -X POST http://…/channels/whatsapp/qr/start \
  -H "authorization: Bearer $TOKEN"
json
{
  "session_id": "qr_01HABC…",
  "qr_data_url": "data:image/png;base64,iVBORw0K…",
  "expires_in": 60
}

Render the qr_data_url as an image. Scan with WhatsApp on your phone: Settings → Linked devices → Link a device.

bash
# 2. Poll for completion
curl "http://…/channels/whatsapp/qr/status?session_id=qr_01HABC…" \
  -H "authorization: Bearer $TOKEN"

Responses: { "status":"pending" }{ "status":"connected", "phone":"+1…" } or {"status":"expired"}.

Bindings — route messages to agents

The channel is now connected, but no agent is listening yet. Create a binding:

bash
curl -X POST http://…/bindings \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{
    "agent":"incident-responder",
    "match_rule":{
      "channel":"whatsapp",
      "group":"+972500000001"
    }
  }'

match_rule fields (all optional; evaluated as AND):

  • channel: "whatsapp"
  • group: a group id or participant phone
  • from: a specific sender
  • to: a specific number when you have multiple connected numbers
  • text_regex: match against message text

Rules are evaluated top-to-bottom; first match wins. Unmatched messages are logged and ignored.

List bindings:

bash
curl "http://…/bindings?channel=whatsapp" -H "authorization: Bearer $TOKEN" | jq

Send a message from an agent

Agents reply automatically when a message arrives via a binding. To send proactively:

bash
curl -X POST http://…/channels/whatsapp/send \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"to":"+972500000002","text":"deploy complete — prod is green"}'

Supports text, media, and reaction payloads. See the schema at GET /channels/whatsapp/schema.

Test credentials

bash
curl -X POST http://…/channels/whatsapp/test -H "authorization: Bearer $TOKEN"

Returns {"status":"ok","phone":"+1…"} or a clear error if the gateway can't reach Meta.

Reload

After editing config or bindings, reload the channel:

bash
curl -X POST http://…/channels/reload -H "authorization: Bearer $TOKEN"

The gateway gracefully disconnects, reloads config, re-connects. Session state is preserved — no re-pairing.

Unpair

bash
curl -X DELETE http://…/channels/whatsapp/configure -H "authorization: Bearer $TOKEN"

Or from your phone: Linked devices → remove the Agentcy session.

Gateway internals

  • Binary: @whiskeysockets/baileys wrapped in a small Node script.
  • Location: ~/.openfang/whatsapp-gateway/ (extracted on first use).
  • Branding: the gateway's browser: string is patched from OpenFangAgentcy at startup so the device shows up nicely in the "Linked devices" screen.
  • Persistence: auth state files in ~/.openfang/whatsapp-gateway/auth/<org_id>/.

Policies

Because WhatsApp messages can trigger tool calls, policies apply. A common pattern:

rego
deny[msg] {
  input.subject.channel == "whatsapp"
  input.action == "chat.tool.execute"
  input.resource.tool_effect != "read"
  not input.context.approval_granted
  msg := "write tools require approval when triggered from whatsapp"
}

The channel binding automatically populates subject.channel = "whatsapp" for evaluation.

Gotchas

  • WhatsApp rate-limits aggressively. Bulk sends are a great way to get your account flagged. For broadcasts, use the official Business API.
  • One session per account. If the account is already paired to the gateway from a stale session, unpair first or the QR will repeatedly expire.
  • Group messages include mentions you need to handle. The binding matches on group id; your template should inspect whether the agent was mentioned before replying.
  • Media is downloaded to the artifact store. On large volumes, point AGENTCY_ARTIFACT_BACKEND=s3.

Next

Built by AgentcyLabs. For in-house deployment or Agentcy Cloud (PaaS) access, visit agentcylabs.com.