751 lines
23 KiB
Markdown
751 lines
23 KiB
Markdown
# WhatsApp Shared Account Model - Implementation Guide
|
||
|
||
## Overview
|
||
|
||
This guide documents the **Shared WhatsApp Business Account** implementation for the bakery-ia pilot program. This model simplifies WhatsApp setup by using a single master WhatsApp Business Account with phone numbers assigned to each bakery tenant.
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
### Shared Account Model
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ Master WhatsApp Business Account (WABA) │
|
||
│ - Centrally managed by platform admin │
|
||
│ - Single set of credentials │
|
||
│ - Multiple phone numbers (up to 120) │
|
||
└─────────────────────────────────────────────┘
|
||
│
|
||
┌─────────────┼─────────────┐
|
||
│ │ │
|
||
Phone #1 Phone #2 Phone #3
|
||
Bakery A Bakery B Bakery C
|
||
```
|
||
|
||
### Key Benefits
|
||
|
||
✅ **Zero configuration for bakery users** - No Meta navigation required
|
||
✅ **5-minute setup** - Admin assigns phone number via UI
|
||
✅ **Lower support burden** - Centralized management
|
||
✅ **Predictable costs** - One WABA subscription
|
||
✅ **Perfect for pilot** - Quick deployment for 10 bakeries
|
||
|
||
---
|
||
|
||
## User Experience
|
||
|
||
### For Bakery Owners (Non-Technical Users)
|
||
|
||
**Before (Manual Setup):**
|
||
- Navigate Meta Business Suite ❌
|
||
- Create WhatsApp Business Account ❌
|
||
- Create message templates ❌
|
||
- Get credentials (3 different IDs) ❌
|
||
- Copy/paste into settings ❌
|
||
- **Time:** 1-2 hours, high error rate
|
||
|
||
**After (Shared Account):**
|
||
- Toggle WhatsApp ON ✓
|
||
- See assigned phone number ✓
|
||
- **Time:** 30 seconds, zero configuration
|
||
|
||
### For Platform Admin
|
||
|
||
**Admin Workflow:**
|
||
1. Access WhatsApp Admin page (`/app/admin/whatsapp`)
|
||
2. View list of tenants
|
||
3. Select tenant
|
||
4. Assign phone number from dropdown
|
||
5. Done!
|
||
|
||
---
|
||
|
||
## Technical Implementation
|
||
|
||
### Backend Changes
|
||
|
||
#### 1. Tenant Settings Model
|
||
|
||
**File:** `services/tenant/app/models/tenant_settings.py`
|
||
|
||
**Changed:**
|
||
```python
|
||
# OLD (Per-Tenant Credentials)
|
||
notification_settings = {
|
||
"whatsapp_enabled": False,
|
||
"whatsapp_phone_number_id": "",
|
||
"whatsapp_access_token": "", # REMOVED
|
||
"whatsapp_business_account_id": "", # REMOVED
|
||
"whatsapp_api_version": "v18.0", # REMOVED
|
||
"whatsapp_default_language": "es"
|
||
}
|
||
|
||
# NEW (Shared Account)
|
||
notification_settings = {
|
||
"whatsapp_enabled": False,
|
||
"whatsapp_phone_number_id": "", # Phone # from shared account
|
||
"whatsapp_display_phone_number": "", # Display format "+34 612 345 678"
|
||
"whatsapp_default_language": "es"
|
||
}
|
||
```
|
||
|
||
#### 2. WhatsApp Business Service
|
||
|
||
**File:** `services/notification/app/services/whatsapp_business_service.py`
|
||
|
||
**Changed `_get_whatsapp_credentials()` method:**
|
||
|
||
```python
|
||
async def _get_whatsapp_credentials(self, tenant_id: str) -> Dict[str, str]:
|
||
"""
|
||
Uses global master account credentials with tenant-specific phone number
|
||
"""
|
||
# Always use global master account
|
||
access_token = self.global_access_token
|
||
business_account_id = self.global_business_account_id
|
||
phone_number_id = self.global_phone_number_id # Default
|
||
|
||
# Fetch tenant's assigned phone number
|
||
if self.tenant_client:
|
||
notification_settings = await self.tenant_client.get_notification_settings(tenant_id)
|
||
if notification_settings and notification_settings.get('whatsapp_enabled'):
|
||
tenant_phone_id = notification_settings.get('whatsapp_phone_number_id', '')
|
||
if tenant_phone_id:
|
||
phone_number_id = tenant_phone_id # Use tenant's phone
|
||
|
||
return {
|
||
'access_token': access_token,
|
||
'phone_number_id': phone_number_id,
|
||
'business_account_id': business_account_id
|
||
}
|
||
```
|
||
|
||
**Key Change:** Always uses global credentials, but selects the phone number based on tenant assignment.
|
||
|
||
#### 3. Phone Number Management API
|
||
|
||
**New File:** `services/tenant/app/api/whatsapp_admin.py`
|
||
|
||
**Endpoints:**
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| GET | `/api/v1/admin/whatsapp/phone-numbers` | List available phone numbers from master WABA |
|
||
| GET | `/api/v1/admin/whatsapp/tenants` | List all tenants with WhatsApp status |
|
||
| POST | `/api/v1/admin/whatsapp/tenants/{id}/assign-phone` | Assign phone to tenant |
|
||
| DELETE | `/api/v1/admin/whatsapp/tenants/{id}/unassign-phone` | Remove phone assignment |
|
||
|
||
**Example: Assign Phone Number**
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{tenant_id}/assign-phone \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"phone_number_id": "123456789012345",
|
||
"display_phone_number": "+34 612 345 678"
|
||
}'
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Phone number +34 612 345 678 assigned to tenant 'Panadería San Juan'",
|
||
"tenant_id": "uuid-here",
|
||
"phone_number_id": "123456789012345",
|
||
"display_phone_number": "+34 612 345 678"
|
||
}
|
||
```
|
||
|
||
### Frontend Changes
|
||
|
||
#### 1. Simplified Notification Settings Card
|
||
|
||
**File:** `frontend/src/pages/app/database/ajustes/cards/NotificationSettingsCard.tsx`
|
||
|
||
**Removed:**
|
||
- Access Token input field
|
||
- Business Account ID input field
|
||
- Phone Number ID input field
|
||
- API Version selector
|
||
- Setup wizard instructions
|
||
|
||
**Added:**
|
||
- Display-only phone number (green badge if configured)
|
||
- "Contact support" message if not configured
|
||
- Language selector only
|
||
|
||
**UI Before/After:**
|
||
|
||
```
|
||
BEFORE:
|
||
┌────────────────────────────────────────┐
|
||
│ WhatsApp Business API Configuration │
|
||
│ │
|
||
│ Phone Number ID: [____________] │
|
||
│ Access Token: [____________] │
|
||
│ Business Acct: [____________] │
|
||
│ API Version: [v18.0 ▼] │
|
||
│ Language: [Español ▼] │
|
||
│ │
|
||
│ ℹ️ Setup Instructions: │
|
||
│ 1. Create WhatsApp Business... │
|
||
│ 2. Create templates... │
|
||
│ 3. Get credentials... │
|
||
└────────────────────────────────────────┘
|
||
|
||
AFTER:
|
||
┌────────────────────────────────────────┐
|
||
│ WhatsApp Configuration │
|
||
│ │
|
||
│ ✅ WhatsApp Configured │
|
||
│ Phone: +34 612 345 678 │
|
||
│ │
|
||
│ Language: [Español ▼] │
|
||
│ │
|
||
│ ℹ️ WhatsApp Notifications Included │
|
||
│ WhatsApp messaging is included │
|
||
│ in your subscription. │
|
||
└────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 2. Admin Interface
|
||
|
||
**New File:** `frontend/src/pages/app/admin/WhatsAppAdminPage.tsx`
|
||
|
||
**Features:**
|
||
- Lists all available phone numbers from master WABA
|
||
- Shows phone number quality rating (GREEN/YELLOW/RED)
|
||
- Lists all tenants with WhatsApp status
|
||
- Dropdown to assign phone numbers
|
||
- One-click unassign button
|
||
- Real-time status updates
|
||
|
||
**Screenshot Mockup:**
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ WhatsApp Admin Management │
|
||
│ Assign WhatsApp phone numbers to bakery tenants │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ 📞 Available Phone Numbers (3) │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ +34 612 345 678 Bakery Platform [GREEN] │
|
||
│ +34 612 345 679 Bakery Support [GREEN] │
|
||
│ +34 612 345 680 Bakery Notifications [YELLOW] │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ 👥 Bakery Tenants (10) │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Panadería San Juan ✅ Active │
|
||
│ Phone: +34 612 345 678 [Unassign] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Panadería Goiko ⚠️ Not Configured │
|
||
│ No phone number assigned [Assign phone number... ▼] │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Setup Instructions
|
||
|
||
### Step 1: Create Master WhatsApp Business Account (One-Time)
|
||
|
||
**Prerequisites:**
|
||
- Meta/Facebook Business account
|
||
- Verified business
|
||
- Phone number(s) to register
|
||
|
||
**Instructions:**
|
||
|
||
1. **Create WhatsApp Business Account**
|
||
- Go to [Meta Business Suite](https://business.facebook.com)
|
||
- Add WhatsApp product
|
||
- Complete business verification (1-3 days)
|
||
|
||
2. **Add Phone Numbers**
|
||
- Add at least 10 phone numbers (one per pilot bakery)
|
||
- Verify each phone number
|
||
- Note: You can request up to 120 phone numbers per WABA
|
||
|
||
3. **Create Message Templates**
|
||
- Create `po_notification` template:
|
||
```
|
||
Category: UTILITY
|
||
Language: Spanish (es)
|
||
Message: "Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}."
|
||
```
|
||
- Submit for approval (15 min - 24 hours)
|
||
|
||
4. **Get Master Credentials**
|
||
- Business Account ID: From WhatsApp Manager settings
|
||
- Access Token: Create System User or use temporary token
|
||
- Phone Number ID: Listed in phone numbers section
|
||
|
||
### Step 2: Configure Environment Variables
|
||
|
||
**File:** `services/notification/.env`
|
||
|
||
```bash
|
||
# Master WhatsApp Business Account Credentials
|
||
WHATSAPP_BUSINESS_ACCOUNT_ID=987654321098765
|
||
WHATSAPP_ACCESS_TOKEN=EAAxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||
WHATSAPP_PHONE_NUMBER_ID=123456789012345 # Default/fallback phone
|
||
WHATSAPP_API_VERSION=v18.0
|
||
ENABLE_WHATSAPP_NOTIFICATIONS=true
|
||
WHATSAPP_WEBHOOK_VERIFY_TOKEN=random-secret-token-here
|
||
```
|
||
|
||
**Security Notes:**
|
||
- Store `WHATSAPP_ACCESS_TOKEN` securely (use secrets manager in production)
|
||
- Rotate token every 60 days
|
||
- Use System User token (not temporary token) for production
|
||
|
||
### Step 3: Assign Phone Numbers to Tenants
|
||
|
||
**Via Admin UI:**
|
||
|
||
1. Access admin page: `http://localhost:5173/app/admin/whatsapp`
|
||
2. See list of tenants
|
||
3. For each tenant:
|
||
- Select phone number from dropdown
|
||
- Click assign
|
||
- Verify green checkmark appears
|
||
|
||
**Via API:**
|
||
|
||
```bash
|
||
# Assign phone to tenant
|
||
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{tenant_id}/assign-phone \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"phone_number_id": "123456789012345",
|
||
"display_phone_number": "+34 612 345 678"
|
||
}'
|
||
```
|
||
|
||
### Step 4: Test Notifications
|
||
|
||
**Enable WhatsApp for a Tenant:**
|
||
|
||
1. Login as bakery owner
|
||
2. Go to Settings → Notifications
|
||
3. Toggle WhatsApp ON
|
||
4. Verify phone number is displayed
|
||
5. Save settings
|
||
|
||
**Trigger Test Notification:**
|
||
|
||
```bash
|
||
# Create a purchase order (will trigger WhatsApp notification)
|
||
curl -X POST http://localhost:8003/api/v1/orders/purchase-orders \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-Tenant-ID: {tenant_id}" \
|
||
-d '{
|
||
"supplier_id": "uuid",
|
||
"items": [...]
|
||
}'
|
||
```
|
||
|
||
**Verify:**
|
||
- Check notification service logs: `docker logs -f notification-service`
|
||
- Supplier should receive WhatsApp message from assigned phone number
|
||
- Message status tracked in `whatsapp_messages` table
|
||
|
||
---
|
||
|
||
## Monitoring & Operations
|
||
|
||
### Check Phone Number Usage
|
||
|
||
```bash
|
||
# List all tenants with assigned phone numbers
|
||
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | jq
|
||
```
|
||
|
||
### View WhatsApp Message Logs
|
||
|
||
```sql
|
||
-- In notification database
|
||
SELECT
|
||
tenant_id,
|
||
recipient_phone,
|
||
template_name,
|
||
status,
|
||
created_at,
|
||
error_message
|
||
FROM whatsapp_messages
|
||
WHERE created_at > NOW() - INTERVAL '24 hours'
|
||
ORDER BY created_at DESC;
|
||
```
|
||
|
||
### Monitor Meta Rate Limits
|
||
|
||
WhatsApp Cloud API has the following limits:
|
||
|
||
| Metric | Limit |
|
||
|--------|-------|
|
||
| Messages per second | 80 |
|
||
| Messages per day (verified) | 100,000 |
|
||
| Messages per day (unverified) | 1,000 |
|
||
| Conversations per 24h | Unlimited (pay per conversation) |
|
||
|
||
**Check Quality Rating:**
|
||
|
||
```bash
|
||
curl -X GET "https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}" \
|
||
-H "Authorization: Bearer {ACCESS_TOKEN}" \
|
||
| jq '.quality_rating'
|
||
```
|
||
|
||
**Quality Ratings:**
|
||
- **GREEN** - No issues, full limits
|
||
- **YELLOW** - Warning, limits may be reduced
|
||
- **RED** - Quality issues, severely restricted
|
||
|
||
---
|
||
|
||
## Migration from Per-Tenant to Shared Account
|
||
|
||
If you have existing tenants with their own credentials:
|
||
|
||
### Automatic Migration Script
|
||
|
||
```python
|
||
# services/tenant/scripts/migrate_to_shared_account.py
|
||
"""
|
||
Migrate existing tenant WhatsApp credentials to shared account model
|
||
"""
|
||
|
||
import asyncio
|
||
from sqlalchemy import select
|
||
from app.core.database import database_manager
|
||
from app.models.tenant_settings import TenantSettings
|
||
|
||
async def migrate():
|
||
async with database_manager.get_session() as session:
|
||
# Get all tenant settings
|
||
result = await session.execute(select(TenantSettings))
|
||
all_settings = result.scalars().all()
|
||
|
||
for settings in all_settings:
|
||
notification_settings = settings.notification_settings
|
||
|
||
# If tenant has old credentials, preserve phone number ID
|
||
if notification_settings.get('whatsapp_access_token'):
|
||
phone_id = notification_settings.get('whatsapp_phone_number_id', '')
|
||
|
||
# Update to new schema
|
||
notification_settings['whatsapp_phone_number_id'] = phone_id
|
||
notification_settings['whatsapp_display_phone_number'] = '' # Admin will set
|
||
|
||
# Remove old fields
|
||
notification_settings.pop('whatsapp_access_token', None)
|
||
notification_settings.pop('whatsapp_business_account_id', None)
|
||
notification_settings.pop('whatsapp_api_version', None)
|
||
|
||
settings.notification_settings = notification_settings
|
||
|
||
print(f"Migrated tenant: {settings.tenant_id}")
|
||
|
||
await session.commit()
|
||
print("Migration complete!")
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(migrate())
|
||
```
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Issue: Tenant doesn't receive WhatsApp messages
|
||
|
||
**Checklist:**
|
||
1. ✅ WhatsApp enabled in tenant settings?
|
||
2. ✅ Phone number assigned to tenant?
|
||
3. ✅ Master credentials configured in environment?
|
||
4. ✅ Template approved by Meta?
|
||
5. ✅ Recipient phone number in E.164 format (+34612345678)?
|
||
|
||
**Check Logs:**
|
||
|
||
```bash
|
||
# Notification service logs
|
||
docker logs -f notification-service | grep whatsapp
|
||
|
||
# Look for:
|
||
# - "Using tenant-assigned WhatsApp phone number"
|
||
# - "WhatsApp template message sent successfully"
|
||
# - Any error messages
|
||
```
|
||
|
||
### Issue: Phone number assignment fails
|
||
|
||
**Error:** "Phone number already assigned to another tenant"
|
||
|
||
**Solution:**
|
||
```bash
|
||
# Find which tenant has the phone number
|
||
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | \
|
||
jq '.[] | select(.phone_number_id == "123456789012345")'
|
||
|
||
# Unassign from old tenant first
|
||
curl -X DELETE http://localhost:8001/api/v1/admin/whatsapp/tenants/{old_tenant_id}/unassign-phone
|
||
```
|
||
|
||
### Issue: "WhatsApp master account not configured"
|
||
|
||
**Solution:**
|
||
|
||
Ensure environment variables are set:
|
||
|
||
```bash
|
||
# Check if variables exist
|
||
docker exec notification-service env | grep WHATSAPP
|
||
|
||
# Should show:
|
||
# WHATSAPP_BUSINESS_ACCOUNT_ID=...
|
||
# WHATSAPP_ACCESS_TOKEN=...
|
||
# WHATSAPP_PHONE_NUMBER_ID=...
|
||
```
|
||
|
||
### Issue: Template not found
|
||
|
||
**Error:** "Template po_notification not found"
|
||
|
||
**Solution:**
|
||
|
||
1. Create template in Meta Business Manager
|
||
2. Wait for approval (check status):
|
||
```bash
|
||
curl -X GET "https://graph.facebook.com/v18.0/{WABA_ID}/message_templates" \
|
||
-H "Authorization: Bearer {TOKEN}" \
|
||
| jq '.data[] | select(.name == "po_notification")'
|
||
```
|
||
3. Ensure template language matches tenant's `whatsapp_default_language`
|
||
|
||
---
|
||
|
||
## Cost Analysis
|
||
|
||
### WhatsApp Business API Pricing (as of 2024)
|
||
|
||
**Meta Pricing:**
|
||
- **Business-initiated conversations:** €0.0319 - €0.0699 per conversation (Spain)
|
||
- **User-initiated conversations:** Free (24-hour window)
|
||
- **Conversation window:** 24 hours
|
||
|
||
**Monthly Cost Estimate (10 Bakeries):**
|
||
- Assume 5 PO notifications per bakery per day
|
||
- 5 × 10 bakeries × 30 days = 1,500 messages/month
|
||
- Cost: 1,500 × €0.05 = **€75/month**
|
||
|
||
**Shared Account vs. Individual Accounts:**
|
||
|
||
| Model | Setup Time | Monthly Cost | Support Burden |
|
||
|-------|------------|--------------|----------------|
|
||
| Individual Accounts | 1-2 hrs/bakery | €75 total | High |
|
||
| Shared Account | 5 min/bakery | €75 total | Low |
|
||
|
||
**Savings:** Time savings = 10 hrs × €50/hr = **€500 in setup cost**
|
||
|
||
---
|
||
|
||
## Future Enhancements
|
||
|
||
### Option 1: Template Management API
|
||
|
||
Automate template creation for new tenants:
|
||
|
||
```python
|
||
async def create_po_template(waba_id: str, access_token: str):
|
||
"""Programmatically create PO notification template"""
|
||
url = f"https://graph.facebook.com/v18.0/{waba_id}/message_templates"
|
||
payload = {
|
||
"name": "po_notification",
|
||
"language": "es",
|
||
"category": "UTILITY",
|
||
"components": [{
|
||
"type": "BODY",
|
||
"text": "Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}."
|
||
}]
|
||
}
|
||
response = await httpx.post(url, headers={"Authorization": f"Bearer {access_token}"}, json=payload)
|
||
return response.json()
|
||
```
|
||
|
||
### Option 2: WhatsApp Embedded Signup
|
||
|
||
For scaling beyond pilot:
|
||
|
||
- Apply for Meta Business Solution Provider program
|
||
- Implement OAuth-style signup flow
|
||
- Users click "Connect WhatsApp" → auto-configured
|
||
- Estimated implementation: 2-4 weeks
|
||
|
||
### Option 3: Tiered Pricing
|
||
|
||
```
|
||
Basic Tier (Free):
|
||
- Email notifications only
|
||
|
||
Standard Tier (€29/month):
|
||
- Shared WhatsApp account
|
||
- Pre-approved templates
|
||
- Up to 500 messages/month
|
||
|
||
Enterprise Tier (€99/month):
|
||
- Own WhatsApp Business Account
|
||
- Custom templates
|
||
- Unlimited messages
|
||
- White-label phone number
|
||
```
|
||
|
||
---
|
||
|
||
## Security & Compliance
|
||
|
||
### Data Privacy
|
||
|
||
**GDPR Compliance:**
|
||
- WhatsApp messages contain supplier contact info (phone numbers)
|
||
- Ensure GDPR consent for sending notifications
|
||
- Provide opt-out mechanism
|
||
- Data retention: Messages stored for 90 days (configurable)
|
||
|
||
**Encryption:**
|
||
- WhatsApp messages: End-to-end encrypted by Meta
|
||
- Access tokens: Stored in environment variables (use secrets manager in production)
|
||
- Database: Encrypt `notification_settings` JSON column
|
||
|
||
### Access Control
|
||
|
||
**Admin Access:**
|
||
- Only platform admins can assign/unassign phone numbers
|
||
- Implement role-based access control (RBAC)
|
||
- Audit log for phone number assignments
|
||
|
||
```python
|
||
# Example: Add admin check
|
||
@router.post("/admin/whatsapp/tenants/{tenant_id}/assign-phone")
|
||
async def assign_phone(tenant_id: UUID, current_user = Depends(require_admin_role)):
|
||
# Only admins can access
|
||
pass
|
||
```
|
||
|
||
---
|
||
|
||
## Support & Contacts
|
||
|
||
**Meta Support:**
|
||
- WhatsApp Business API Support: https://business.whatsapp.com/support
|
||
- Developer Docs: https://developers.facebook.com/docs/whatsapp
|
||
|
||
**Platform Admin:**
|
||
- Email: admin@bakery-platform.com
|
||
- Phone number assignment requests
|
||
- Template approval assistance
|
||
|
||
**Bakery Owner Help:**
|
||
- Settings → Notifications → Toggle WhatsApp ON
|
||
- If phone number not showing: Contact support
|
||
- Language preferences can be changed anytime
|
||
|
||
---
|
||
|
||
## Appendix
|
||
|
||
### A. Database Schema Changes
|
||
|
||
**Migration Script:**
|
||
|
||
```sql
|
||
-- Add new field, remove old fields
|
||
-- services/tenant/migrations/versions/00002_shared_whatsapp_account.py
|
||
|
||
ALTER TABLE tenant_settings
|
||
-- The notification_settings JSONB column now has:
|
||
-- + whatsapp_display_phone_number (new)
|
||
-- - whatsapp_access_token (removed)
|
||
-- - whatsapp_business_account_id (removed)
|
||
-- - whatsapp_api_version (removed)
|
||
;
|
||
|
||
-- No ALTER TABLE needed (JSONB is schema-less)
|
||
-- Migration handled by application code
|
||
```
|
||
|
||
### B. API Reference
|
||
|
||
**Phone Number Info Schema:**
|
||
|
||
```typescript
|
||
interface WhatsAppPhoneNumberInfo {
|
||
id: string; // Meta Phone Number ID
|
||
display_phone_number: string; // E.164 format: +34612345678
|
||
verified_name: string; // Business name verified by Meta
|
||
quality_rating: string; // GREEN, YELLOW, RED
|
||
}
|
||
```
|
||
|
||
**Tenant WhatsApp Status Schema:**
|
||
|
||
```typescript
|
||
interface TenantWhatsAppStatus {
|
||
tenant_id: string;
|
||
tenant_name: string;
|
||
whatsapp_enabled: boolean;
|
||
phone_number_id: string | null;
|
||
display_phone_number: string | null;
|
||
}
|
||
```
|
||
|
||
### C. Environment Variables Reference
|
||
|
||
```bash
|
||
# Notification Service (services/notification/.env)
|
||
WHATSAPP_BUSINESS_ACCOUNT_ID= # Meta WABA ID
|
||
WHATSAPP_ACCESS_TOKEN= # Meta System User Token
|
||
WHATSAPP_PHONE_NUMBER_ID= # Default phone (fallback)
|
||
WHATSAPP_API_VERSION=v18.0 # Meta API version
|
||
ENABLE_WHATSAPP_NOTIFICATIONS=true
|
||
WHATSAPP_WEBHOOK_VERIFY_TOKEN= # Random secret for webhook verification
|
||
```
|
||
|
||
### D. Useful Commands
|
||
|
||
```bash
|
||
# View all available phone numbers
|
||
curl http://localhost:8001/api/v1/admin/whatsapp/phone-numbers | jq
|
||
|
||
# View tenant WhatsApp status
|
||
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | jq
|
||
|
||
# Assign phone to tenant
|
||
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{id}/assign-phone \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"phone_number_id": "XXX", "display_phone_number": "+34 612 345 678"}'
|
||
|
||
# Unassign phone from tenant
|
||
curl -X DELETE http://localhost:8001/api/v1/admin/whatsapp/tenants/{id}/unassign-phone
|
||
|
||
# Test WhatsApp connectivity
|
||
curl -X GET "https://graph.facebook.com/v18.0/{PHONE_ID}" \
|
||
-H "Authorization: Bearer {TOKEN}"
|
||
|
||
# Check message template status
|
||
curl "https://graph.facebook.com/v18.0/{WABA_ID}/message_templates?fields=name,status,language" \
|
||
-H "Authorization: Bearer {TOKEN}" | jq
|
||
```
|
||
|
||
---
|
||
|
||
**Document Version:** 1.0
|
||
**Last Updated:** 2025-01-17
|
||
**Author:** Platform Engineering Team
|
||
**Status:** Production Ready for Pilot
|