# Twilio WhatsApp Business API Integration Plan
# Halavoice.store - Twilio Number +1 (629) 291-8169

**Created**: 2026-06-23
**Twilio Number**: +1 (629) 291-8169
**User Account**: ashraffaridhd@gmail.com
**Project**: Halavoice.store
**Public URL**: https://halavoice.store

---

## Executive Summary

This plan outlines the integration of **Twilio WhatsApp Business API** with Halavoice.store using the Twilio number +1 (629) 291-8169. The integration will enable:
- Sending WhatsApp messages programmatically through Halavoice
- Receiving incoming WhatsApp messages via webhooks
- AI-powered auto-responses for customer queries
- Unified inbox for WhatsApp and other channels

---

## Prerequisites & Requirements

### 1. Twilio Account Setup
- [ ] Verify Twilio account access for `ashraffaridhd@gmail.com`
- [ ] Confirm number +1 (629) 291-8169 is eligible for WhatsApp
- [ ] Enable WhatsApp Business API in Twilio Console
- [ ] Obtain WhatsApp Business Profile approval from Meta

### 2. Technical Requirements
- **Public Webhook URL**: `https://halavoice.store/api/twilio-whatsapp/webhook`
- **Twilio Credentials**: Account SID, Auth Token
- **WhatsApp Sender ID**: Must be approved for the number
- **Message Templates**: Pre-approved templates for outbound messages

### 3. Environment Variables
```bash
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_WHATSAPP_NUMBER=whatsapp:+16292918169
TWATSAPP_WEBHOOK_URL=https://halavoice.store/api/twilio-whatsapp/webhook
```

---

## Architecture Overview

```
┌─────────────────────────────────────────────────────────────────┐
│                        HALAVOICE.STORE                          │
│                  https://halavoice.store                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │              Public Webhook Endpoint                        │  │
│  │   /api/twilio-whatsapp/webhook (No Auth - Twilio only)      │  │
│  └──────────────┬────────────────────────────────────────────┘  │
│                 │                                                 │
│                 ▼                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │              Twilio WhatsApp Service Layer                  │  │
│  │   - Message validation                                     │  │
│  │   - Signature verification                                  │  │
│  │   - Message processing                                     │  │
│  │   - AI response generation                                 │  │
│  └──────────────┬────────────────────────────────────────────┘  │
│                 │                                                 │
│                 ▼                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │              Database Layer (PostgreSQL)                   │  │
│  │   - whatsapp_messages (store incoming/outgoing)            │  │
│  │   - whatsapp_sessions (session tracking)                   │  │
│  │   - whatsapp_conversations (conversation history)          │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                   │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │              API Routes (Authenticated)                    │  │
│  │   /api/whatsapp/send - Send messages                      │  │
│  │   /api/whatsapp/conversations - List conversations        │  │
│  │   /api/whatsapp/settings - WhatsApp settings              │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                                    │
                                    │ HTTPS (Message Send)
                                    ▼
┌─────────────────────────────────────────────────────────────────┐
│                        TWILIO API                                │
│                   api.twilio.com                                 │
│  WhatsApp Business API + Number: +1 (629) 291-8169            │
└─────────────────────────────────────────────────────────────────┘
                                    │
                                    │ WhatsApp Messages
                                    ▼
┌─────────────────────────────────────────────────────────────────┐
│                     WHATSAPP (Meta)                              │
│                   whatsapp.net                                   │
└─────────────────────────────────────────────────────────────────┘
```

---

## Implementation Plan

### Phase 1: Database Schema (30 minutes)

Create database tables for WhatsApp integration:

