Blog
Jan 4, 2025
Automating WhatsApp with Node.js and Baileys: Send, Receive, and Broadcast Messages with Code
Discover how conducting user research can inform design decisions and lead to better user satisfaction.
Elvis Gonçalves
WhatsApp is one of the most used messaging platforms in the world, and more and more businesses are looking to integrate it into their systems. In this article, I’ll walk you through using the powerful Baileys library to automate WhatsApp messaging with Node.js — including sending messages, receiving replies, and even broadcasting to groups or multiple users.
What is Baileys?
Baileys is a Node.js library that uses the WhatsApp Web protocol to provide programmatic access to WhatsApp features. It connects via WebSocket and allows you to send messages, respond to events, and handle media — all without a phone emulator.
Important: Baileys is unofficial. It replicates WhatsApp Web and may break if WhatsApp updates its system. Use responsibly and never for spam.
mkdir whatsapp-bot
cd whatsapp-bot
npm init -y
npm install @whiskeysockets/baileys
Connecting and QR Authentication
You’ll need to scan a QR code once to authenticate. Here’s a basic setup: index.js
import makeWASocket, { useMultiFileAuthState, fetchLatestBaileysVersion, DisconnectReason } from '@whiskeysockets/baileys'
import { Boom } from '@hapi/boom'
import P from 'pino'
async function startBot() {
const { state, saveCreds } = await useMultiFileAuthState('auth')
const { version } = await fetchLatestBaileysVersion()
const sock = makeWASocket({
version,
auth: state,
logger: P({ level: 'silent' }),
printQRInTerminal: true
})
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
if (connection === 'close') {
const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
if (shouldReconnect) startBot()
} else if (connection === 'open') {
console.log('✅ Connected to WhatsApp!')
}
})
sock.ev.on('messages.upsert', async ({ messages }) => {
const msg = messages[0]
if (!msg.key.fromMe && msg.message?.conversation) {
const sender = msg.key.remoteJid
const text = msg.message.conversation.toLowerCase()
console.log(`📩 Message from ${sender}: ${text}`)
if (text === 'hi') {
await sock.sendMessage(sender, { text: 'Hello! How can I help you today?' })
}
}
})
}
startBot()
Creating Simple Command Responses
Extend your bot with commands like !help, !time, or !info:
if (text === '!help') {
await sock.sendMessage(sender, {
text: `Available commands:\n- !help\n- !time\n- !about`
})
}
if (text === '!time') {
const time = new Date().toLocaleTimeString()
await sock.sendMessage(sender, { text: `🕒 Current time: ${time}` })
}
Sending Media (Images, Audio)
You can also send images or audio:import fs from 'fs'
await sock.sendMessage(sender, {
image: fs.readFileSync('./image.jpg'),
caption: 'Here is your image!'
})
Sending to Groups
To send messages to a group, you need its group ID (JID). You can fetch it or hardcode it if known:
const groupId = '1234567890-123456@g.us' // Replace with actual group JID
await sock.sendMessage(groupId, {
text: '👋 Hello everyone! This is an automated message.'
})
Real Use Cases
Here are real-world applications for Baileys:
Customer support automation
CRM integrations for reminders, updates, or invoices
Internal alert systems for devops or monitoring
WhatsApp-based surveys or data collection
Group moderation bots
Anti-Spam Best Practices
WhatsApp has systems in place to detect abuse. Here are some anti-spam rules to follow:
Do not send mass unsolicited messages
Always allow users to opt-in
Include clear identification (e.g. business name)
Avoid sending the exact same message repeatedly
Add delays (randomized) between message batches
Never use Baileys to mimic WhatsApp Business API behavior at scale
If you’re doing serious volume, use the official WhatsApp Business API.
Resources
GitHub: @whiskeysockets/baileys