Como criar um bot de WhatsApp que funciona 24h numa VPS (passo a passo)
Um bot de WhatsApp com menu automático rodando no seu servidor, sem depender do seu computador ligado. Node.js, Baileys e PM2, com código pronto.

O problema do bot no notebook
Quase todo bot de WhatsApp começa rodando no computador de quem programou. Funciona até o notebook fechar, a internet cair ou o Windows reiniciar para atualizar. Para atender cliente de verdade, o bot precisa ficar ligado 24 horas, e é para isso que serve uma VPS.
Neste passo a passo você vai:
- criar um bot com menu automático em Node.js;
- conectar o bot ao WhatsApp lendo um QR code;
- deixar o bot rodando 24h na VPS, voltando sozinho se cair ou se o servidor reiniciar.
Antes de começar: um aviso importante
O bot deste tutorial usa a biblioteca Baileys, que conecta no WhatsApp da mesma forma que o WhatsApp Web. Ela é gratuita e muito usada, mas não é a API oficial da Meta. Por isso:
- use um número separado, nunca o seu número pessoal ou o número principal da empresa;
- não dispare mensagens em massa para quem não te chamou: é o jeito mais rápido de ter o número banido;
- deixe o bot responder quem fala com você.
Para campanhas e avisos em massa, o caminho é a API oficial do WhatsApp Business (Cloud API), com modelos aprovados pela Meta.
O que você vai precisar
- Uma VPS Linux (Ubuntu ou Debian) com 1 GB de RAM ou mais. O Baileys não abre navegador, então roda leve.
- Acesso root por SSH.
- Um celular com o WhatsApp do número que vai virar bot.
1. Instale o Node.js
Entre na VPS:
ssh root@IP_DA_VPS
Instale o Node.js 22:
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
Confira com node -v. Deve aparecer v22 ou maior.
2. Crie o projeto
mkdir -p /opt/bot && cd /opt/bot
npm init -y
npm pkg set type=module
npm install @whiskeysockets/baileys qrcode-terminal pino
3. Escreva o bot
Crie o arquivo bot.js:
import makeWASocket, { useMultiFileAuthState, DisconnectReason } from '@whiskeysockets/baileys'
import qrcode from 'qrcode-terminal'
import pino from 'pino'
const RESPOSTAS = {
menu: 'Olá! 👋 Escolha uma opção:\n1 - Horário de atendimento\n2 - Falar com um atendente',
'1': 'Atendemos de segunda a sexta, das 9h às 18h.',
'2': 'Certo! Um atendente vai te responder em instantes.',
}
async function iniciar() {
const { state, saveCreds } = await useMultiFileAuthState('sessao')
const sock = makeWASocket({ auth: state, logger: pino({ level: 'silent' }) })
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {
if (qr) qrcode.generate(qr, { small: true })
if (connection === 'open') console.log('✅ Bot conectado')
if (connection === 'close') {
const deslogado = lastDisconnect?.error?.output?.statusCode === DisconnectReason.loggedOut
if (deslogado) console.log('Sessão encerrada. Apague a pasta "sessao" e leia o QR de novo.')
else iniciar()
}
})
sock.ev.on('messages.upsert', async ({ messages, type }) => {
if (type !== 'notify') return
for (const msg of messages) {
if (msg.key.fromMe || msg.key.remoteJid?.endsWith('@g.us')) continue
const texto = (msg.message?.conversation || msg.message?.extendedTextMessage?.text || '').trim().toLowerCase()
const resposta = RESPOSTAS[texto] ?? RESPOSTAS.menu
await sock.sendMessage(msg.key.remoteJid, { text: resposta })
}
})
}
iniciar()
O que ele faz:
- guarda a sessão na pasta
sessao, para você não precisar ler o QR toda vez; - reconecta sozinho se a conexão cair;
- ignora grupos e as próprias mensagens;
- responde
1e2com o texto da opção e qualquer outra mensagem com o menu.
Para mudar as respostas, edite o objeto RESPOSTAS.
4. Conecte o número
Rode o bot pela primeira vez:
node bot.js
Vai aparecer um QR code no terminal. No celular, abra o WhatsApp → Aparelhos conectados → Conectar um aparelho e leia o QR.
Quando aparecer ✅ Bot conectado, mande "oi" de outro número para testar. O bot responde com o menu. Depois, aperte Ctrl + C para parar: no próximo passo ele volta a rodar em segundo plano.
5. Deixe rodando 24h com PM2
O PM2 mantém o bot ligado, reinicia se ele travar e liga de novo quando a VPS reiniciar:
npm install -g pm2
pm2 start bot.js --name bot-whatsapp
pm2 save
pm2 startup
O pm2 startup mostra um comando na tela. Copie e rode esse comando para o bot subir junto com o servidor.
Comandos úteis no dia a dia:
| Comando | Para que serve |
|---|---|
pm2 logs bot-whatsapp |
ver o que o bot está fazendo |
pm2 restart bot-whatsapp |
reiniciar depois de editar o bot.js |
pm2 status |
conferir se está online |
Problemas comuns
O QR some antes de eu conseguir ler. O QR muda a cada poucos segundos. Espere o próximo aparecer e leia de novo.
Apareceu "Sessão encerrada". O aparelho foi desconectado pelo celular. Rode pm2 stop bot-whatsapp, apague a pasta com rm -rf /opt/bot/sessao, rode node bot.js, leia o QR de novo e volte com pm2 restart bot-whatsapp.
O bot parou de responder depois de um tempo. Veja os logs com pm2 logs bot-whatsapp. Se a VPS ficou sem memória, free -m mostra. Um bot simples usa pouco, mas se você somar banco de dados e outros serviços, pode ser hora de uma máquina maior.
Próximos passos
Com o bot no ar, dá para ir além: buscar respostas num banco de dados, encaminhar para um atendente humano, ou ligar o bot a um fluxo do n8n. Se for usar o n8n, veja o nosso tutorial de como instalar o n8n numa VPS com Docker e HTTPS.
Onde rodar
Na NullNinja, o VPS Start custa R$ 54,98/mês, com 1 vCPU, 2 GB de RAM, 20 GB NVMe, acesso root e IP fixo incluso, em datacenter em São Paulo. É mensal, sem fidelidade e com reembolso integral em até 7 dias.
Travou em algum passo? Chama no WhatsApp: (65) 99233-0983.