WhatsApp Integration¶
WhatsApp provides two-way mobile command and control via Vonage Messages API (WABA - WhatsApp Business API).
Configuration¶
WABA Number: +44 7441 443388 (447441443388 without +)
Authorized Users:
- 447490195079 (Personal)
- 447816246275 (Work)
- 447713861128 (Girlfriend)
Webhook Endpoints (aegis.rbnk.uk):
- Inbound: /api/vonage/whatsapp/inbound
- Status: /api/vonage/whatsapp/status
Environment Variables¶
Configured in aegis.config.settings:
VONAGE_API_KEY = settings.vonage_api_key
VONAGE_API_SECRET = settings.vonage_api_secret
VONAGE_APPLICATION_ID = settings.vonage_application_id
VONAGE_WHATSAPP_NUMBER = settings.vonage_whatsapp_number
VONAGE_PRIVATE_KEY_B64 = settings.vonage_private_key_b64 # Base64-encoded private key
VONAGE_SIGNATURE_SECRET = settings.vonage_signature_secret # For webhook verification
Code Structure¶
Core Module: /home/agent/projects/aegis-core/aegis/whatsapp/__init__.py
Webhook Routes: /home/agent/projects/aegis-core/aegis/dashboard/routes/vonage.py
Available Commands¶
Claude Sessions (Power Feature)¶
Start and manage Claude Code sessions from your phone:
Starts a new Claude Code session with the task description.
Resume the current session with additional instructions.
List your active Claude sessions.
View details of a specific session.
Terminate the running session.
MCP Tasks Input¶
Provide input to tasks awaiting clarification:
Check tasks waiting for input:
Knowledge Graph¶
Search knowledge graph for entities and facts (brief).
Verbose knowledge graph search with full details.
Twitter Analysis¶
Analyze Twitter profile and extract tools, tactics, and insights.
3D Generation¶
Generate 3D models via Meshy.ai (for 3D printing).
System Commands¶
Get system health (containers, memory, disk, tasks).
Show pending Beads tasks.
Show today's schedule from Google Calendar.
Email triage status (unread count, recent activity).
Show today's journal entry (or specific date).
Comprehensive morning briefing (system health, tasks, calendar, emails).
Day summary (sessions completed, tasks closed, git activity, tomorrow preview).
Operations¶
Deploy services, restart containers, view logs.
Stop a Docker container.
View container logs (optionally filter for errors only).
Show all available commands.
Intent Recognition¶
WhatsApp commands are parsed using pattern matching:
Location: aegis.whatsapp.parse_intent()
Pattern Examples¶
# Claude session commands
r"^task:\s*(.+)" # task: <description>
r"^c:\s*(.*)$" # c: <prompt>
r"^continue:\s*(.*)$" # continue: <prompt>
r"^sessions?$" # sessions
r"^session\s+([a-zA-Z0-9-]+)" # session <id>
r"^stop\s+session" # stop session
# MCP Tasks input
r"^input:\s*(.+)" # input: <response>
r"^pending$|^awaiting$|^waiting$" # pending/awaiting/waiting
# Knowledge graph
r"^(?:recall|remember)\s+full\s+(.+)" # recall full <query>
r"^(?:recall|remember)\s+(.+)" # recall <query>
# Status
r"^/status$|^status$|^s$" # status / s
Sending Messages¶
Via Python Code¶
from aegis.whatsapp import send_whatsapp_message
result = await send_whatsapp_message(
to_number="447490195079",
text="Your task is complete!"
)
Via MCP Tool¶
Send Files¶
from aegis.whatsapp import send_whatsapp_file
result = await send_whatsapp_file(
to_number="447490195079",
file_url="https://aegisagent.ai/reports/analysis.pdf",
caption="Analysis complete",
filename="analysis.pdf"
)
Send Images¶
from aegis.whatsapp import send_whatsapp_image
result = await send_whatsapp_image(
to_number="447490195079",
image_url="https://aegisagent.ai/charts/metrics.png",
caption="Latest metrics"
)
Webhook Handling¶
Inbound Messages¶
POST requests from Vonage arrive at /api/vonage/whatsapp/inbound:
{
"message_uuid": "abc-123",
"from": "447490195079",
"to": "447441443388",
"timestamp": "2026-01-25T12:34:56Z",
"message_type": "text",
"text": "status",
"channel": "whatsapp"
}
Processed by aegis.whatsapp.process_inbound_message():
1. Verify sender is authorized
2. Parse intent from message text
3. Route to appropriate handler
4. Send response
Status Updates¶
POST requests from Vonage arrive at /api/vonage/whatsapp/status:
{
"message_uuid": "abc-123",
"to": "447490195079",
"from": "447441443388",
"timestamp": "2026-01-25T12:34:56Z",
"status": "delivered", // or "read", "failed"
"channel": "whatsapp"
}
Updates are logged to whatsapp_messages table.
Database Schema¶
whatsapp_sessions¶
CREATE TABLE whatsapp_sessions (
id SERIAL PRIMARY KEY,
phone_number TEXT NOT NULL UNIQUE,
last_intent TEXT,
last_target TEXT,
context JSONB DEFAULT '{}',
preferences JSONB DEFAULT '{"notifications": true}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
whatsapp_messages¶
CREATE TABLE whatsapp_messages (
id SERIAL PRIMARY KEY,
message_uuid TEXT UNIQUE,
phone_number TEXT NOT NULL,
direction TEXT NOT NULL, -- 'inbound' or 'outbound'
text TEXT,
intent TEXT,
status TEXT DEFAULT 'received', -- received, sent, delivered, read, failed
processed BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW()
);
Authentication¶
WhatsApp uses JWT authentication with Vonage:
from aegis.whatsapp import _create_vonage_jwt
token = _create_vonage_jwt("whatsapp") # Creates JWT valid for 1 hour
The private key is base64-encoded in environment variable VONAGE_PRIVATE_KEY_B64.
Webhook Signature Verification¶
Vonage signs webhooks with HMAC-SHA256:
def verify_vonage_signature(payload: bytes, signature: str) -> bool:
secret = settings.vonage_signature_secret
expected = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Set VONAGE_SIGNATURE_SECRET to enable verification.
Command Suggestions¶
Unknown commands trigger fuzzy matching:
User: "satus"
Bot: 🤔 Unknown command: "satus"
Did you mean: status or tasks?
Type 'help' for all commands
Uses Levenshtein distance for suggestions.
Best Practices¶
- Brevity: WhatsApp is mobile-first, keep responses concise
- Formatting: Use WhatsApp markdown (
*bold*,_italic_,` code `) - Context: Sessions maintain context, use
c:for follow-ups - Security: Only authorized numbers can send commands
- Error Handling: Always provide clear error messages with suggestions
- Rate Limits: Vonage enforces rate limits on message sending
Troubleshooting¶
Message Not Sent¶
Check Vonage application configuration:
curl -X GET "https://api.nexmo.com/v2/applications/$VONAGE_APPLICATION_ID" \
-H "Authorization: Bearer $JWT_TOKEN"
Webhook Not Received¶
Verify webhook URLs in Vonage dashboard:
# POST to /api/vonage/configure-webhooks
{
"inbound_url": "https://aegis.rbnk.uk/api/vonage/whatsapp/inbound",
"status_url": "https://aegis.rbnk.uk/api/vonage/whatsapp/status"
}
Unauthorized User¶
Add phone number to AUTHORIZED_NUMBERS in aegis/whatsapp/__init__.py:
AUTHORIZED_NUMBERS = {
"447490195079", # Personal
"447816246275", # Work
"447713861128", # Girlfriend
}
Example Workflow¶
- User sends:
task: Fix bug in auth.py - System creates Claude Code session
- System responds: "🤖 Task started: Fix bug in auth.py (Session: wa-1234-567890)"
- Claude works on the task
- System sends updates: "✅ Bug fixed in auth.py. Added validation for email field."
- User sends:
c: Now write tests for it - Claude continues in same session
- System responds: "✅ Added tests in test_auth.py. Coverage: 95%"