Inspiration

Shopify teams still lose hours to work whose only reliable interface is a phone number: carrier exceptions, delivery traces, and stalled customer conversations. We wanted voice AI to close that gap without letting a probabilistic conversation directly change a real order.

What it does

CallmeMaybe adds two controlled Shopify phone workflows:

  • A carrier trace where CALL-E navigates the phone tree, speaks with an agent, and returns a schema-validated trace reference, disposition, promised response window, and hold time.
  • A consent-based customer callback where CALL-E verifies identity before sensitive disclosure, captures one decision, reads consequential details back, and records spoken confirmation.

A call produces evidence; it never authorizes an order mutation. A deterministic policy engine evaluates the evidence, a merchant approves any consequential action, and the app re-reads the live Shopify order immediately before writing. If the order changed, execution stops and records why.

How we built it

The embedded app uses React Router 7, React, Shopify App Bridge, customer-account and thank-you extensions, and Shopify Admin GraphQL. PostgreSQL, Prisma, and pg-boss persist cases, jobs, consent, policy snapshots, idempotency receipts, and audit events.

CALL-E is isolated behind a TypeScript provider adapter. It receives bounded task instructions and an issue-specific JSON Schema, places the call, and returns structured evidence. Terminal webhooks are treated as untrusted notifications: the server authenticates and deduplicates them, then fetches the canonical CALL-E result before evaluation. Fixture mode exercises the same downstream contracts without dialing.

Safety and privacy

  • Explicit consent, suppression, quiet-hour, and attempt-limit controls.
  • Deterministic policy decisions and merchant-approved Shopify actions.
  • Fresh-order drift checks immediately before mutation.
  • Tenant scoping, encrypted sensitive values, redacted displays, retention, and privacy jobs.
  • No model decides whether Shopify may be mutated.

Challenges

The hardest part was designing the trust boundary between an adaptive phone conversation and a consequential commerce action. We also had to make webhooks idempotent, keep call evidence tenant-scoped, enforce consent, and ensure that stale order state could never be applied blindly.

Accomplishments

  • Implemented CALL-E carrier and customer workflows behind one provider contract.
  • Added strict structured-result schemas and canonical result re-fetching.
  • Added a deterministic approval and execution path with audit receipts.
  • Added a safe fixture provider for judging without real calls.
  • Kept the recovered repository reproducible with Bun, green hosted CI, CodeQL, container scanning, secret-history scanning, and 80 passing tests.
  • Contributed the project to the official CALL-E community directory in a reviewed and merged pull request.

What we learned

Voice agents are most useful when they close gaps that APIs and email cannot, but their output should remain evidence rather than authority. Separating conversation, policy, approval, and execution makes the system easier to reason about and safer to operate.

Testing

The public repository is the judge-accessible build. A credential-free code-path check places no phone call:

bun install --frozen-lockfile
bunx prisma generate
bun run test

The full embedded flow requires Node 22.12, Bun 1.3.14, PostgreSQL 16+, a Shopify Partner development app, and a development store. Keep CALL_PROVIDER=fixture and CALLE_REAL_CALLS_ENABLED=false for safe evaluation.

The recovered checkout does not contain an installed demo store or an authorized test number, so the public video is an honest technical walkthrough rather than a staged live-call claim.

What's next

A controlled pilot would add a dedicated Shopify development store, authorized test numbers, production credentials, and a small merchant cohort. The separate Shopify App Store release gates are not claimed complete.

Built With

Share this project:

Updates