A powerful, extensible WhatsApp bot built with TypeScript β with a REST API, command system and in-memory cache
This application is a WhatsApp client that connects to WhatsApp Web using Puppeteer, enabling real-time automation, command execution and programmatic control via a built-in HTTP REST API. Built with TypeScript and following modern software architecture principles.
- π€ Command-based Architecture - Extensible command system with interface-based design
- π HTTP REST API - Control the bot and query data programmatically
- β‘ In-memory Cache - Contacts and chats cached with configurable TTL
- π Alias Support - Multiple names for the same command
- π‘οΈ Error Handling - Robust error handling with user-friendly messages
- π Type Safety - Full TypeScript implementation
- π― Easy to Extend - Add new commands in minutes
- π Group Validation - Built-in group-only command support
- π¬ Real-time Responses - Typing indicators and instant feedback
- π Graceful Shutdown - Clean SIGTERM/SIGINT handling
| Command | Aliases | Description |
|---|---|---|
!help |
!ajuda, !comandos, !commands |
Shows all available commands with descriptions |
!cotacao |
!moeda, !dolar, !bitcoin |
Get current currency exchange rates (USD, BTC, EUR) |
!cep <code> |
- | Search Brazilian postal code information |
!perfil @user |
!foto, !avatar, !pic |
Get user's profile picture |
!mencionar |
!everyone, !all, !todos |
Mention all group members (admin only) |
!sms @user |
- | Send SMS to mentioned user |
Note: All commands start with
!prefix
The bot exposes a REST API on port 3000 (configurable) for programmatic control.
Set API_KEY in .env to enable Bearer token authentication. If not set, the API is open.
Authorization: Bearer <your-api-key>
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/status |
Bot connection status + QR code when pending |
GET |
/api/contacts |
List all contacts (paginated) |
GET |
/api/contacts/search?q= |
Search contacts by name or number |
GET |
/api/groups |
List all groups (paginated) |
GET |
/api/groups/:id |
Group details + participants with admin flags |
POST |
/api/messages/send |
Send a message to a contact or group |
/api/contacts and /api/groups support ?page=1&limit=20 (max limit: 100).
{
"contacts": [...],
"pagination": {
"total": 120,
"page": 1,
"limit": 20,
"pages": 6
}
}Get bot status:
curl http://localhost:3000/api/status
# {"status":"ready","name":"MyBot","qr":null}List groups:
curl http://localhost:3000/api/groups?page=1&limit=10Send a message:
curl -X POST http://localhost:3000/api/messages/send \
-H "Content-Type: application/json" \
-d '{"to": "5511999999999", "text": "Hello!"}'Tip: Import
insomnia.jsonfrom the project root into Insomnia for a ready-to-use collection.
- Node.js 16+
- npm
- WhatsApp account
# Clone the repository
git clone git@github.com:caioagiani/whatsapp-bot.git
cd whatsapp-bot
# Install dependencies
npm install
# Configure environment variables
cp .env.example .env
# Edit .env with your settings
# Start the bot
npm run dev- When you start the bot for the first time, a QR code will appear in your terminal
- Open WhatsApp on your phone
- Go to Settings β Linked Devices β Link a Device
- Scan the QR code displayed in your terminal
- Wait for the authentication to complete
β
Your bot is now connected. The HTTP API is available at http://localhost:3000.
src/
βββ api/
β βββ middleware/
β β βββ auth.ts # Bearer token auth
β βββ routes/
β β βββ contacts.ts # GET /api/contacts
β β βββ groups.ts # GET /api/groups
β β βββ messages.ts # POST /api/messages/send
β β βββ status.ts # GET /api/status
β βββ utils/
β β βββ cache.ts # In-memory TTL cache
β β βββ paginate.ts # Pagination helper
β βββ server.ts # Express setup
β βββ state.ts # Bot state tracker
βββ app/
β βββ commands/ # Command implementations
β β βββ CepCommand.ts
β β βββ EconomyCommand.ts
β β βββ HelpCommand.ts
β β βββ ProfileCommand.ts
β β βββ QuoteCommand.ts
β β βββ SmsCommand.ts
β β βββ index.ts
β βββ interfaces/
β β βββ ICommand.ts
β β βββ Cep.ts
β βββ utils/
β βββ BaseCommand.ts
β βββ CommandDispatcher.ts
βββ config/
β βββ integrantes.json # Admin users (gitignored)
βββ data/ # WhatsApp session data (gitignored)
βββ services/
β βββ mobizon.ts # SMS service
β βββ shutdown.ts # Graceful shutdown
β βββ whatsapp.ts # WhatsApp client
βββ index.ts
getContacts() and getChats() are expensive Puppeteer calls (~500ms). Results are cached in memory for 30 seconds (configurable via CACHE_TTL_MS). Cache is cleared automatically on disconnect.
# HTTP API
API_PORT=3000
API_KEY= # Bearer token (leave empty to disable auth)
# Bot owner β receives a message when the bot connects
# Falls back to the first admin in integrantes.json if not set
BOT_OWNER_PHONE=
# Cache TTL in milliseconds (default: 30000)
CACHE_TTL_MS=30000
# Mobizon SMS (optional β required for !sms command)
MOBIZON_URL_SRV=https://api.mobizon.com.br
MOBIZON_API_KEY=For admin-only commands (like !mencionar), configure authorized users in src/config/integrantes.json (gitignored):
{
"company": [
{
"numero": "5511999999999",
"admin": true,
"nome": "Your Name",
"cargo": "Admin"
}
]
}// src/app/commands/HelloCommand.ts
import { BaseCommand } from '../utils/BaseCommand';
import type { Message } from 'whatsapp-web.js';
export class HelloCommand extends BaseCommand {
name = 'hello';
description = 'Responds with a greeting';
aliases = ['hi', 'ola'];
async execute(message: Message, args: string[]): Promise<Message> {
await this.sendTyping(message);
const name = args.join(' ') || 'friend';
return message.reply(`π Hello, ${name}!`);
}
}Then register in src/app/commands/index.ts:
commandDispatcher.register(new HelloCommand());# Run tests
npm test
# Run linter
npm run lint
# Development mode with auto-reload
npm run devTests use Jest + Supertest and cover all API endpoints, pagination, authentication and error paths (46 tests).
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using Conventional Commits
- Push to the branch and open a Pull Request
Copyright Β© 2022-2026 Caio Agiani
This project is licensed under the GNU AGPL License.
This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or affiliates.
Use this bot responsibly and in accordance with WhatsApp's Terms of Service.
- @pedroslopez - whatsapp-web.js library
- All contributors who have helped improve this project
- Author: Caio Agiani
- LinkedIn: linkedin.com/in/caioagiani
- GitHub: @caioagiani
Made with β€οΈ by Caio Agiani
