0

Como criar um bot de WhatsApp que roda 24h numa VPS com Node.js (passo a passo)

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 1 e 2 com 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:

ComandoPara que serve
pm2 logs bot-whatsappver o que o bot está fazendo
pm2 restart bot-whatsappreiniciar depois de editar o bot.js
pm2 statusconferir 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.


Escrevi esse passo a passo para o blog da NullNinja, uma hospedagem brasileira (VPS com IP fixo e datacenter em São Paulo). Se travar em alguma etapa, comenta aqui que eu ajudo.

Carregando publicação patrocinada...