This project is a fully TypeScript-based WhatsApp bot using Baileys and Fastify, supporting job queues, email delivery, and media handling.
- Node.js v18+
- WhatsApp account for QR code scan
- Clone the repo and install dependencies:
npm install-
Copy
.env.exampleto.envand fill in values. -
Start the app:
npm startThis bot is designed as a modular message-handler system:
src/index.ts- Bootstraps the app and WhatsApp socket.
- Dynamically loads every
.tsfile fromsrc/modules.
src/modules/- One file per feature/command (
ping.ts,reminder.ts,todo.ts, etc.). - Each module owns its parsing logic and action.
- Module toggle state is read via
getModuleStatus(name).
- One file per feature/command (
src/api/- Fastify routes for dashboard and automation endpoints.
- Includes endpoints for config, groups, module toggle, and queue-backed sends.
src/queues/queue.ts: queue abstraction + queue instances.processors.ts: consumers that process queued jobs.
src/utils/- Shared helpers such as database, config, and mail functions.
data/- SQLite database and runtime data.
auth/- Baileys session/auth state files.
Follow these steps to add a command module:
- Create a new file in
src/modules, for examplehello.ts. - Export a
handleMessagefunction with signature(client: WASocket, msg: WAMessage). - Parse message text, guard with your command, and return early when not matched.
- Send response using
client.sendMessage(...). - Restart the app. The loader in
src/index.tsauto-detects your new module file. - Enable/disable it from dashboard modules (or config storage), since runtime checks use the module filename as key.
Example module:
import { WASocket, WAMessage } from '@whiskeysockets/baileys';
export const handleMessage = async (client: WASocket, msg: WAMessage) => {
const body = (msg.message?.conversation || msg.message?.extendedTextMessage?.text || '').trim();
if (body !== '!hello') return;
await client.sendMessage(msg.key.remoteJid!, { text: 'Hello from module!' });
};
export default { handleMessage };Notes:
- The module name comes from filename (example:
hello.ts-> keyhello). - Keep one feature per module file for clean toggling and maintenance.
- For long-running or retryable tasks, enqueue work in
src/queuesinstead of blocking handler execution.
See .env.example for details.
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
See the LICENSE file for full details.
Built with ❤️ by @chethaslp for µLearn UCEK