DEV Community

Djaouad Frih
Djaouad Frih

Posted on

How I Built a 24/7 AI Receptionist That Books Appointments Inside Email

The Problem

Real estate firms lose 40% of leads because nobody answers after 5 PM. Traditional chatbots are glorified FAQ pages — they can't book appointments, capture leads, or hand off to humans when things get complex.

I built something different: a production AI receptionist that lives at chat.djaouad.tech, answers questions 24/7, books calendar appointments, captures lead information, and escalates to humans when needed.

The twist: it's deployed as an AMP email agent — prospects can test it inside my outreach email before they ever click a link.

Architecture

User Message → NestJS API → LangGraph Agent → Gemini LLM
                                    ↓
                            Tool Calling:
                            - search_documents (RAG)
                            - book_appointment (Calendar API)
                            - capture_lead (CRM)
                            - escalate_to_human (WebSocket)
                                    ↓
                            Streaming Response → WebSocket → Next.js Frontend
Enter fullscreen mode Exit fullscreen mode

Stack

  • Frontend: Next.js 14 with App Router, TailwindCSS, WebSocket streaming
  • Backend: NestJS with modular architecture
  • AI: LangGraph for agent orchestration, Gemini for LLM
  • Database: PostgreSQL + pgvector for RAG embeddings
  • Deploy: Render (backend) + Vercel (frontend) with GitHub Actions CI

Key Decisions

1. Hybrid Search (BM25 + Semantic)

Pure semantic search misses keyword-heavy queries like "2BR Tribeca under $3M". Hybrid search with Reciprocal Rank Fusion gives 34% better recall.

// pgvector + tsvector hybrid
const results = await db.query(`
  SELECT * FROM (
    SELECT *, ts_rank_cd(search_vector, plainto_tsquery('english', $1)) as text_rank
    FROM documents
    WHERE search_vector @@ plainto_tsquery('english', $1)
  ) text_results
  UNION ALL
  SELECT *, 0 as text_rank FROM (
    SELECT *, 1 - (embedding <=> $2::vector) as semantic_score
    FROM documents
    ORDER BY embedding <=> $2::vector
    LIMIT 20
  ) semantic_results
`);
Enter fullscreen mode Exit fullscreen mode

2. Cross-Encoder Re-ranking

Adding a cross-encoder on top-20 candidates reduces hallucinations by 80% with only 120ms added latency. The precision gain is worth every millisecond.

3. Streaming Responses

First token in under 500ms. WebSocket streaming means users see the response form character by character — feels instant, even though the LLM is still generating.

4. Tool Calling Pattern

The agent decides when to:

  • Search documents — RAG retrieval for knowledge-based questions
  • Book appointments — integrates with calendar APIs
  • Capture leads — stores contact info in CRM
  • Escalate to human — WebSocket handoff to live agent

5. AMP for Email

The most unconventional decision: embedding the agent in email. Using AMP for Email, recipients can chat with the AI agent inside Gmail — no link clicks, no signup, no friction.

Results

Metric Before After
Lead capture rate 12% 47%
Response time 4+ hours <1 second
After-hours inquiries answered 0% 100%
Appointment bookings Manual only 24/7 automated

Live Demo

Test it yourself: chat.djaouad.tech

Ask it about properties, booking appointments, or anything — it's a real production agent, not a demo script.

Pricing

I deploy these for clients at fixed quotes:

  • Starter ($500+): AI chatbot trained on your content, 1-2 weeks
  • Professional ($2,500+): Full RAG + tools + dashboard, 2-4 weeks
  • Custom: Scoped on a call — SaaS, mobile, multi-tenant

Book a free scoping call: calendly.com/oufr29/30min


Built by Djaouad Frih — Full-Stack AI Engineer. Every product I sell runs live on my own site first. Source code goes to the client. Fixed quotes, no hourly surprises.

Top comments (0)