```sql
-- WhatsApp conversations table
CREATE TABLE whatsapp_conversations (
  id VARCHAR(255) PRIMARY KEY,
  user_id VARCHAR(255) NOT NULL REFERENCES users(id),
  phone_number VARCHAR(50) NOT NULL,
  contact_name VARCHAR(255),
  status VARCHAR(50) DEFAULT 'active',
  last_message_at TIMESTAMP,
  unread_count INTEGER DEFAULT 0,
  metadata JSONB,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- WhatsApp messages table
CREATE TABLE whatsapp_messages (
  id VARCHAR(255) PRIMARY KEY,
  conversation_id VARCHAR(255) REFERENCES whatsapp_conversations(id),
  twilio_message_sid VARCHAR(255) UNIQUE,
  direction VARCHAR(20) CHECK (direction IN ('inbound', 'outbound')),
  body TEXT,
  media_url TEXT,
  status VARCHAR(50),
  sent_at TIMESTAMP,
  received_at TIMESTAMP DEFAULT NOW(),
  metadata JSONB,
  created_at TIMESTAMP DEFAULT NOW()
);

-- WhatsApp settings table
CREATE TABLE whatsapp_settings (
  id VARCHAR(255) PRIMARY KEY,
  user_id VARCHAR(255) NOT NULL REFERENCES users(id),
  auto_reply_enabled BOOLEAN DEFAULT false,
  ai_model VARCHAR(100) DEFAULT 'gpt-4o',
  business_profile_id VARCHAR(255),
  template_message_ids TEXT[],
  metadata JSONB,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Indexes
CREATE INDEX idx_whatsapp_conv_user ON whatsapp_conversations(user_id);
CREATE INDEX idx_whatsapp_conv_phone ON whatsapp_conversations(phone_number);
CREATE INDEX idx_whatsapp_msg_conv ON whatsapp_messages(conversation_id);
CREATE INDEX idx_whatsapp_msg_sid ON whatsapp_messages(twilio_message_sid);
```

### Phase 2: Twilio WhatsApp Service (1 hour)

Create service layer for Twilio WhatsApp integration:

**File**: `server/services/twilio-whatsapp-service.ts`

```typescript
import twilio from 'twilio';
import { db } from '../db';
import { whatsappConversations, whatsappMessages } from '@shared/schema';

const TWILIO_ACCOUNT_SID = process.env.TWILIO_ACCOUNT_SID;
const TWILIO_AUTH_TOKEN = process.env.TWILIO_AUTH_TOKEN;
const TWILIO_WHATSAPP_FROM = process.env.TWILIO_WHATSAPP_FROM;

const client = twilio(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN);

export class TwilioWhatsAppService {
  /**
   * Send WhatsApp message via Twilio
   */
  async sendMessage(to: string, body: string, mediaUrl?: string) {
    try {
      const message = await client.messages.create({
        from: TWILIO_WHATSAPP_FROM, // whatsapp:+16292918169
        to: `whatsapp:${to}`,
        body,
        mediaUrl: mediaUrl ? [mediaUrl] : undefined,
      });

      // Store in database
      await this.storeMessage({
        twilioMessageSid: message.sid,
        direction: 'outbound',
        body,
        mediaUrl,
        status: message.status.toString(),
        sentAt: new Date(message.dateCreated),
      });

      return { success: true, messageSid: message.sid };
    } catch (error) {
      console.error('[Twilio WhatsApp] Send error:', error);
      throw error;
    }
  }

  /**
   * Send template message (pre-approved by WhatsApp)
   */
  async sendTemplateMessage(to: string, templateName: string, templateParams?: any[]) {
    try {
      const message = await client.messages.create({
        from: TWILIO_WHATSAPP_FROM,
        to: `whatsapp:${to}`,
        body: templateParams?.join(' ') || '', // Template content
        // Template messaging requires specific setup
      });

      return { success: true, messageSid: message.sid };
    } catch (error) {
      console.error('[Twilio WhatsApp] Template send error:', error);
      throw error;
    }
  }

  /**
   * Get message status from Twilio
   */
  async getMessageStatus(messageSid: string) {
    try {
      const message = await client.messages(messageSid).fetch();
      return {
        sid: message.sid,
        status: message.status,
        direction: message.direction,
        timestamp: message.dateCreated,
      };
    } catch (error) {
      console.error('[Twilio WhatsApp] Status fetch error:', error);
      throw error;
    }
  }

  /**
   * Store incoming message in database
   */
  async storeIncomingMessage(data: {
    from: string;
    body: string;
    mediaUrl?: string;
    messageSid: string;
  }) {
    const { from, body, mediaUrl, messageSid } = data;

    // Find or create conversation
    let [conversation] = await db
      .select()
      .from(whatsappConversations)
      .where(eq(whatsappConversations.phoneNumber, from))
      .limit(1);

    if (!conversation) {
      const conversationId = `wa_conv_${Date.now()}`;
      [conversation] = await db
        .insert(whatsappConversations)
        .values({
          id: conversationId,
          userId: 'system', // Assign to system or auto-assign
          phoneNumber: from,
          status: 'active',
          lastMessageAt: new Date(),
          unreadCount: 1,
        })
        .returning();
    }

    // Store message
    await db.insert(whatsappMessages).values({
      id: `wa_msg_${Date.now()}`,
      conversationId: conversation.id,
      twilioMessageSid: messageSid,
      direction: 'inbound',
      body,
      mediaUrl,
      status: 'received',
      receivedAt: new Date(),
    });

    // Update conversation
    await db
      .update(whatsappConversations)
      .set({
        lastMessageAt: new Date(),
        unreadCount: sql`${whatsappConversations.unreadCount} + 1`,
      })
      .where(eq(whatsappConversations.id, conversation.id));

    return conversation;
  }

  /**
   * Verify Twilio webhook signature
   */
  verifyWebhookSignature(url: string, payload: any, signature: string): boolean {
    return twilio.validateRequest(
      TWILIO_AUTH_TOKEN!,
      signature,
      url,
      payload
    );
  }
}

export const twilioWhatsAppService = new TwilioWhatsAppService();
```

