Skip to main content

WhatsApp Agent

Audience: Sales · Management · QA · Support · Engineering · Where in app: Settings → AI Agents → WhatsApp Agent (per-agent tabs: Agent, Rules, Connect Number) · Plan availability: Per-company admin gate whatsapp_agents_allowed (a count) — see Plan & limits

The WhatsApp Agent lets you connect a WhatsApp number and have an AI answer your customers' WhatsApp messages automatically — the same brain as your web Chat Agent, but on WhatsApp. A company can run multiple WhatsApp agents, each with its own name, system prompt, reply rules, and connected WhatsApp number. Each agent is a slot in company.whatsapp_agents, identified by an agent_key, and flips to active once a number is connected.

What it does

  • Answers inbound WhatsApp messages with an AI agent that mirrors the web chat brain (knowledge base, product catalog, order lookup, and the company's single connected calendar are wired server-side — see How it works).
  • Supports many agents per company, each with its own prompt, rules, and bound WhatsApp number.
  • Runs a rules engine so you control when and how it replies (let AI respond, stay silent, send a fixed reply, or hand off to a human) based on message content, timing, contact history, and AI signals (intent, sentiment, confidence, KB hit, spam).
  • Connects a number through Dualhook using a manual two-step onboarding (webhook details + Meta Cloud API credentials).
  • Enriches the connected number's identity (business display name + profile picture) from the Meta business profile, shown on the Connect tab and the agent card.

How it works

The flow spans the frontend config, the backend agent CRUD, and the message runtime in ms-communication.

  1. Create an agent. From the agent list (AgentList.vue) you create an agent with just a name; everything else is editable afterwards. This POST /whatsapp-agents adds a slot to company.whatsapp_agents with a generated agent_key.
  2. Configure behavior (Agent tab → Behavior.vue): set the agent name and an optional system prompt. There is no per-agent tool picker — the knowledge base and product catalog auto-enable on integration, order lookup is always offered, and the active calendar is derived server-side. Saving advances to the Rules tab.
  3. Set rules (Rules tab → Rules.vue): build ordered rules that run top-to-bottom; the first match wins, and if none match the AI answers normally. Stored under the agent's meta.rules.
  4. Connect a number (Connect tab → Connect.vue), a manual two-step onboarding via Dualhook:
    • Step 1 — webhook details: POST /whatsapp-agents/:agent_key/webhook-setup mints (idempotently) a Webhook URL + Verify Token to paste into Dualhook's "Webhook Override" form for the number.
    • Step 2 — Meta credentials: POST /whatsapp-agents/:agent_key/credentials saves the Phone Number ID + Access Token (and optional WhatsApp Business Account ID) so the agent can send. This activates the agent (status: active).
  5. Runtime. Inbound messages arrive on the Meta webhook → ms-communication's WhatsAppRuleEngine evaluates the agent's rules, then either lets the AI respond, stays silent, sends a canned reply, or hands off. The backend WhatsappAgentController sanitizes rule JSON against the same signal/operator/action whitelist the runtime understands, so malformed rules can never persist. (verify the exact ms-communication inbound webhook handler + send path.)

Status values

The agent (and its connected number) report a status, surfaced as a coloured badge:

StatusMeaning
draftCreated, no number connected yet.
connectingOnboarding in progress.
activeNumber connected and answering.
disconnectedNumber connection lost/removed.

Configuration & options

Agent tab (Behavior.vue)

FieldStored asNotes
Agent namenameRequired.
System instructionssystem_promptOptional. Tells the agent who it is and how to behave. Blank → falls back to the default sales-assistant prompt.

Rules tab (Rules.vue → agent meta.rules)

Ordered list; first match wins; no match → AI answers normally. Each rule has a name, an enabled toggle, a match mode (all/any), one or more conditions, and an action. Quick-start templates are provided (outside-hours auto-reply, pricing → send link, unhappy → human, spam → ignore, opt-out → stop replying).

Condition signals & operators (must mirror ms-communication's WhatsAppRuleEngine and the backend sanitizer):

SignalOperatorsValue
Message textcontains, not_contains, equals, starts_with, matches_regextext
Working hoursis_within, is_outside
Day of weekis, is_not, in, not_inweekday(s)
Contactis_new, is_returning
Message counteq (=), gt (>), lt (<)number
Intent (AI)in, not_infrom intent set + custom intents
Sentiment (AI)is, is_notpositive / neutral / negative
Confidence (AI)gte (≥), lte (≤)0.0–1.0
Knowledge base hit (AI)is_true, is_false
Spam / abuse (AI)is_true, is_false

Base intents: greeting, pricing, product_inquiry, support, booking, order_status, complaint, human_request, goodbye, other (plus any meta.custom_intents). AI signals add "a quick classification step per message" (flagged in the UI).

Actions:

Actionaction.typeNotes
Let AI respondrespondDefault.
Stay silent (record only)silentNo reply sent.
Send a fixed replycannedRequires a message body.
Hand off to a humanhandoffOptional message before handing off; blank stays silent.

On save, conditions missing a signal/operator are filtered out, and only canned/handoff keep a message.

Connect tab (Connect.vue)

FieldSent asNotes
Phone Number IDphone_number_idRequired. From the Dualhook dashboard.
Access Tokenmeta_access_tokenRequired. Meta Cloud API access token (password field; cleared after submit).
WhatsApp Business Account IDwaba_idOptional.

The connected card shows the Meta verified name, display number, and profile picture (from agent.connection, enriched server-side via WhatsAppProfileHelper). "Update credentials" re-opens the credential form.

For QA/Support: the Agent and Rules tabs track unsaved edits and prompt before navigation; Connect uses its own mutations (no dirty-prompt). Toasts confirm each save ("Agent settings updated", "Rules saved", "WhatsApp number connected").

Behaviors & edge cases

  • Multi-agent, shared cap. The list query returns { agents, count, allowed }. count/allowed are company-wide (members only receive their own agents but still see the shared cap). The "Create agent" tile disappears when the cap is reached or the package allows zero.
  • Member scoping. Members can manage only the agents they created (created_by); owners/agency/admins manage all. Legacy agents without created_by are owner-only.
  • First-match rule ordering. Rules evaluate top-to-bottom; the order in the list is significant.
  • Webhook setup is idempotent. Generating webhook details reuses the existing channel/token, so re-running step 1 is safe.
  • Delete is destructive. Deleting an agent removes its config and disconnects its number; it cannot be undone.
  • Provider note. Connection is via Dualhook onto Meta's WhatsApp Cloud API (manual "developer plan" onboarding — no automated Platform API embedded signup in this path, though a /connect route for embedded signup exists). (verify which onboarding path is live in production.)

Plan & limits

  • Gating flag: the WhatsApp card and create flow are gated on company.whatsapp_agents_allowed (a count, admin-controlled per company). Agents.vue shows the card when (whatsapp_agents_allowed ?? 0) > 0. When the count is 0, the list shows "Your package doesn't include WhatsApp agents"; when the count is used up, "Your company has used all N WhatsApp agent(s)".
  • Cap is shared across all users in the company.
  • AI credits: AI replies and per-message AI classification (intent/sentiment/confidence/KB/spam used by rules) consume AI credits — see AI Credits. (verify per-message classification credit accounting.)
  • Sales/Management framing: WhatsApp Agent extends the always-on AI brain to WhatsApp with fine-grained control over when it speaks vs. defers to a human.

Technical implementation

  • Frontend: frontend/src/views/settings/ai/agents/WhatsAppAgent/index.vue (per-agent tabs), AgentList.vue (list/create/delete + cap), Behavior.vue (name/prompt), Rules.vue (rules engine UI + templates), Connect.vue (Dualhook onboarding). Card: WhatsAppAgentCard.vue. Repository: frontend/src/repositories/admin/whatsapp-agents.js. Composable: frontend/src/composables/useWhatsappAgent.js.
  • Backend: backend/app/controllers/WhatsappAgentController.js (CRUD + connect/webhook-setup/credentials, rule-JSON sanitizer), backend/app/routes/whatsappAgentRoutes.js, backend/app/helpers/WhatsAppProfileHelper.js (Meta profile enrichment). Config persists in company.whatsapp_agents[] (each agent: agent_key, name, system_prompt, meta.rules, connection, status, created_by).
  • Runtime: message handling and rule evaluation live in ms-communication (WhatsAppRuleEngine) — see ms-communication. AI generation/classification is served by ms-ai. Nox surfaces config/state but does not connect numbers — see Nox assistant.