# Gemini Deep Think Result

**Model**: gemini-2.5-flash
**Elapsed**: 40.86s

## Response

This is an ambitious, critical, and entirely achievable mission. The constraints (no new subscriptions, existing tech stack) force creative solutions, which is precisely where the power of orchestration tools like n8n combined with advanced LLMs and specialized APIs shines.

Let's engineer Sunaiva's 100% autonomous revenue engine.

---

## The Autonomous Revenue Pipeline: Optimal Architecture

The core principle is **modularity and event-driven processing** using n8n as the central orchestrator, PostgreSQL for persistent state, Redis for transient state/queues, and Telnyx/Gemini/Instantly/Stripe/Cal.com as specialized service providers.

We'll use a **modular n8n workflow architecture**. A single mega-workflow is a maintenance and debugging nightmare. Instead, specific stages of the pipeline will be distinct n8n workflows, triggered by webhooks or internal messages (e.g., Redis queues, internal HTTP calls between n8n workflows).

### 1. The Complete n8n Workflow Structure (Node-by-Node)

Each major stage will be a dedicated n8n workflow.

---

#### **Workflow 1: `Instantly_Reply_Processor` (Triggered by Instantly.ai Webhook)**

**Purpose:** Ingests Instantly.ai email replies, classifies intent, enriches lead data, and dispatches to subsequent stages.

```
┌─────────────────────────────────┐
│ START: Webhook (Instantly.ai)   │ Trigger on `email.replied`, `email.unsubscribed`
│  (URL: api.sunaivadigital.com/n8n/webhook/instantly_reply)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Insert Raw Event │ Store full webhook payload for audit/debugging
│    (Table: `raw_events`, `event_type`, `payload`, `timestamp`)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. Set Node: Extract Key Data   │ email, reply_body, campaign_id, timestamp, etc.
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. LLM Node (Gemini-Ultra):     │ Intent Classification, Entity Extraction
│    (Prompt outlined in 3.1)     │ Output: JSON (intent, urgency, entities, sentiment, next_action)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 4. PostgreSQL: Update Lead      │ Upsert lead into `leads` table with classified data
│    (Table: `leads`, `email`, `last_reply_body`, `intent`, `status`, ...)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 5. Switch Node: Route by Intent │ Routes based on LLM's `next_action`
│                                 │ (e.g., `call_now`, `send_resources`, `unsubscribe`, `archive`)
└────────┬────────────────────────┘
         ├─────────────────────────────────────────────────► **Case: `call_now`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5a. Set Node: Prepare Data  │ Email, name, company from LLM entities
         │                                                    └────────┬────────────────────┘
         │                                                             │
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5b. HTTP Request (Clay/Hunter) │ Enrich phone. See 1.3
         │                                                    │    (Waterfall or Parallel)    │ (Retry with exponential backoff)
         │                                                    └────────┬────────────────────┘
         │                                                             │
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5c. PostgreSQL: Update Lead │ Add `phone_number`, `phone_enrich_status`
         │                                                    └────────┬────────────────────┘
         │                                                             │ (if phone found)
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5d. Redis: Add to Queue     │ `call_queue` (priority, lead_id)
         │                                                    │                             │ (Trigger `Voice_Call_Processor` workflow)
         │                                                    └─────────────────────────────┘
         │
         ├─────────────────────────────────────────────────► **Case: `send_resources`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5e. HTTP Request (n8n internal) │ Trigger `RAG_Email_Responder` workflow
         │                                                    │  (Payload: lead_id, question) │ (URL: api.sunaivadigital.com/n8n/webhook/rag_email_responder)
         │                                                    └─────────────────────────────┘
         │
         ├─────────────────────────────────────────────────► **Case: `unsubscribe`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5f. HTTP Request (Instantly) │ Add email to suppression list
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5g. PostgreSQL: Update Lead │ status='unsubscribed'
         │                                                    └─────────────────────────────┘
         │
         ├─────────────────────────────────────────────────► **Case: `archive`/`spam`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 5h. PostgreSQL: Update Lead │ status='archived' or 'spam'
         │                                                    └─────────────────────────────┘
         │
         └─────────────────────────────────────────────────► **Error Branch**
                                                              ┌─────────────────────────────┐
                                                              │ Error Trigger Node          │ If LLM classification fails, or other error
                                                              └────────┬────────────────────┘
                                                                       ▼
                                                              ┌─────────────────────────────┐
                                                              │ Redis: Add to `dlq_instantly`│ Dead Letter Queue for human review
                                                              └─────────────────────────────┘
```