### Phase 3: Webhook Endpoint (45 minutes)

Create public webhook endpoint for Twilio callbacks:

**File**: `server/routes/twilio-whatsapp-routes.ts`

```typescript
import { Router } from 'express';
import { twilioWhatsAppService } from '../services/twilio-whatsapp-service';
import { generateAIResponse } from '../services/ai-response-service';

export function createTwilioWhatsAppRoutes(): Router {
  const router = Router();

  /**
   * POST /api/twilio-whatsapp/webhook
   * Public webhook - receives incoming WhatsApp messages from Twilio
   * NO AUTHENTICATION - Twilio requires public URL
   */
  router.post('/webhook', async (req, res) => {
    try {
      const { From, To, Body, MediaUrl0, MessageSid, SmsStatus } = req.body;

      // Verify Twilio signature
      const signature = req.get('X-Twilio-Signature');
      const isValid = twilioWhatsAppService.verifyWebhookSignature(
        req.protocol + '://' + req.get('host') + req.originalUrl,
        req.body,
        signature
      );

      if (!isValid) {
        console.warn('[Twilio WhatsApp] Invalid webhook signature');
        return res.status(403).send('Invalid signature');
      }

      // Store incoming message
      const phoneNumber = From.replace('whatsapp:', '');
      const conversation = await twilioWhatsAppService.storeIncomingMessage({
        from: phoneNumber,
        body: Body,
        mediaUrl: MediaUrl0,
        messageSid: MessageSid,
      });

      // Generate AI response if auto-reply enabled
      const userSettings = await getUserWhatsAppSettings(conversation.userId);
      if (userSettings.autoReplyEnabled) {
        const aiResponse = await generateAIResponse({
          message: Body,
          conversationId: conversation.id,
          phoneNumber,
          aiModel: userSettings.aiModel,
        });

        // Send AI response via Twilio
        await twilioWhatsAppService.sendMessage(phoneNumber, aiResponse);
      }

      // Respond to Twilio (required)
      res.type('text/xml');
      res.send('<Response></Response>');
    } catch (error) {
      console.error('[Twilio WhatsApp] Webhook error:', error);
      res.status(500).send('Error processing webhook');
    }
  });

  /**
   * POST /api/twilio-whatsapp/status
   * Webhook for message status updates
   */
  router.post('/status', async (req, res) => {
    try {
      const { MessageSid, MessageStatus } = req.body;

      // Update message status in database
      await updateWhatsAppMessageStatus(MessageSid, MessageStatus);

      res.send('<Response></Response>');
    } catch (error) {
      console.error('[Twilio WhatsApp] Status webhook error:', error);
      res.status(500).send('Error');
    }
  });

  return router;
}
```

