Modular, scalable, and maintainable WhatsApp bot API with multi-device support.
whatsapp-bot/
βββ src/
β βββ config/
β β βββ constants.js # Global constants & configurations
β β βββ environment.js # Environment variables loader
β βββ core/
β β βββ WhatsAppManager.js # WhatsApp client manager
β βββ middleware/
β β βββ validation.js # Request validation middleware
β βββ routes/
β β βββ index.js # Route aggregator
β β βββ device.routes.js # Device management routes
β β βββ message.routes.js # Message sending routes
β β βββ status.routes.js # Status & health routes
β βββ services/
β β βββ device.service.js # Device business logic
β β βββ message.service.js # Message handling logic
β β βββ webhook.service.js # Webhook management
β βββ utils/
β β βββ file.utils.js # File operations
β β βββ download.utils.js # Download helpers
β β βββ logger.utils.js # Logging utilities
β βββ app.js # Express app setup
βββ configs/ # Device configs (auto-generated)
βββ sessions/ # WhatsApp sessions (auto-generated)
βββ index.js # Entry point
βββ package.json
βββ .env.example
βββ .gitignore
βββ README.md
# Clone or create project directory
mkdir whatsapp-bot && cd whatsapp-bot
# Install dependencies
npm installCreate .env file from example:
cp .env.example .envEdit .env and set your API key:
API_KEY=your_secret_api_key_here
PORT=4001# Production
npm start
# Development (with auto-reload)
npm run devPOST /api/devices
Content-Type: application/json
{
"apikey": "your_api_key",
"device_name": "My Device",
"webhook_url": "https://your-webhook.com/endpoint",
"auto_reply": false
}GET /api/devicesGET /api/device
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid"
}PUT /api/device
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid",
"device_name": "Updated Name",
"webhook_url": "https://new-webhook.com",
"auto_reply": true
}DELETE /api/device
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid"
}POST /api/device/qr
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid"
}POST /api/device/logout
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid"
}POST /api/device/send-message
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid",
"number": "6281234567890",
"message": "Hello World!"
}POST /api/device/send-image
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid",
"number": "6281234567890",
"image": "https://example.com/image.jpg",
"caption": "Check this out!"
}Or with base64:
{
"apikey": "your_api_key",
"device_id": "device-uuid",
"number": "6281234567890",
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"caption": "Base64 image"
}POST /api/device/send-document
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid",
"number": "6281234567890",
"document": "https://example.com/document.pdf",
"filename": "report.pdf",
"caption": "Here's the report"
}GET /api/statusGET /api/healthPOST /api/device/test-webhook
Content-Type: application/json
{
"apikey": "your_api_key",
"device_id": "device-uuid"
}| Variable | Description | Default |
|---|---|---|
API_KEY |
Global API key for authentication | YOUR_SUPER_SECRET_API_KEY |
PORT |
Server port | 4001 |
NODE_ENV |
Environment mode | development |
CONFIG_DIR |
Device configs directory | ./configs |
SESSIONS_DIR |
WhatsApp sessions directory | ./sessions |
WEBHOOK_TIMEOUT |
Webhook request timeout (ms) | 30000 |
MAX_FILE_SIZE |
Max file upload size (bytes) | 52428800 (50MB) |
DOWNLOAD_TIMEOUT |
Download timeout (ms) | 60000 |
- Manage multiple WhatsApp devices simultaneously
- Each device has independent session and configuration
- Auto-load existing devices on startup
- Send incoming messages to your webhook
- Send outgoing messages to your webhook
- Configurable per device
- Includes contact info and metadata
- Text messages
- Images (URL or base64)
- Documents (URL or base64)
- Captions and filenames support
- Configurable auto-reply per device
- Custom reply messages
!info- Show device information!test- Test bot response!ping- Ping bot
- Modular code structure
- Separation of concerns
- Easy to maintain and extend
- Comprehensive error handling
{
"device_id": "device-uuid",
"device_name": "My Device",
"type": "incoming_chat",
"data": {
"chat_id": "6281234567890",
"message_id": "message_id",
"name": "John Doe",
"profile_picture": "https://...",
"timestamp": 1234567890,
"message_body": "Hello!",
"message_ack": "PENDING",
"has_media": false,
"media_mime": "",
"media_name": "",
"location_attached": {
"lat": null,
"lng": null
},
"is_forwarding": false,
"is_from_me": false
}
}{
"device_id": "device-uuid",
"device_name": "My Device",
"type": "outgoing_chat",
"data": {
"chat_id": "6281234567890",
"message_id": "message_id",
"name": "Contact Name",
"timestamp": 1234567890,
"message_body": "Reply message",
"message_ack": "SENT",
"is_from_me": true
}
}- API key authentication on all endpoints
- Input validation middleware
- Rate limiting recommended for production
- Environment variables for sensitive data
- config/ - Configuration and constants
- core/ - Core business logic (WhatsApp client)
- middleware/ - Express middleware
- routes/ - API route handlers
- services/ - Business logic layer
- utils/ - Helper utilities
- Add configuration in
src/config/ - Add business logic in
src/services/ - Add routes in
src/routes/ - Add utilities in
src/utils/if needed
Use the Logger utility for consistent logging:
const Logger = require('./utils/logger.utils');
Logger.log(deviceId, 'Message', data);
Logger.error(deviceId, 'Error message', error);
Logger.success(deviceId, 'Success message');
Logger.warn(deviceId, 'Warning message');
Logger.info(deviceId, 'Info message');- Check if device already authenticated
- Try logout and re-initialize
- Wait for "WhatsApp Bot is ready!" message
- Check session directory permissions
- Verify webhook URL is accessible
- Check webhook endpoint logs
- Test with
/api/device/test-webhook
ISC
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please open an issue on GitHub.