# Webhook Integration Examples

This document shows real-world examples of how to integrate the WhatsApp CRM API webhooks with different platforms.

## Example 1: Integrate with Shopify

### Scenario: Customer Messages → Create Order

```javascript
const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

const WHATSAPP_API = 'http://localhost:3000/api';
const SESSION_ID = 'your_session_id';
const API_KEY = 'your_api_key';

// Webhook endpoint for WhatsApp CRM API
app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'message.received') {
    const customerPhone = data.from;
    const message = data.text.toLowerCase();

    // Check if customer is asking to place order
    if (message.includes('order') || message.includes('buy')) {
      try {
        // 1. Get customer details from our database
        const customer = await db.findCustomer(customerPhone);

        // 2. Create Shopify order
        const shopifyResponse = await axios.post(
          'https://yourshop.myshopify.com/admin/api/2024-01/orders.json',
          {
            order: {
              email: customer.email,
              financial_status: 'authorized',
              fulfillment_status: 'unshipped',
              line_items: [
                {
                  variant_id: 123456,
                  quantity: 1
                }
              ]
            }
          },
          {
            headers: {
              'X-Shopify-Access-Token': process.env.SHOPIFY_TOKEN
            }
          }
        );

        const orderId = shopifyResponse.data.order.id;

        // 3. Send confirmation via WhatsApp
        await axios.post(
          `${WHATSAPP_API}/messages/${SESSION_ID}/send`,
          {
            phone: customerPhone,
            message: `Great! Your order #${orderId} has been created. Your order will be shipped within 24 hours.`
          },
          {
            headers: { 'X-API-Key': API_KEY }
          }
        );

        // 4. Store interaction in database
        await db.logInteraction({
          customer: customerPhone,
          event: 'order_created',
          orderId: orderId,
          timestamp: new Date()
        });

      } catch (error) {
        console.error('Error processing order:', error);
        
        // Send error message to customer
        await axios.post(
          `${WHATSAPP_API}/messages/${SESSION_ID}/send`,
          {
            phone: customerPhone,
            message: 'Sorry, there was an issue processing your order. Please try again later.'
          },
          {
            headers: { 'X-API-Key': API_KEY }
          }
        );
      }
    }
  }

  res.json({ success: true });
});

app.listen(3001, () => console.log('Shopify webhook listening on port 3001'));
```

---

## Example 2: Integrate with HubSpot CRM

### Scenario: New Message → Create HubSpot Contact/Lead

```javascript
const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

const HUBSPOT_API = 'https://api.hubapi.com';
const HUBSPOT_TOKEN = process.env.HUBSPOT_API_KEY;
const WHATSAPP_API = 'http://localhost:3000/api';
const SESSION_ID = 'your_session_id';
const API_KEY = 'your_api_key';

app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, sessionId, data } = req.body;

  if (event === 'message.received') {
    try {
      // 1. Check if contact exists in HubSpot
      const existingContact = await axios.get(
        `${HUBSPOT_API}/crm/v3/objects/contacts/search`,
        {
          headers: {
            'Authorization': `Bearer ${HUBSPOT_TOKEN}`,
            'Content-Type': 'application/json'
          },
          data: {
            filterGroups: [
              {
                filters: [
                  {
                    propertyName: 'phone',
                    operator: 'EQ',
                    value: data.from
                  }
                ]
              }
            ]
          }
        }
      ).catch(() => null);

      let contactId;

      if (existingContact?.data?.results?.length > 0) {
        contactId = existingContact.data.results[0].id;
      } else {
        // 2. Create new contact in HubSpot
        const createResponse = await axios.post(
          `${HUBSPOT_API}/crm/v3/objects/contacts`,
          {
            properties: {
              firstname: 'WhatsApp',
              lastname: 'Contact',
              phone: data.from,
              lifecyclestage: 'lead'
            }
          },
          {
            headers: {
              'Authorization': `Bearer ${HUBSPOT_TOKEN}`,
              'Content-Type': 'application/json'
            }
          }
        );

        contactId = createResponse.data.id;
      }

      // 3. Create engagement/note in HubSpot
      await axios.post(
        `${HUBSPOT_API}/crm/v3/objects/contacts/${contactId}/associations`,
        {
          inputs: [
            {
              id: contactId,
              types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 0 }]
            }
          ]
        },
        {
          headers: {
            'Authorization': `Bearer ${HUBSPOT_TOKEN}`,
            'Content-Type': 'application/json'
          }
        }
      );

      // 4. Send acknowledgment
      await axios.post(
        `${WHATSAPP_API}/messages/${SESSION_ID}/send`,
        {
          phone: data.from,
          message: 'Thanks for reaching out! We\'ve received your message and will get back to you soon.'
        },
        {
          headers: { 'X-API-Key': API_KEY }
        }
      );

    } catch (error) {
      console.error('HubSpot integration error:', error);
    }
  }

  res.json({ success: true });
});

