Pular para o conteúdo principal

Como Substituir o Baileys pelo whatsmeow-node Como Substituir o Baileys pelo whatsmeow-node

Como Substituir o Baileys pelo whatsmeow-node

Se você usa o Baileys e está enfrentando problemas de manutenção, instabilidade de forks ou quer um upstream mais confiável, o whatsmeow-node é uma alternativa direta com uma superfície de API similar. Este guia mapeia os conceitos-chave e mostra como migrar.

Por Que Migrar?

  • Upstream estável — o whatsmeow é mantido pelo time Mautrix e usado em produção por milhares de bridges Matrix 24/7. Quando o WhatsApp muda o protocolo, as correções chegam rápido.
  • Sem roleta de forks — o Baileys já passou por múltiplos forks (adiwajshing, WhiskeySockets, outros). O whatsmeow-node encapsula uma única biblioteca Go estável.
  • Menos memória — ~10-20 MB vs ~50 MB típicos do Baileys.
  • API tipada — mais de 100 métodos async tipados com design TypeScript-first.

Veja a Comparação com Alternativas para mais detalhes.

Passo 1: Instalar

# Remove Baileys
npm uninstall @whiskeysockets/baileys

# Install whatsmeow-node
npm install @whatsmeow-node/whatsmeow-node

Passo 2: Atualizar a Inicialização do Client

Baileys

import makeWASocket, { useMultiFileAuthState } from "@whiskeysockets/baileys";

const { state, saveCreds } = await useMultiFileAuthState("auth_info");
const sock = makeWASocket({ auth: state });
sock.ev.on("creds.update", saveCreds);

whatsmeow-node

import { createClient } from "@whatsmeow-node/whatsmeow-node";

const client = createClient({ store: "session.db" });
const { jid } = await client.init();
await client.connect();

A persistência da sessão é automática — não precisa de callback saveCreds. A opção store aceita um caminho de arquivo (SQLite) ou uma string de conexão PostgreSQL.

informação

Você precisará parear novamente (escanear QR code) após a troca. O estado de autenticação do Baileys não é compatível com sessões do whatsmeow.

Passo 3: Atualizar os Listeners de Eventos

Mensagens

Baileys:

sock.ev.on("messages.upsert", ({ messages }) => {
for (const msg of messages) {
if (msg.key.fromMe) continue;
const text = msg.message?.conversation
?? msg.message?.extendedTextMessage?.text;
console.log(`${msg.pushName}: ${text}`);
}
});

whatsmeow-node:

client.on("message", ({ info, message }) => {
if (info.isFromMe) return;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
console.log(`${info.pushName}: ${text}`);
});

Diferenças principais:

  • Uma mensagem por evento (sem batch)
  • Metadados da mensagem ficam em info, conteúdo protobuf fica em message
  • info.isFromMe substitui msg.key.fromMe
  • info.chat substitui msg.key.remoteJid
  • info.sender substitui msg.key.participant (em grupos)

Conexão

Baileys:

sock.ev.on("connection.update", ({ connection, lastDisconnect }) => {
if (connection === "open") console.log("Connected!");
if (connection === "close") { /* handle reconnection */ }
});

whatsmeow-node:

client.on("connected", ({ jid }) => console.log(`Connected as ${jid}`));
client.on("disconnected", () => console.log("Disconnected"));
client.on("logged_out", ({ reason }) => console.error(`Logged out: ${reason}`));

Você não precisa de lógica manual de reconexão — o whatsmeow faz isso automaticamente.

Passo 4: Atualizar o Envio de Mensagens

Mensagem de texto

Baileys:

await sock.sendMessage(jid, { text: "Hello!" });

whatsmeow-node:

await client.sendMessage(jid, { conversation: "Hello!" });

Resposta com citação

Baileys:

await sock.sendMessage(jid, { text: "Reply!" }, { quoted: msg });

whatsmeow-node:

