forked from sagnik/Project_Velocity
feat: Whatsapp Integration
This commit is contained in:
265
.Agent Context/COMMS_INTEGRATION_HANDOFF.md
Normal file
265
.Agent Context/COMMS_INTEGRATION_HANDOFF.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# Velocity Comms Integration — Handoff Document
|
||||
|
||||
## 1. Architecture Recommendation
|
||||
|
||||
### Goal
|
||||
Add a native **Conversations** module to Project Velocity so brokers/agents can manage WhatsApp (and future SMS/call) threads without leaving the WebOS.
|
||||
|
||||
### Design Philosophy
|
||||
- **Native Velocity UI**: Dark glass panels, compact density, blue accent, no iframe embeds.
|
||||
- **Provider-agnostic backend**: Abstract `CommsProvider` class with adapter pattern.
|
||||
- **CRM-first**: Every thread attempts to link to `crm_people` by `primary_phone`. Unresolved numbers are surfaced for manual linking.
|
||||
- **Mock-first development**: The module renders fully without real credentials.
|
||||
|
||||
### Provider Comparison
|
||||
|
||||
| Provider | Best For | Velocity Fit | 72-Hour Viability |
|
||||
|----------|----------|--------------|-------------------|
|
||||
| **Chatwoot** | Full support suite (email, SMS, WA) | Too heavy to embed; good UX reference | Low — would require stripping UI |
|
||||
| **WAHA** | Lightweight WhatsApp Web gateway | Good adapter candidate | High — simple REST, easy webhooks |
|
||||
| **Evolution API** | Modern WA gateway with groups, status, typing | Best adapter candidate | **High** — active community, clean webhooks |
|
||||
| **Meta Cloud API** | Official WABA; template-based outbound | Required for production scale at large builders | Medium — needs Meta Business verification |
|
||||
|
||||
**Recommended 72-hour route:**
|
||||
1. **Day 1**: Merge schema + backend routes + mock provider. Frontend compiles with mock data.
|
||||
2. **Day 2**: Connect Evolution API or WAHA in a staging environment. Test inbound webhook → thread creation.
|
||||
3. **Day 3**: CRM linking, settings UI, call-log upload placeholder, and smoke tests.
|
||||
|
||||
For production, plan a **dual-provider** setup:
|
||||
- **Evolution/WAHA** for quick conversational messaging (no Meta approval needed).
|
||||
- **Meta Cloud API** for template-based broadcast/re-engagement once Business Manager is verified.
|
||||
|
||||
---
|
||||
|
||||
## 2. Exact Files Created
|
||||
|
||||
```
|
||||
app/src/types/commsTypes.ts
|
||||
app/src/lib/commsApi.ts
|
||||
app/src/components/modules/Comms.tsx
|
||||
backend/db/schema_comms.sql
|
||||
backend/services/comms_provider.py
|
||||
backend/services/comms_waha_provider.py
|
||||
backend/services/comms_evolution_provider.py
|
||||
backend/services/comms_ingest.py
|
||||
backend/api/routes_comms.py
|
||||
COMMS_INTEGRATION_HANDOFF.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Patch Instructions for Existing Files
|
||||
|
||||
### A. `app/src/types/index.ts`
|
||||
Add `'comms'` to the `ModuleId` union:
|
||||
```typescript
|
||||
export type ModuleId = 'dashboard' | 'oracle' | 'sentinel' | 'inventory' | 'settings' | 'catalyst' | 'admin' | 'crm' | 'comms';
|
||||
```
|
||||
|
||||
### B. `app/src/App.tsx`
|
||||
1. Import the new component:
|
||||
```typescript
|
||||
import { Comms } from '@/components/modules/Comms';
|
||||
```
|
||||
2. Insert the route into `MODULE_ROUTES` **just before** `settings`:
|
||||
```typescript
|
||||
{ id: 'comms', path: '/comms', title: 'Conversations', component: Comms },
|
||||
```
|
||||
|
||||
### C. `app/src/components/layout/Sidebar.tsx`
|
||||
1. Import a new icon:
|
||||
```typescript
|
||||
import { MessageCircle } from 'lucide-react';
|
||||
```
|
||||
2. Add to `NAV_ICONS`:
|
||||
```typescript
|
||||
const NAV_ICONS: Record<string, LucideIcon> = {
|
||||
'/dashboard': LayoutGrid,
|
||||
'/oracle': MessageSquarePlus,
|
||||
'/sentinel': ScanFace,
|
||||
'/inventory': Building2,
|
||||
'/catalyst': Megaphone,
|
||||
'/comms': MessageCircle, // ← NEW
|
||||
'/settings': Sliders,
|
||||
'/admin': Shield,
|
||||
'/crm': Users,
|
||||
};
|
||||
```
|
||||
|
||||
### D. `backend/main.py`
|
||||
1. Import the router near the other imports:
|
||||
```python
|
||||
from backend.api.routes_comms import router as comms_router
|
||||
```
|
||||
2. Include it after the other routers:
|
||||
```python
|
||||
app.include_router(comms_router, prefix="/api/comms", tags=["Comms"])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Environment Variables
|
||||
|
||||
Add these to your `.env` or systemd environment:
|
||||
|
||||
```bash
|
||||
# Provider selection: mock | waha | evolution | meta_cloud
|
||||
COMMS_PROVIDER=mock
|
||||
|
||||
# Provider connectivity
|
||||
COMMS_PROVIDER_BASE_URL=
|
||||
COMMS_PROVIDER_API_KEY=
|
||||
COMMS_INSTANCE_ID=default
|
||||
|
||||
# Webhook security
|
||||
COMMS_WEBHOOK_SECRET=
|
||||
|
||||
# Phone normalization
|
||||
COMMS_DEFAULT_COUNTRY_CODE=91
|
||||
|
||||
# Media storage
|
||||
COMMS_MEDIA_STORAGE_DIR=/opt/dlami/nvme/assets/comms
|
||||
|
||||
# Transcription (none | openai | local)
|
||||
COMMS_TRANSCRIPTION_PROVIDER=none
|
||||
```
|
||||
|
||||
**No secrets are hardcoded in source.**
|
||||
|
||||
---
|
||||
|
||||
## 5. Database Migration
|
||||
|
||||
Run the SQL file against your Postgres database:
|
||||
|
||||
```bash
|
||||
psql $DATABASE_URL -f backend/db/schema_comms.sql
|
||||
```
|
||||
|
||||
Tables created:
|
||||
- `comms_threads` — conversation headers with CRM link
|
||||
- `comms_messages` — individual messages (inbound/outbound/system)
|
||||
- `comms_call_logs` — call records with optional transcript
|
||||
- `comms_settings` — key-value config store
|
||||
|
||||
---
|
||||
|
||||
## 6. API Routes
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| GET | `/api/comms/threads` | List threads (search, status, pagination) |
|
||||
| GET | `/api/comms/threads/{id}` | Get single thread with CRM enrichment |
|
||||
| GET | `/api/comms/threads/{id}/messages` | Chronological messages |
|
||||
| POST | `/api/comms/threads/{id}/messages` | Send outbound message via provider |
|
||||
| POST | `/api/comms/threads/{id}/link-person` | Link thread to `crm_people.id` |
|
||||
| POST | `/api/comms/threads/{id}/notes` | Add system note |
|
||||
| POST | `/api/comms/threads/{id}/tasks` | Add system task |
|
||||
| POST | `/api/comms/webhooks/{provider}` | Public webhook endpoint |
|
||||
| GET | `/api/comms/settings` | Get comms configuration |
|
||||
| PATCH | `/api/comms/settings` | Update configuration |
|
||||
| POST | `/api/comms/provider/test` | Test provider connectivity |
|
||||
| POST | `/api/comms/recordings/transcribe` | Queue transcription job |
|
||||
|
||||
---
|
||||
|
||||
## 7. Frontend Route Changes
|
||||
|
||||
- New sidebar item: **Conversations** (icon: `MessageCircle`)
|
||||
- Position: directly above **Settings**
|
||||
- Route: `/comms`
|
||||
- Component: `Comms.tsx` with three-pane layout (Inbox | Chat | CRM Rail)
|
||||
|
||||
---
|
||||
|
||||
## 8. Settings Changes
|
||||
|
||||
A new **Communications** subsection should be added inside your existing Settings module (or as a standalone card). Fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| Provider | select | mock / waha / evolution / meta_cloud |
|
||||
| Provider Base URL | text | e.g. `http://localhost:3000` |
|
||||
| API Key | password | masked after save |
|
||||
| Instance ID | text | WA/Evolution session name |
|
||||
| Phone Number ID | text | Meta Cloud API only |
|
||||
| Webhook Callback URL | text | Auto-populated or custom |
|
||||
| Webhook Secret | password | Sets `webhook_secret_set` flag |
|
||||
| Default Assignment User | select | User dropdown from `/api/auth/users` |
|
||||
| Auto-link by Phone | toggle | Match `crm_people.primary_phone` automatically |
|
||||
| Create CRM Interaction on Inbound | toggle | Write to `intel_interactions` if table exists |
|
||||
| Default Country Code | text | e.g. `91` for India |
|
||||
| Transcription Provider | select | none / openai / local |
|
||||
| Connection Test | button | Calls `POST /api/comms/provider/test` |
|
||||
|
||||
---
|
||||
|
||||
## 9. Smoke Test Steps
|
||||
|
||||
1. **DB**: Run `schema_comms.sql`. Verify tables exist.
|
||||
2. **Backend**: Start FastAPI. Confirm `/health` returns `db_pool: connected`.
|
||||
3. **Backend**: `curl -X POST http://localhost:8000/api/comms/provider/test` → should return mock success.
|
||||
4. **Frontend**: Load Velocity. Sidebar should show **Conversations**.
|
||||
5. **Frontend**: Click Conversations. Mock mode should render 3 threads and messages.
|
||||
6. **Frontend**: Send a message in mock thread. Optimistic update → mock delivery checkmark.
|
||||
7. **Backend**: Post sample webhook:
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/api/comms/webhooks/evolution -H "Content-Type: application/json" -d '{"event":"messages.upsert","instance":"default","data":{"key":{"remoteJid":"919876543210@s.whatsapp.net","fromMe":false,"id":"test-1"},"message":{"conversation":"Hello from webhook"},"messageTimestamp":1710000000}}'
|
||||
```
|
||||
8. **Backend**: Verify thread + message inserted. Check `comms_threads` for new row.
|
||||
9. **Frontend**: Refresh inbox. New thread should appear.
|
||||
10. **CRM Link**: Click "Link to Contact" (or call `POST /api/comms/threads/{id}/link-person`) and verify `person_id` is set.
|
||||
|
||||
---
|
||||
|
||||
## 10. Known Limitations
|
||||
|
||||
- **Call recording via WhatsApp API**: Neither WAHA nor Evolution supports native WhatsApp call recording. Call logs are designed for **external telephony intake** (manual upload or webhook from a PBX/VoIP system). Recording file + transcript workflow is scaffolded but needs a real transcription provider (OpenAI Whisper, AWS Transcribe, or faster-whisper) wired in.
|
||||
- **Media downloads**: `get_media()` is stubbed for WAHA/Evolution. Production needs signed URL handling or local file download.
|
||||
- **Meta Cloud API adapter**: Not yet implemented. Add `comms_meta_provider.py` when Meta Business verification is complete.
|
||||
- **Template messages**: Only placeholder methods exist. Template approval flow (Meta) or local template storage must be built for outbound campaigns.
|
||||
- **Webhook auth**: Currently accepts any payload. Add HMAC/signature verification per provider before production.
|
||||
- **Rate limiting**: Not implemented. Add FastAPI rate-limit middleware on `/api/comms/webhooks/{provider}`.
|
||||
- **phonenumbers library**: `comms_ingest.py` gracefully degrades to regex if `phonenumbers` is not installed. Install it for robust E.164 normalization:
|
||||
```bash
|
||||
pip install phonenumbers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. What Still Needs Real Credentials
|
||||
|
||||
| Item | What You Need |
|
||||
|------|---------------|
|
||||
| **Evolution API** | A running Evolution instance (Docker), API key, and a paired WhatsApp number. |
|
||||
| **WAHA** | A running WAHA container, session QR-scan, and API key. |
|
||||
| **Meta Cloud API** | Meta Business Manager, verified business, WhatsApp Business Account, permanent access token, phone number ID. |
|
||||
| **Transcription** | OpenAI API key (for Whisper) or local faster-whisper model path. |
|
||||
| **CRM enrichment** | Ensure `crm_people` table exists with `primary_phone` indexed. |
|
||||
|
||||
---
|
||||
|
||||
## 12. What to Verify Before Production
|
||||
|
||||
- [ ] Webhook endpoint is exposed via HTTPS (ngrok/cloudflare tunnel for local dev).
|
||||
- [ ] `COMMS_WEBHOOK_SECRET` is set and signature verification is enabled in `routes_comms.py`.
|
||||
- [ ] Database has indexes on `comms_threads(phone_e164)` and `comms_messages(thread_id, created_at)`.
|
||||
- [ ] `crm_people.primary_phone` is normalized to E.164 before comms matching.
|
||||
- [ ] Media storage directory exists and is writable (`COMMS_MEDIA_STORAGE_DIR`).
|
||||
- [ ] Outbound message queue / retry logic is added (currently synchronous).
|
||||
- [ ] GDPR/opt-out handling is implemented if targeting EU markets.
|
||||
- [ ] Backup strategy for `comms_messages` (contains legal conversation records).
|
||||
|
||||
---
|
||||
|
||||
## 13. Next Iteration Ideas
|
||||
|
||||
- **Bulk broadcast**: Template-based outbound to filtered CRM segments.
|
||||
- **AI reply suggestions**: Integrate Oracle / local LLM to draft replies based on CRM context.
|
||||
- **Voice notes**: Upload `.ogg` audio, transcribe, store transcript as message.
|
||||
- **Read receipts**: Poll provider for delivery/read status and update `comms_messages`.
|
||||
- **Assignment rules**: Round-robin or load-based auto-assignment to agents.
|
||||
|
||||
---
|
||||
|
||||
*Document generated for Project Velocity v1.1 — Comms Module Integration*
|
||||
Reference in New Issue
Block a user