app.listen(3001);
```

---

## Example 3: Integrate with Twilio for SMS Notifications

### Scenario: WhatsApp Message → Send SMS Notification

```javascript
const express = require('express');
const twilio = require('twilio');
const app = express();

app.use(express.json());

const TWILIO_ACCOUNT = process.env.TWILIO_ACCOUNT_SID;
const TWILIO_AUTH = process.env.TWILIO_AUTH_TOKEN;
const twilioClient = twilio(TWILIO_ACCOUNT, TWILIO_AUTH);

app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'message.received') {
    try {
      // Send SMS to business owner
      await twilioClient.messages.create({
        body: `New WhatsApp message from ${data.from}: "${data.text}"`,
        from: process.env.TWILIO_PHONE,
        to: process.env.OWNER_PHONE
      });

      console.log('SMS notification sent to owner');

    } catch (error) {
      console.error('Twilio error:', error);
    }
  }

  res.json({ success: true });
});

app.listen(3001);
```

---

## Example 4: Integrate with OpenAI for Chatbot

### Scenario: Message → ChatGPT → Auto-Response

```javascript
const express = require('express');
const axios = require('axios');
const { Configuration, OpenAIApi } = require('openai');
const app = express();

app.use(express.json());

const openai = new OpenAIApi(
  new Configuration({
    apiKey: process.env.OPENAI_API_KEY
  })
);

const WHATSAPP_API = 'http://localhost:3000/api';
const SESSION_ID = 'your_session_id';
const API_KEY = 'your_api_key';

app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'message.received') {
    try {
      // 1. Get AI response
      const completion = await openai.createChatCompletion({
        model: 'gpt-3.5-turbo',
        messages: [
          {
            role: 'system',
            content: 'You are a helpful customer service assistant. Keep responses short (1-2 sentences) for WhatsApp.'
          },
          {
            role: 'user',
            content: data.text
          }
        ]
      });

      const aiResponse = completion.data.choices[0].message.content;

      // 2. Send response via WhatsApp
      await axios.post(
        `${WHATSAPP_API}/messages/${SESSION_ID}/send`,
        {
          phone: data.from,
          message: aiResponse
        },
        {
          headers: { 'X-API-Key': API_KEY }
        }
      );

    } catch (error) {
      console.error('ChatGPT error:', error);
    }
  }

  res.json({ success: true });
});

app.listen(3001);
```

---

## Example 5: Integrate with Google Sheets for Logging

### Scenario: All Events → Log to Google Sheets

```javascript
const express = require('express');
const { google } = require('googleapis');
const app = express();

app.use(express.json());

const sheets = google.sheets('v4');
const SPREADSHEET_ID = process.env.GOOGLE_SHEET_ID;
const SHEET_NAME = 'WhatsApp Messages';