---

#### **Workflow 2: `Voice_Call_Processor` (Triggered by Redis Queue / Internal Webhook)**

**Purpose:** Initiates Telnyx voice calls for qualified leads, manages call state, and dispatches to demo booking.

```
┌─────────────────────────────────┐
│ START: Webhook (from Redis/n8n) │ Receives `lead_id` from `call_queue`
│  (URL: api.sunaivadigital.com/n8n/webhook/voice_call_processor)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Get Lead Data    │ Fetch `lead_id`, `phone_number`, `first_name`, `company_name`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. Set Node: Prepare Telnyx Call│ Set `to_number`, `from_number` (+61 7 3130 4377 for AIVA)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. HTTP Request (Telnyx API)    │ Initiate call to Telnyx AIVA agent (details in 2.1)
│                                 │ Store `call_id` in Redis (key: `telnyx:call:{{call_id}}`, value: `lead_id`)
│                                 │ (Retry with exponential backoff if Telnyx fails)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 4. PostgreSQL: Update Call Log  │ Record `call_id`, `lead_id`, `status='initiated'`, `start_time`
└─────────────────────────────────┘

// Telnyx will then make HTTP requests *back* to n8n for function calls (e.g., book_demo_call)
// These are handled by separate workflows (e.g., `CalCom_Booking_Processor`)
```

---

#### **Workflow 3: `CalCom_Booking_Processor` (Triggered by Telnyx Function Call Webhook)**

**Purpose:** Handles `book_demo_call` function from Telnyx, interacts with Cal.com, and dispatches to demo video generation.

```
┌─────────────────────────────────┐
│ START: Webhook (Telnyx Function)│ Triggered by `book_demo_call` or `reschedule_demo_call`
│  (URL: api.sunaivadigital.com/n8n/webhook/telnyx_calcom_booking)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. Set Node: Extract Function Args│ `email`, `preferred_date`, `preferred_time`, `timezone`, `call_id`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. Redis: Get `lead_id`         │ From `telnyx:call:{{call_id}}`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. PostgreSQL: Get Lead Data    │ `first_name`, `company_name`, `pain_points`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 4. Code Node: Parse Date/Time   │ Convert to ISO 8601 for Cal.com
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 5. HTTP Request (Cal.com API)   │ Check availability (before booking)
│    (Function Call: get_avail_slots)
└────────┬────────────────────────┘
         │
┌────────┴────────────────────────┐
│ 6. IF Node: Slot Available?     │ Yes → Book; No → Respond to Telnyx with alternatives
└────────┬────────────────────────┘
         ├─ Yes ───────────────────► ┌─────────────────────────────────┐
         │                           │ 7a. HTTP Request (Cal.com API)  │ Book the demo (see 2.3)
         │                           │                                 │ (Retry with exponential backoff)
         │                           └────────┬────────────────────────┘
         │                                    │
         │                                    ▼
         │                           ┌─────────────────────────────────┐
         │                           │ 7b. PostgreSQL: Update Booking  │ Store `booking_id`, `status='booked'`
         │                           └────────┬────────────────────────┘
         │                                    │
         │                                    ▼
         │                           ┌─────────────────────────────────┐
         │                           │ Redis: Add to `demo_gen_queue`  │ `lead_id`, `booking_id`, `preferred_time`
         │                           │                                 │ (Trigger `Demo_Video_Generator` workflow)
         │                           └─────────────────────────────────┘
         │
         └─ No ────────────────────► ┌─────────────────────────────────┐
                                     │ 7c. HTTP Request (Telnyx API)   │ Send alternative slots back to agent
                                     │    (Update call state, continue conversation)
                                     └─────────────────────────────────┘

// If Reschedule: First Cal.com DELETE then Cal.com POST
```

---

#### **Workflow 4: `Demo_Video_Generator` (Triggered by Redis Queue / Internal Webhook)**

**Purpose:** Generates a personalized demo video using Gemini and sends it to the lead.

