BestDealOn

Handbook

Architecture

Two services on Render, linked by an HMAC-signed API (shared secret CALLBOT_SHARED_SECRET, header X-BDO-Signature: t=…,v1=…, 300 s clock skew).

  • bestdealon.app (bestdealon-v2, PHP 8.3 + SQLite on a Render disk): website, accounts, listings, admin, verify-by-call, claims, caller-profile lookup, Sync API for the extension.
  • callbots-bdo (rfsafe-phone-agent, branch bestdealon, Node.js): the phone bot on (727) 632-0002 — Twilio voice, xAI Grok Voice realtime, tools, newsletter, owner API. Runs a single tenant, bestdealon.
Diagram 1 (source below)
Diagram source (Mermaid)
flowchart LR
  subgraph Owners & visitors
    B[Browser]
    X[Best Deal On Bot<br/>Chrome extension 2.3.0]
    P[Caller's phone]
  end
  subgraph Render
    W[bestdealon.app<br/>PHP 8.3 + SQLite]
    C[callbots-bdo<br/>Node.js]
  end
  T[Twilio<br/>voice / Verify / SMS]
  V[xAI Grok Voice<br/>realtime]
  R[Resend<br/>email]
  G[GitHub<br/>source]
  B -- pages, account, admin --> W
  X -- Sync API v1 bearer token --> W
  X -- /api/owner/v1 (token checked via /api/v1/me) --> C
  W -- /account/phone-bot proxy --> C
  P -- call (727) 632-0002 --> T --> C
  C <-- audio + tool calls --> V
  C -- signed /api/callbot/* --> W
  W -- Verify-by-call code call --> C
  W -- confirm / sign-in / reset mail --> R
  C -- links, summaries, newsletter mail --> R
  G -. deploy on approval .-> W
  G -. deploy on approval .-> C

Call flow

Diagram 2 (source below)
Diagram source (Mermaid)
sequenceDiagram
  autonumber
  participant Caller
  participant Twilio
  participant Bot as callbots-bdo
  participant Site as bestdealon.app
  participant Grok as xAI Grok Voice
  Caller->>Twilio: dials (727) 632-0002
  Twilio->>Bot: POST /twilio/voice (signed webhook)
  Bot->>Grok: open realtime session
  par while the session opens (max 1.5 s)
    Bot->>Site: POST /api/callbot/caller-profile with caller number (HMAC signed)
    Site-->>Bot: known, name, on-file flags, email label (never an address)
  end
  Bot->>Bot: newsletter returning-caller match (own records)
  Bot->>Grok: instructions, guardrails and tools, plus greeting Welcome back NAME or the normal disclosure
  loop conversation
    Caller->>Grok: speech
    Grok->>Bot: tool call such as kb_answer, send_link or take_message
    Bot-->>Grok: tool result, addresses resolved server-side and never echoed
  end
  Bot->>Bot: call.ended log masked, summary or message email via Resend

Verify-by-call is the one outbound path: the site asks the bot to ring the listing's own stored number (never user input) and read or collect a 6-digit code.