await client.sendRawMessage(jid, {
extendedTextMessage: {
text: "Reply!",
contextInfo: {
stanzaId: info.id,
participant: info.sender,
quotedMessage: { conversation: originalText },
},
},
});

Mídia

Baileys:

await sock.sendMessage(jid, {
image: { url: "/path/to/photo.jpg" },
caption: "Check this out",
});

whatsmeow-node:

const media = await client.uploadMedia("/path/to/photo.jpg", "image");
await client.sendRawMessage(jid, {
imageMessage: {
URL: media.URL,
directPath: media.directPath,
mediaKey: media.mediaKey,
fileEncSHA256: media.fileEncSHA256,
fileSHA256: media.fileSHA256,
fileLength: String(media.fileLength),
mimetype: "image/jpeg",
caption: "Check this out",
},
});

O upload e o envio de mídia são etapas separadas no whatsmeow-node. Isso dá mais controle (ex.: fazer upload uma vez, enviar para vários chats).

Reações

Baileys:

await sock.sendMessage(jid, { react: { text: "👍", key: msg.key } });

whatsmeow-node:

await client.sendReaction(jid, senderJid, messageId, "👍");

Passo 5: Atualizar Operações de Grupo

Baileyswhatsmeow-node
sock.groupCreate(name, members)client.createGroup(name, members)
sock.groupMetadata(jid)client.getGroupInfo(jid)
sock.groupFetchAllParticipating()client.getJoinedGroups()
sock.groupUpdateSubject(jid, name)client.setGroupName(jid, name)
sock.groupUpdateDescription(jid, desc)client.setGroupDescription(jid, desc)
sock.groupSettingUpdate(jid, "announcement")client.setGroupAnnounce(jid, true)
sock.groupParticipantsUpdate(jid, [jid], "add")client.updateGroupParticipants(jid, [jid], "add")
sock.groupInviteCode(jid)client.getGroupInviteLink(jid)
sock.groupLeave(jid)client.leaveGroup(jid)

Referência Rápida de API

Baileyswhatsmeow-node
makeWASocket()createClient()
sock.sendMessage(jid, content)client.sendMessage(jid, content)
sock.readMessages([key])client.markRead([id], chat, sender)
sock.sendPresenceUpdate("available")client.sendPresence("available")
sock.presenceSubscribe(jid)client.subscribePresence(jid)
sock.profilePictureUrl(jid)client.getProfilePicture(jid)
sock.updateBlockStatus(jid, "block")client.updateBlocklist(jid, "block")
sock.logout()client.logout()

Checklist de Migração

  • Instalar @whatsmeow-node/whatsmeow-node, remover @whiskeysockets/baileys
  • Substituir makeWASocket por createClient
  • Remover useMultiFileAuthState — a sessão é tratada automaticamente
  • Atualizar listeners de eventos (ev.on por client.on, nomes de eventos diferentes)
  • Atualizar chamadas de sendMessage (text por conversation)
  • Atualizar envio de mídia (etapas separadas de upload + envio)
  • Atualizar operações de grupo (nomes dos métodos diferem levemente)
  • Remover lógica manual de reconexão — o whatsmeow reconecta automaticamente
  • Parear novamente via QR code (nova sessão necessária)
  • Testar todos os tipos de mensagem de ponta a ponta

Erros Comuns

Nova sessão necessária

O estado de autenticação do Baileys não pode ser migrado. Você precisa parear uma nova sessão escaneando o QR code. Seu histórico de conversas e contatos do WhatsApp não são afetados — apenas o vínculo do dispositivo é novo.

text vs conversation

O Baileys usa { text: "..." } para mensagens. O whatsmeow-node usa { conversation: "..." } — seguindo o nome do campo protobuf do WhatsApp.

Casing dos campos proto

Os campos da resposta do upload usam o casing exato do protobuf: URL, fileSHA256, fileEncSHA256não camelCase. Usar o casing errado falha silenciosamente.