### Phase 4: API Routes for Users (45 minutes)

Create authenticated API routes for users:

**File**: `server/routes/whatsapp-api-routes.ts`

```typescript
import { Router } from 'express';
import { authenticateToken } from '../middleware/auth';
import { twilioWhatsAppService } from '../services/twilio-whatsapp-service';

export function createWhatsAppApiRoutes(): Router {
  const router = Router();

  /**
   * POST /api/whatsapp/send
   * Send WhatsApp message (authenticated)
   */
  router.post('/send', authenticateToken, async (req, res) => {
    try {
      const { to, body, mediaUrl } = req.body;

      if (!to || !body) {
        return res.status(400).json({ error: 'Missing required fields: to, body' });
      }

      const result = await twilioWhatsAppService.sendMessage(to, body, mediaUrl);

      res.json({
        success: true,
        messageSid: result.messageSid,
      });
    } catch (error: any) {
      console.error('[WhatsApp API] Send error:', error);
      res.status(500).json({ error: error.message });
    }
  });

  /**
   * GET /api/whatsapp/conversations
   * Get all conversations for current user
   */
  router.get('/conversations', authenticateToken, async (req, res) => {
    try {
      const conversations = await getUserConversations(req.userId!);
      res.json(conversations);
    } catch (error) {
      res.status(500).json({ error: 'Failed to fetch conversations' });
    }
  });

  /**
   * GET /api/whatsapp/conversations/:id/messages
   * Get messages for a conversation
   */
  router.get('/conversations/:id/messages', authenticateToken, async (req, res) => {
    try {
      const messages = await getConversationMessages(req.params.id);
      res.json(messages);
    } catch (error) {
      res.status(500).json({ error: 'Failed to fetch messages' });
    }
  });

  return router;
}
```

### Phase 5: Register Routes in Main App (15 minutes)

Add routes to `server/routes.ts`:

```typescript
import { createTwilioWhatsAppRoutes } from './routes/twilio-whatsapp-routes';
import { createWhatsAppApiRoutes } from './routes/whatsapp-api-routes';

// Public webhook for Twilio (NO AUTH)
app.use('/api/twilio-whatsapp', createTwilioWhatsAppRoutes());

// Authenticated WhatsApp API
app.use('/api/whatsapp', authenticateToken as unknown as RequestHandler, createWhatsAppApiRoutes());
```

### Phase 6: Twilio Console Configuration (30 minutes)

**Steps in Twilio Console:**

1. **Navigate to WhatsApp Sandbox Settings**
   - Go to Messaging > Settings > WhatsApp Sandbox Settings
   - Or: Messaging > Try it out > Send a WhatsApp message

2. **Configure Inbound Webhook URL**
   ```
   URL: https://halavoice.store/api/twilio-whatsapp/webhook
   ```

3. **Configure Status Callback URL** (optional)
   ```
   URL: https://halavoice.store/api/twilio-whatsapp/status
   ```

4. **Verify Webhook is Working**
   - Send test message from WhatsApp
   - Check Halavoice logs for incoming webhook

---

## Environment Variables Configuration

Add to `.env`:

```bash
# Twilio Configuration
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_WHATSAPP_FROM=whatsapp:+16292918169

# Twilio WhatsApp Webhook
TWILIO_WHATSAPP_WEBHOOK_URL=https://halavoice.store/api/twilio-whatsapp/webhook

# WhatsApp Auto-Reply Settings
WHATSAPP_AUTO_REPLY_ENABLED=true
WHATSAPP_DEFAULT_AI_MODEL=gpt-4o

# WhatsApp Message Templates (pre-approved by Meta)
WHATSAPP_WELCOME_TEMPLATE=welcome_message_1
WHATSAPP_APPOINTMENT_TEMPLATE=appointment_reminder_1
```

---

## Twilio Console Setup Steps

### Step 1: Enable WhatsApp for Your Number

1. Log in to Twilio Console
2. Go to **Messaging** > **Settings** > **WhatsApp Sandbox Settings**
3. Verify your number +1 (629) 291-8169 is eligible
4. Follow Twilio's WhatsApp enablement process

