BestDealOn

Handbook › Callbots

Verify by call (Best Deal On, [bdo]; off by default, on in production)

Code exists on the bestdealon branch (commit 0e959ca; first deployed to callbots-bdo 8:03 PM EST Nov 3, Render dep-dbl88igm7kps739isctg). Full doc: docs/BDO_VERIFY_CALL.md [bdo]. It is for tenant bestdealon only. Main does not have it. Live state (Render, checked 11:40 PM EST): BDO_VERIFY_CALLS is on (live mode); BDO_INBOUND_CLAIM is off (unset), so the inbound claim tools are not offered.

What it does

bestdealon.app asks the phone service to call a business listing's phone number with a verification code. This proves the person claiming the listing controls that phone.

  • POST /bdo/verify-call (src/bdoverify.js:113 [bdo]):
    • The request must be HMAC-signed by the site (BDO_CALLBOT_SHARED_SECRET).
    • to must equal the listing phone. Every tenant's own number is refused.
    • Limits: 3 calls per number per hour, and a 120 s time limit (src/bdoverify.js:40).
    • Modes (src/bdoverify.js:87):
      • read: the bot speaks the code twice, and the person types it on the site.
      • keyin: the person keys in 6 digits on the phone. The bot never receives the code.
  • POST /bdo/verify-gather is Twilio-signed. It forwards the digits to the site's /api/callbot/verify-check (src/bdoverify.js:114).
  • BDO_VERIFY_CALLS:
    • off (default)
    • dryrun: records the request and dials nothing
    • live: places one Twilio call

Inbound claim tools

  • They need BDO_INBOUND_CLAIM=on and tenant bdo_claims: true. Tools: bdo_listing_for_caller and bdo_start_claim (src/bdoverify.js:122+).
  • On a spoken yes, the bot creates only a pending claim. Caller ID is never proof.
Diagram 1 (source below)
Diagram source (Mermaid)
sequenceDiagram
  participant Site as bestdealon.app
  participant CB as callbots-bdo
  participant TW as Twilio
  participant P as Listing phone
  Site->>CB: POST /bdo/verify-call (HMAC signed, to=listing phone, mode)
  CB->>CB: checks: flag, signature, to==listing, not a tenant number, rate limit
  CB->>TW: create call (inline TwiML, 120 s cap)
  TW->>P: rings
  alt read
    TW->>P: speaks code twice, user types it on the site
  else keyin
    P->>TW: 6 DTMF digits
    TW->>CB: POST /bdo/verify-gather (Twilio signed)
    CB->>Site: POST /api/callbot/verify-check
  end

Tests: node --test test/bdo-verify-call.test.js. They use a mock driver and make no network calls.