One agent (Order) that watches the storefront and keeps you and the customer in the loop — the customer gets a WhatsApp message, you get both WhatsApp and email. Built with LangGraph + FastAPI, deployed on Render.
It listens to the storefront's Supabase project through a Database Webhook — nothing here touches the site's code, it only reacts to changes.
Supabase fires a Database Webhook whenever a row in orders is
inserted or updated → hits /webhooks/orders on this service → sends
a WhatsApp message to the customer, and both a WhatsApp + email to
you, with wording that depends on what actually happened (new order,
payment went through, payment failed, status changed).
Message text is written by Gemini (free tier) when GEMINI_API_KEY is
set, and falls back to a plain static template if it isn't set, or if
the API hiccups — either way, a real message always goes out.
Every send goes through log-mode until you add real credentials — the
service never crashes for missing keys, it just logs what it would
have sent. Check /health any time to see what's actually configured.
- Twilio — console.twilio.com → get a WhatsApp-enabled sender
(the sandbox number works for testing,
whatsapp:+14155238886) plus your Account SID and Auth Token. - Resend — resend.com → API key, and verify a sending domain (or use their shared test domain while testing).
- Gemini (optional) — aistudio.google.com → Get API key. Free, no credit card. Powers LLM-written messages; skip it and the static templates are used instead.
- Push this repo to GitHub (a fresh repo, e.g.
capo-agents). - In Render: New → Blueprint → point it at the repo.
render.yamlalready defines the web service. - Fill in the env vars Render asks for (everything marked
sync: falseinrender.yaml— same names as.env.example).
Supabase Dashboard → Database → Webhooks → Create a new webhook:
- Table:
orders - Events: Insert, Update
- Type: HTTP Request
- URL:
https://<your-render-service>.onrender.com/webhooks/orders - HTTP Headers: add
x-webhook-secret= the same value asWEBHOOK_SHARED_SECRETyou set on Render
curl https://<your-service>.onrender.com/health— confirm it showstruefor whichever services you've actually configured.- Place a real test order on the live site with a phone number and email you control. Confirm you get the "order placed" WhatsApp message on the customer's phone, and both a WhatsApp + email on the admin side.
- Pay for that test order (or trigger the Razorpay webhook manually in test mode). Confirm the "payment received" message arrives.
- In Supabase, manually edit that test order's
statuscolumn to something else (e.g.ready). Confirm the status-update message arrives — and that editingupdated_atalone with no real change does not trigger a message.
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # fill in what you have; leave the rest blank for log-mode
uvicorn app.main:app --reload
pip install pytest pytest-asyncio
pytest -q