Chapter 32 / 40

WhatsApp order-acknowledgment bot

Status: Planned — scheduled for later in the engagement after the mail stack and the CRM are live. This is an experimental channel, deliberately secondary to email and phone. A small, controlled surface: one use case, a short allowlist of customers, a human-review queue before anything goes out.


What it does in one line.

When a customer on the allowlist sends an order-shaped message to Sodimo’s WhatsApp Business number, the bot drafts an acknowledgment reply. The reply is not sent until a human approves it.


What it explicitly does not do.

  • No live two-way conversation. The bot does not hold a thread or answer follow-up questions.
  • No voice transcription, no voice-to-order, no Whisper integration. Voice is out of scope for this engagement.
  • No write-path to Sodiwin. The bot never creates an order. An order entered through WhatsApp still lands in a mailbox or on a phone — the bot only acknowledges receipt.
  • No unsolicited outbound. The bot responds; it does not initiate.

The scope is deliberately thin because WhatsApp is a secondary channel at Sodimo and a live conversational agent needs a higher confidence threshold than this engagement can establish.


The wiring

Rani / Paulreview_queueD1 (CRM + run_ledger)sodimo-core Worker(webhook endpoint)Meta Cloud APICustomer (WhatsApp)Rani / Paulreview_queueD1 (CRM + run_ledger)sodimo-core Worker(webhook endpoint)Meta Cloud APICustomer (WhatsApp)alt[approved][rejected / edited]sends messagewebhook POSTverify signature + allowlist checklook up customer, recent ordersLLM drafts ack replywrite run_ledger rowenqueue draft for reviewreview draft (CRM UI)approvesend replydeliver replyreject or edit-and-sendsend edited text (if edited)

The webhook lands on a Cloudflare Worker — the same sodimo-core Worker that hosts the single MCP surface (Chapter 42). The Worker is the one endpoint Meta’s servers talk to. The Fedora harness is not involved in the inbound path; the bot does not touch local services.


Guardrails

Every one of these is a hard requirement before the bot can be turned on, not an aspiration.

Allowlisted customers only. The webhook drops any message whose sender is not on an explicit phone-number allowlist in D1. The allowlist starts empty; Rani adds customers to it one at a time after an explicit opt-in. There is no “open to all customers” switch.

Rate limit. The Worker caps throughput per sender and per hour. A runaway loop on the sending side cannot flood the queue or drive model spend.

Human review queue. No draft leaves the system without a human pressing approve. The draft lands in the CRM (Chapter 53) as a review card; Rani or Paul approves, edits, or discards it. “Auto-approve after N seconds” is not a feature.

Message-shape gate. Before the Worker asks a model to draft anything, a deterministic check confirms the message looks like an order — keywords, numerics, known product references. Off-topic messages are routed to a human-only bucket with no draft generated.

Run-ledger emission. Every invocation — inbound message parsed, draft generated, approved, rejected — is a row in run_ledger (Chapter 15, Principle 2). If a future review ever asks “how often did the bot help? how often did it mislead?”, the answer is a SQL query.

Signature verification. The Worker verifies Meta’s webhook signature on every request. Unsigned or mis-signed requests are rejected silently.


Why this is in the manual at all

WhatsApp is where several Sodimo customers already reach the team — a sales rep’s phone, mostly. Two failure modes exist today: a message is missed entirely, or a message is answered hours later. The bot targets only the second one, and only for the “we received your order” reply, which is the lowest-stakes message in the thread.

If the bot works in this narrow shape over a month or two, a future engineer can widen the scope — more templates, more customers, eventually a tighter loop with the order system. If it does not, the surface is small enough to turn off without anyone noticing.


Decision traceability. D-119 (Tuesday annotation): “drop the voice ecosystem completely. whatsapp gets a bot that is well scoped, that we set up with strong guardrails. use as experimental, this is quite secondary.” D-018 (Monday annotation): repo sequencing — changelog, then brand, then whatsapp-webhook next week, then pillars when unblocked. Chapter 55 has the full annotations.

Cross-references. Chapter 15 (Principle 3 — single MCP surface, run-ledger), Chapter 42 (sodimo-core Worker and the MCP tool inventory), Chapter 53 (the CRM, which hosts the human-review queue).