### Step 2: Configure Webhooks

1. In WhatsApp Sandbox Settings, set:
   - **"When a message comes in"**: `https://halavoice.store/api/twilio-whatsapp/webhook`
   - **"Status callback URL"**: `https://halavoice.store/api/twilio-whatsapp/status`

2. Click **Save**

### Step 3: Test Integration

1. Send a WhatsApp message to +1 (629) 291-8169
2. Check Halavoice logs for webhook receipt
3. Verify message is stored in database
4. Test AI auto-reply response

---

## Security Considerations

### Webhook Signature Verification

All incoming webhooks from Twilio must be verified using the `X-Twilio-Signature` header:

```typescript
import twilio from 'twilio';

const isValid = twilio.validateRequest(
  process.env.TWILIO_AUTH_TOKEN,
  signature,
  url,
  body
);
```

### Rate Limiting

Implement rate limiting for:
- Outbound messages (prevent spam)
- Webhook processing (prevent abuse)

### Access Control

- Public webhook URL is open to Twilio only
- Authenticated API routes require JWT token
- User-specific conversations are isolated by `user_id`

---

## Testing Checklist

### Phase 1: Webhook Receipt
- [ ] Send test WhatsApp message
- [ ] Verify webhook is received
- [ ] Check signature validation works
- [ ] Confirm message is stored in database

### Phase 2: Message Sending
- [ ] Send message via API
- [ ] Verify message is delivered to WhatsApp
- [ ] Check message status updates

### Phase 3: AI Auto-Reply
- [ ] Enable auto-reply for test conversation
- [ ] Send test message
- [ ] Verify AI response is generated
- [ ] Confirm response is sent via WhatsApp

### Phase 4: Integration Testing
- [ ] Test full conversation flow
- [ ] Verify media handling (images, documents)
- [ ] Test error handling
- [ ] Verify rate limiting

---

## Public URLs

### Production URLs:
```
Webhook URL:       https://halavoice.store/api/twilio-whatsapp/webhook
Status Callback:   https://halavoice.store/api/twilio-whatsapp/status
Send API:          https://halavoice.store/api/whatsapp/send (authenticated)
Conversations:     https://halavoice.store/api/whatsapp/conversations (authenticated)
```

### Testing (Development):
```
Webhook URL:       https://halavoice.store/api/twilio-whatsapp/webhook
(Same as production - no separate dev environment)
```

---

## Troubleshooting

### Issue: Webhook not received
**Solution**: 
- Verify URL is accessible from internet
- Check firewall allows inbound traffic
- Verify URL in Twilio Console is correct
- Check Halavoice server is running

### Issue: Signature validation fails
**Solution**:
- Verify `TWILIO_AUTH_TOKEN` is correct
- Check webhook URL exactly matches Twilio Console (including https/http)
- Ensure request body is not modified before validation

### Issue: Message not sent
**Solution**:
- Verify Twilio account has WhatsApp credits
- Check number is WhatsApp-enabled
- Verify message body complies with WhatsApp policies
- Check recipient number format (include country code)

### Issue: Template message rejected
**Solution**:
- Verify template is pre-approved by Meta
- Check template parameters match template definition
- Ensure template is active in Twilio Console

---

## Next Steps

1. **Setup Twilio Account**: Complete WhatsApp enablement process
2. **Implement Database**: Run migrations to create tables
3. **Implement Service Layer**: Create `twilio-whatsapp-service.ts`
4. **Implement Routes**: Create webhook and API routes
5. **Configure Webhooks**: Set URLs in Twilio Console
6. **Test**: Verify end-to-end message flow
7. **Deploy**: Deploy to production

---

## References

- [Twilio WhatsApp API Documentation](https://www.twilio.com/docs/whatsapp/api)
- [Twilio WhatsApp Quickstart](https://www.twilio.com/docs/whatsapp/quickstart)
- [Twilio Webhook Security Guide](https://www.twilio.com/docs/usage/security)
- [WhatsApp Business API Requirements](https://developers.facebook.com/docs/whatsapp/business-api)

---

**Document Status**: Draft v1.0
**Last Updated**: 2026-06-23