```
┌─────────────────────────────────┐
│ START: Webhook (from Redis/n8n) │ Receives `lead_id`, `booking_id`, `preferred_time`
│  (URL: api.sunaivadigital.com/n8n/webhook/demo_video_generator)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Get Lead/Booking │ Fetch `first_name`, `company_name`, `pain_points`, `product_interest`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. LLM Node (Gemini-Ultra):     │ Generate Video Script (2-3 min, personalized)
│    (Prompt outlined in 3.1)     │
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. Code Node: Video Generation  │ (FALLBACK OPTION, see 3.2 if Veo 2 isn't ready)
│    - Call Gemini Vision (Imagen 3) for custom imagery
│    - Call Telnyx TTS (NaturalHD) for voiceover
│    - Use FFmpeg (via Elestio CLI/script) or Playwright for screen recording
│    - Assemble into MP4
│    (This is the most complex step, requires custom script on Elestio VPS)
│    (Store video URL on Elestio MinIO S3-compatible storage or similar)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 4. PostgreSQL: Update Booking   │ Store `demo_video_url`, `status='video_generated'`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 5. Set Node: Prepare Email      │ Recipient, Subject (Personalized), Body (Video Link, CTA)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 6. HTTP Request (Resend API)    │ Send personalized demo video email
│    (Retry with exponential backoff)
└─────────────────────────────────┘
```

---

#### **Workflow 5: `RAG_Email_Responder` (Triggered by Internal Webhook)**

**Purpose:** Answers lead questions using Qdrant (RAG) and Gemini, sends email replies.

```
┌─────────────────────────────────┐
│ START: Webhook (from `Instantly_Reply_Processor`)
│  (URL: api.sunaivadigital.com/n8n/webhook/rag_email_responder)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Get Lead Data    │ Fetch `email`, `last_reply_body` (the question)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. LLM Node (Gemini): Embedding │ `text-embedding-004` for `last_reply_body`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. HTTP Request (Qdrant API)    │ Semantic search in `knowledge_base` collection (top 3)
│    (Retry with exponential backoff)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 4. LLM Node (Gemini-Ultra):     │ Generate Reply (Prompt in 4.1)
│    (Input: `last_reply_body`, `retrieved_docs`)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 5. Set Node: Prepare Email      │ Recipient, Subject, Body (from LLM)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 6. HTTP Request (Resend API)    │ Send email
│    (Retry with exponential backoff)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 7. PostgreSQL: Update Lead      │ `status='email_replied'`, `last_auto_reply`
└─────────────────────────────────┘
```

---

#### **Workflow 6: `Stripe_Webhook_Processor` (Triggered by Stripe Webhook)**

**Purpose:** Handles all critical Stripe events for license provisioning, renewals, dunning, and cancellations.

```
┌─────────────────────────────────┐
│ START: Webhook (Stripe)         │ Listen to all critical events (see 5.1)
│  (URL: api.sunaivadigital.com/n8n/webhook/stripe)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Insert Raw Event │ Store full webhook payload
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. Set Node: Extract Event Type │ `event.type` (e.g., `checkout.session.completed`, `invoice.payment_failed`)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 3. Switch Node: Route by Event  │
└────────┬────────────────────────┘
         ├─────────────────────────────────────────────────► **Case: `checkout.session.completed`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3a. PostgreSQL: Upsert User │ If new, create. If existing, update.
         │                                                    │   (Table: `customers`, `email`, `stripe_customer_id`, `product`, `tier`)
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3b. Code Node: Provision    │ Generate API Key, Provision AI Memory/Widget
         │                                                    │    (Call FastAPI: `POST /provision_license`)
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3c. Email Node (Resend)     │ "Welcome! Here's your API key..."
         │                                                    └─────────────────────────────┘
         │
         ├─────────────────────────────────────────────────► **Case: `invoice.payment_failed`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3d. PostgreSQL: Update Status│ `status='past_due'`
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3e. Email Node (Resend)     │ "Payment Failed! Update your card." (Link to Stripe hosted page)
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ Redis: Add to `dunning_queue`│ `customer_id`, `retry_count=1`, `next_retry_time`
         │                                                    │                             │ (Trigger `Dunning_Processor` workflow)
         │                                                    └─────────────────────────────┘
         │
         ├─────────────────────────────────────────────────► **Case: `customer.subscription.deleted`**
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3f. PostgreSQL: Update Status│ `status='canceled'`, `canceled_at=NOW()`
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3g. Code Node: Revoke Access│ Call FastAPI: `DELETE /revoke_license`
         │                                                    └────────┬────────────────────┘
         │                                                             ▼
         │                                                    ┌─────────────────────────────┐
         │                                                    │ 3h. Email Node (Resend)     │ "Sorry to see you go! Here's an exit survey."
         │                                                    └─────────────────────────────┘
         │
         └─────────────────────────────────────────────────► **Error Branch**
                                                              ┌─────────────────────────────┐
                                                              │ Error Trigger Node          │
                                                              └────────┬────────────────────┘
                                                                       ▼
                                                              ┌─────────────────────────────┐
                                                              │ Redis: Add to `dlq_stripe`  │ Dead Letter Queue for critical review
                                                              └─────────────────────────────┘
```