// Setup Google Sheets authentication
const auth = new google.auth.GoogleAuth({
  keyFile: process.env.GOOGLE_KEY_FILE,
  scopes: ['https://www.googleapis.com/auth/spreadsheets']
});

app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  try {
    // Prepare row data based on event
    let row = [
      new Date().toISOString(),
      event,
      data.from || data.to || data.phone || 'N/A',
      data.text || data.name || 'N/A'
    ];

    // 1. Log to Google Sheets
    await sheets.spreadsheets.values.append({
      auth,
      spreadsheetId: SPREADSHEET_ID,
      range: `${SHEET_NAME}!A:D`,
      valueInputOption: 'USER_ENTERED',
      resource: {
        values: [row]
      }
    });

    console.log('Logged to Google Sheets');

  } catch (error) {
    console.error('Google Sheets error:', error);
  }

  res.json({ success: true });
});

app.listen(3001);
```

---

## Example 6: Multi-Event Handler

### Scenario: Handle All Event Types

```javascript
const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

const WHATSAPP_API = 'http://localhost:3000/api';
const SESSION_ID = 'your_session_id';
const API_KEY = 'your_api_key';

// Store conversation context
const conversations = {};

app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  try {
    switch(event) {
      case 'message.received':
        await handleMessageReceived(data);
        break;

      case 'message.sent':
        await handleMessageSent(data);
        break;

      case 'contact.added':
        await handleContactAdded(data);
        break;

      case 'contact.updated':
        await handleContactUpdated(data);
        break;

      case 'session.authenticated':
        await handleSessionAuthenticated(data);
        break;

      case 'session.disconnected':
        await handleSessionDisconnected(data);
        break;
    }
  } catch (error) {
    console.error('Error handling webhook:', error);
  }

  res.json({ success: true });
});

async function handleMessageReceived(data) {
  const { from, text, timestamp } = data;

  // 1. Store conversation
  if (!conversations[from]) {
    conversations[from] = [];
  }
  conversations[from].push({
    type: 'received',
    text: text,
    timestamp: timestamp
  });

  // 2. Auto-reply
  if (text.toLowerCase().includes('hello')) {
    await axios.post(
      `${WHATSAPP_API}/messages/${SESSION_ID}/send`,
      {
        phone: from,
        message: 'Hello! How can we help you today?'
      },
      {
        headers: { 'X-API-Key': API_KEY }
      }
    );
  }

  // 3. Log to database
  await db.logMessage({
    from: from,
    text: text,
    direction: 'incoming',
    timestamp: timestamp
  });

  console.log(`[${timestamp}] Message from ${from}: ${text}`);
}

async function handleMessageSent(data) {
  const { to, text, timestamp } = data;

  if (!conversations[to]) {
    conversations[to] = [];
  }
  conversations[to].push({
    type: 'sent',
    text: text,
    timestamp: timestamp
  });

  console.log(`[${timestamp}] Message sent to ${to}`);
}

async function handleContactAdded(data) {
  const { contactId, phone, name } = data;

  await db.addContact({
    contactId: contactId,
    phone: phone,
    name: name
  });

  console.log(`New contact: ${name} (${phone})`);
}

async function handleContactUpdated(data) {
  const { contactId, phone, name } = data;

  await db.updateContact(contactId, { name: name, phone: phone });

  console.log(`Updated contact: ${name}`);
}

async function handleSessionAuthenticated(data) {
  const { phone_number } = data;

  await db.updateSession({
    phoneNumber: phone_number,
    status: 'authenticated'
  });

  console.log(`Session authenticated: ${phone_number}`);
}

async function handleSessionDisconnected(data) {
  const { reason } = data;

  console.log(`Session disconnected: ${reason}`);
}

app.listen(3001, () => {
  console.log('Webhook server running on port 3001');
});
```

---

## Example 7: Queue-Based Processing with Bull

### Scenario: Use Job Queue for Better Reliability

```javascript
const express = require('express');
const Queue = require('bull');
const axios = require('axios');
const app = express();

