Westside boutique. Worldwide buyers.
A production-ready WhatsApp Business AI assistant that auto-replies to inbound real-estate leads in under 30 seconds, qualifies them through a natural bilingual (English / Spanish) conversation, scores them with an LA-tuned rubric, and pushes the lead into Google Sheets + Slack.
Built around a fictional but realistic boutique agency β Casa Verde Realty (Santa Monica, CA) β see docs/case_study.md for the full story and projected impact.
Built as a portfolio piece to show how Claude + Twilio + a sane Python backend can replace a $5k/mo SDR for a small services business.
4-frame loop showing the full pipeline: a Spanish-speaking buyer messages WhatsApp β Sofia qualifies β an English-speaking renter messages β the lead lands in Google Sheets and Slack ~5 seconds later.
![]() Spanish qualifier flow |
![]() English qualifier flow |
![]() Lead in Google Sheets |
![]() Slack notification |
- Bilingual β auto-detects Spanish vs English on the first message and mirrors the prospect; switches mid-conversation if they switch
- One question at a time β short WhatsApp-native messages, never an essay
- Natural β uses the prospect's name once given, light emoji, no "I am an AI assistant" formality
- Strict qualification flow enforced via Claude tool use β no aimless small-talk; the LLM only finishes when it has enough info to call
record_lead - Edge-case aware β out-of-budget, casual browsing, hostile/spam, off-topic, existing-client all handled politely in the prompt
- Deterministic LA-tuned scoring in pure Python β
HOT/WARM/COLDbased on budget tier, financing type, timeline urgency - Foreign-national premium β recognizes Casa Verde's high-intent international segment
- Rental vs purchase β separate scoring lanes (a $5k/mo rental in Venice is HOT; a $5k home is COLD)
- Twilio WhatsApp β works out of the box with the free Sandbox; one env-var swap for production
- Google Sheets CRM β appends one row per qualified lead, auto-creates the header row on startup
- Slack incoming webhooks β Block Kit cards, score-based filtering (no ping for cold leads)
- Anthropic Claude with prompt caching on the system prompt β ~10Γ cheaper after the first call within the 5-minute window
- Async FastAPI β webhook acks Twilio in <100 ms, processes in background
- Signed Twilio webhook validation β prevents anyone on the internet from forging messages
- Structured logs (structlog) β JSON β drops into any log aggregator
- Sentry integration β set
SENTRY_DSNand you're done - SQLAlchemy 2.0 async + aiosqlite β conversation memory survives restarts
- Multi-stage Dockerfile β ~120 MB final image, non-root user
- GitHub Actions CI β pytest matrix across Python 3.10 / 3.11 / 3.12 + ruff lint
render.yamlβ push to GitHub, deploy on Render free tier in 60 seconds
WhatsApp ββΊ Twilio ββΊ /webhooks/whatsapp ββΊ (ack 200) ββ
β
background task
β
ββββββββββββββββββΌβββββββββββββββββ
βΌ βΌ βΌ
Claude API Google Sheets Slack
(qualify lead) (CRM row) (alert)
β
βΌ
SQLite (conversation memory)
Full sequence diagram and component-by-component breakdown in docs/architecture.md.
git clone https://github.com/KirillHat/casa-verde-bot.git
cd casa-verde-bot
python -m venv venv && source venv/bin/activate
pip install -r requirements-dev.txtFollow docs/twilio_setup.md β 5 min, no Meta verification needed.
Follow docs/google_sheets_setup.md β 5 min, free.
cp .env.example .env
# Fill in TWILIO_*, ANTHROPIC_API_KEY, GOOGLE_SHEETS_ID, SLACK_WEBHOOK_URLuvicorn app.main:app --reload --port 8000
# in another terminal:
ngrok http 8000
# paste the https://xxx.ngrok.io/webhooks/whatsapp URL into Twilio Sandbox settingsFrom your phone WhatsApp, message the Twilio sandbox number:
"Hi, looking for a 2BR rental in Venice, budget $5k/mo, need it next month"
You should get an AI reply within 5 seconds, see a row appear in Google Sheets, and get a Slack notification.
docker compose upMounts ./data for SQLite persistence and ./google_credentials.json for Sheets auth.
- Push to GitHub
- Render β New β Web Service β connect repo
- Render auto-detects
render.yamland provisions the service - Set env vars in the Render dashboard (everything from
.env.example) - Add
google_credentials.jsonas a Secret File mounted at/etc/secrets/google_credentials.json - Set the Twilio Sandbox webhook to
https://your-app.onrender.com/webhooks/whatsapp
pytest -v
# or with coverage:
pytest --cov=app --cov-report=termThe suite covers:
- Scoring rules β every HOT / WARM / COLD pathway, threshold overrides, foreign-national premium
- Conversation flow β mocked Claude responses, lead persistence, history threading, error isolation (Sheets failure β user-facing failure)
- Webhook β signature validation, ack-fast behaviour, healthcheck
The architecture is generic. To repurpose for a yoga studio, dental clinic, solar installer, online school, etc:
- Edit
app/prompts/qualifier_realestate.mdβ domain context + qualification fields - Edit
app/services/scoring.pyβ your industry's HOT / WARM / COLD rules - Update headers in
app/services/sheets_client.pyto match the new fields
Total adaptation time: ~2 hours. The portability is the actual product β see docs/case_study.md.
docs/case_study.mdβ full Casa Verde story, projected metrics, why this is harddocs/architecture.mdβ sequence diagram, component-by-componentdocs/twilio_setup.mdβ 5-minute sandbox setupdocs/google_sheets_setup.mdβ service account + sheetupwork_description.mdβ copy-paste-ready Upwork portfolio entry
MIT β see LICENSE.
Built by Kirill (@KirillHat). If you want this adapted to your business, hire me on Upwork.






