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

Linkdeln
Linkdeln
Linkdeln
X
X
X
Instagram
Instagram
Instagram

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

Background
light
light

Stay Updated with Us

Stay Updated with Us

Ready to advance your skills? Sign up now and start your learning journey with us!

Ready to advance your skills? Sign up now and start your learning journey with us!

Instant Access

Boost Productivity

Easy Setup

No spam, just genuine updates!

Background
light

Stay Updated with Us

Ready to advance your skills? Sign up now and start your learning journey with us!

Instant Access

Boost Productivity

Easy Setup

No spam, just genuine updates!

Logo

Simplifying Projects and Achieving Goals.

Linkdeln
X

Canada

201 - 1065 Canadian Place #1061 Mississauga, ON L4W 0C2 Canada

Brazil

Paulista Avenue - São Paulo - Bela Vista District - Number 171 Zip Code: 01311-904

© Perdoado. All rights reserved. Contact us for more solutions.

Logo

Simplifying Projects and Achieving Goals.

Linkdeln
X

Canada

201 - 1065 Canadian Place #1061 Mississauga, ON L4W 0C2 Canada

Brazil

Paulista Avenue - São Paulo - Bela Vista District - Number 171 Zip Code: 01311-904

© Perdoado. All rights reserved. Contact us for more solutions.

Logo

Simplifying Projects and Achieving Goals.

Linkdeln
X

Canada

201 - 1065 Canadian Place #1061 Mississauga, ON L4W 0C2 Canada

Brazil

Paulista Avenue - São Paulo - Bela Vista District - Number 171 Zip Code: 01311-904

© Perdoado. All rights reserved. Contact us for more solutions.