app.use(express.json());

// Create job queues
const messageQueue = new Queue('whatsapp-messages', {
  redis: { host: 'localhost', port: 6379 }
});

const contactQueue = new Queue('whatsapp-contacts', {
  redis: { host: 'localhost', port: 6379 }
});

// Process message queue
messageQueue.process(async (job) => {
  const { phone, message } = job.data;

  console.log(`Processing message to ${phone}`);

  // Send message
  await axios.post(
    'http://localhost:3000/api/messages/SESSION_ID/send',
    { phone: phone, message: message },
    { headers: { 'X-API-Key': 'API_KEY' } }
  );
});

// Process contact queue
contactQueue.process(async (job) => {
  const { phone, name } = job.data;

  console.log(`Processing contact: ${name}`);

  // Store in database
  await db.addContact({ phone, name });
});

// Webhook handler
app.post('/webhooks/whatsapp', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'message.received') {
    // Add to queue instead of processing directly
    await messageQueue.add({
      phone: data.from,
      message: `Thanks for your message: "${data.text}"`
    }, {
      attempts: 3,
      backoff: {
        type: 'exponential',
        delay: 2000
      }
    });
  }

  if (event === 'contact.added') {
    await contactQueue.add({
      phone: data.phone,
      name: data.name
    });
  }

  res.json({ success: true });
});

app.listen(3001);
```

---

## Common Patterns

### Pattern 1: Get Customer Info Before Responding

```javascript
async function handleMessageReceived(data) {
  const { from, text } = data;

  // 1. Get customer from database
  const customer = await db.findCustomer(from);

  if (!customer) {
    // 2. New customer
    await sendWelcomeMessage(from);
  } else {
    // 3. Returning customer
    await sendPersonalizedMessage(from, customer);
  }
}
```

### Pattern 2: Template-Based Responses

```javascript
async function handleMessageReceived(data) {
  const { from, text } = data;

  // Get appropriate template
  let template;
  if (text.includes('price')) {
    template = 'PRICE_INQUIRY';
  } else if (text.includes('order')) {
    template = 'ORDER_PLACEMENT';
  } else {
    template = 'GENERAL_INQUIRY';
  }

  // Render and send
  const response = await getTemplate(template);
  await sendMessage(from, response);
}
```

### Pattern 3: Rate Limiting

```javascript
const rateLimit = new Map();

async function handleMessageReceived(data) {
  const { from } = data;
  const now = Date.now();
  const lastMessage = rateLimit.get(from);

  if (lastMessage && now - lastMessage < 1000) {
    // Too soon, skip
    return;
  }

  rateLimit.set(from, now);

  // Process message
}
```

---

## Testing Your Integration

```bash
# 1. Register webhook
curl -X POST http://localhost:3000/api/webhooks/SESSION_ID \
  -H "X-API-Key: API_KEY" \
  -d '{
    "eventType": "message.received",
    "webhookUrl": "http://localhost:3001/webhooks/whatsapp"
  }'

# 2. Test webhook
curl -X POST http://localhost:3000/api/webhooks/SESSION_ID/WEBHOOK_ID/test \
  -H "X-API-Key: API_KEY"

# 3. Check logs
curl http://localhost:3000/api/webhooks/SESSION_ID/WEBHOOK_ID/logs \
  -H "X-API-Key: API_KEY"
```

---

## Production Deployment Checklist

- [ ] Use environment variables for all API keys
- [ ] Implement error handling and logging
- [ ] Add rate limiting on webhook endpoints
- [ ] Use database transactions for reliability
- [ ] Implement message queues for async processing
- [ ] Add monitoring and alerting
- [ ] Use HTTPS for all webhook URLs
- [ ] Implement idempotency keys
- [ ] Add request validation
- [ ] Scale horizontally with load balancer

---

These examples show the flexibility of the webhook system - you can integrate with virtually any platform!
