Odyssey is a unified, intelligent WhatsApp API gateway built using Node.js, TypeScript, and the Baileys library. It acts as a central hub for personal microservices, receiving inbound WhatsApp messages and routing them intelligently to downstream applications via webhooks. It also provides a secure egress API for those applications to reply to the user.
- Baileys-Powered: Utilises the
@whiskeysockets/baileyslibrary for stable, non-official WhatsApp Web API connectivity. - Hybrid Intelligent Routing:
- Explicit Commands: Routes messages starting with predefined prefixes (e.g.,
/task,/otp,/link) to specific apps. - Session State Context: Temporarily locks the routing to a specific app when a conversational session is active.
- AI Intent Classification: Fallback mechanism using Google Gemini Flash to infer which downstream app should handle conversational input (e.g., "Remind me to buy milk" -> Task Manager).
- Explicit Commands: Routes messages starting with predefined prefixes (e.g.,
- Security-First:
- Inbound Whitelist: Silently drops messages from non-whitelisted numbers.
- Egress API Keys: Requires an
x-api-keyheader to send messages to WhatsApp. - Webhook Signatures: Sends a configured
x-gateway-secretto downstream apps to verify the request origin.
- Docker Ready: Designed for containerised deployments (Railway, Docker Compose).
- Swagger Documentation: Built-in interactive API docs.
flowchart TD
User([User on WhatsApp]) <-->|Baileys / WebSockets| Odyssey[Odyssey Gateway]
subgraph Routing Logic
Odyssey --> RouteCheck{Routing Rule}
RouteCheck -->|1. Explicit Command| AppWebhook
RouteCheck -->|2. Active Session| AppWebhook
RouteCheck -->|3. Gemini Intent Match| AppWebhook
RouteCheck -.->|4. Fallback| Drop[Log & Ignore]
end
subgraph Downstream Apps
AppWebhook((POST /webhook)) --> LIAW[Live in a week]
AppWebhook --> Bookmarks[Bookmarks API]
AppWebhook --> PersonalLLM[Personal Assistant]
end
LIAW -->|POST /send| Egress(Odyssey Egress API)
Bookmarks -->|POST /send| Egress
PersonalLLM -->|POST /send| Egress
Egress --> User
- Node.js v20+
- Docker & Docker Compose (optional)
- A WhatsApp account to scan the QR code
npm installCreate a .env file based on .env.example:
PORT=3000
GATEWAY_API_KEY=your_super_secret_api_key_here
GEMINI_API_KEY=your_gemini_api_key_here
ALLOWED_NUMBERS=919876543210Define your downstream apps, their webhook URLs, security secrets, and explicit routing prefixes:
{
"apps": {
"live_in_a_week": {
"webhook_url": "http://host.docker.internal:8001/webhook/whatsapp",
"description": "Personal task manager and weekly planner",
"webhook_secret": "LIAW_WEBHOOK_SECRET"
}
},
"explicit_commands": {
"/task": "live_in_a_week",
"/today": "live_in_a_week"
}
}Run via Docker:
docker compose up --buildOr run natively:
npm run devWhen the application starts, it will print a QR code in the terminal. Open WhatsApp on your phone -> Linked Devices -> Link a Device, and scan the QR code. Your session keys will be saved in the auth_info_baileys folder.
Odyssey exposes REST endpoints for downstream apps. Once running, view the interactive Swagger docs at:
http://localhost:3000/docs
POST /send
Headers:
x-api-key: Must matchGATEWAY_API_KEYin.env
Body:
{
"to": "919876543210",
"text": "Task saved successfully!"
}When Odyssey receives a WhatsApp message from a whitelisted number, it determines the target app and sends a POST request to the app's webhook_url with the following payload:
Headers:
x-gateway-secret: The app's configuredwebhook_secret(for verification)content-type:application/json
Body:
{
"from": "919876543210",
"text": "Buy milk today",
"timestamp": 1714400000,
"app_context": "live_in_a_week"
}Note: Downstream apps should handle these requests asynchronously or return a 200 OK quickly. They should use the Egress API (POST /send) to send any actual replies.
Odyssey is designed to be deployed easily on platforms like Railway or AWS.
- Deploy using the included
Dockerfile. - Ensure you mount a persistent volume to
/app/auth_info_baileysto persist your WhatsApp session keys between deployments/restarts.