---

#### **Workflow 7: `Dunning_Processor` (Triggered by Redis Queue)**

**Purpose:** Manages payment retries and communication for failed payments, including voice calls.

```
┌─────────────────────────────────┐
│ START: Webhook (from Redis/n8n) │ Receives `customer_id`, `retry_count`
│  (URL: api.sunaivadigital.com/n8n/webhook/dunning_processor)
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 1. PostgreSQL: Get Customer     │ Fetch `email`, `phone_number`, `stripe_customer_id`, `retry_count`
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│ 2. IF Node: Max Retries?        │ If `retry_count` > 3, then suspend. Else continue.
└────────┬────────────────────────┘
         ├─ No ───────────────────► ┌─────────────────────────────────┐
         │                           │ 3a. HTTP Request (Stripe API)   │ `POST /invoices/{invoice_id}/pay`
         │                           │    (Retry with exponential backoff)
         │                           └────────┬────────────────────────┘
         │                                    │
         │                                    ▼
         │                           ┌─────────────────────────────────┐
         │                           │ IF Node: Payment Succeeded?     │ Yes → Update status, Email; No → Next Dunning Step
         │                           └────────┬────────────────────────┘
         │                                    ├─ Yes ───────────────────► ┌─────────────────────────────────┐
         │                                    │                           │ 4a. PostgreSQL: Update Status   │ `status='active'`
         │                                    │                           └────────┬────────────────────────┘
         │                                    │                                    ▼
         │                                    │                           ┌─────────────────────────────────┐
         │                                    │                           │ 4b. Email Node (Resend)         │ "Payment Successful!"
         │                                    │                           └─────────────────────────────────┘
         │                                    │
         │                                    └─ No ────────────────────► ┌─────────────────────────────────┐
         │                                                              │ 4c. Set Node: Increment Retry   │ `retry_count + 1`
         │                                                              └────────┬────────────────────────┘
         │                                                                       ▼
         │                                                              ┌─────────────────────────────────┐
         │                                                              │ IF Node: Send Voice Call?       │ If `phone_number` exists and `retry_count` = 2
         │                                                              └────────┬────────────────────────┘
         │                                                                       ├─ Yes ───────────────────► ┌─────────────────────────────────┐
         │                                                                       │                           │ Redis: Add to `call_queue`      │ (high priority) for dunning call
         │                                                                       └─────────────────────────┘
         │                                                                       ▼
         │                                                              ┌─────────────────────────────────┐
         │                                                              │ Redis: Add to `dunning_queue`   │ Reschedule next retry (e.g., 3 days)
         │                                                              └─────────────────────────────────┘
         │
         └─ Yes ───────────────────► ┌─────────────────────────────────┐
                                     │ 3f. PostgreSQL: Update Status   │ `status='suspended'`
                                     └────────┬────────────────────────┘
                                              ▼
                                     ┌─────────────────────────────────┐
                                     │ 3g. Code Node: Revoke Access    │ Call FastAPI: `DELETE /revoke_license`
                                     └────────┬────────────────────────┘
                                              ▼
                                     ┌─────────────────────────────────┐
                                     │ 3h. Email Node (Resend)         │ "Access Suspended."
                                     └─────────────────────────────────┘
```

---

### 2. Exact API Call Sequences & JSON Payloads

#### **2.1. Instantly.ai Reply Webhook → n8n**

-   **Endpoint:** Configured in Instantly.ai webhook settings.

