Uma biblioteca de alto nível (wrapper) robusta e resiliente para a Baileys. Facilita a criação e o gerenciamento de conexões com o WhatsApp, oferecendo uma arquitetura baseada em eventos unificados, normalização de mensagens para estruturas ricas e handlers especializados para simplificar a lógica de negócio do seu bot.
- 🚀 Simplificação do Ciclo de Vida: Conexão auto-gerenciável, tratamento automático de desconexões e reconexão inteligente.
- 📩 Estrutura de Mensagens Ricas: Mensagens recebidas são completamente normalizadas em objetos JavaScript amigáveis, contendo helpers para baixar mídias, verificar menções, respostas, reações e votos.
- 🛠️ Handlers Especializados: Módulos desacoplados para gerenciar Mensagens, Grupos, Contatos, Usuários, Newsletters, Chamadas e Stories.
- 🔘 Mensagens Interativas de Última Geração: Suporte nativo para construir e enviar botões interativos (
Quick Reply,URL,Copy Code,Call,Location) e menus de lista de seleção única (List Buttons). - 📂 Multi-Sessão Nativa: Persistência de estado de autenticação simplificada e isolamento seguro por sessão.
Instale o pacote através do npm:
npm install @areumtecnologia/unitychatAqui está um exemplo básico de como inicializar o cliente, escutar eventos e interagir com mensagens:
const { UnityChat, Events } = require('@areumtecnologia/unitychat');
// Inicializa o cliente com configurações personalizadas
const client = new UnityChat({
sessionName: 'sessao-suporte',
printQRInTerminal: true,
restartOnClose: true
});
// Evento disparado quando a conexão com o WhatsApp está pronta
client.on(Events.CONNECTED, (user) => {
console.log(`✅ Conectado com sucesso como: ${user.name} (${user.id})`);
});
// Escuta novas mensagens recebidas
client.on(Events.MESSAGE_RECEIVED, async (message) => {
console.log(`📩 Nova mensagem de ${message.fromPushName} (${message.from}): ${message.body}`);
// Exemplo de resposta simples
if (message.body === '!ping') {
await client.messages.sendTextMessage(message.from, 'pong! 🏓');
}
// Se a mensagem contiver mídia (imagem, áudio, etc)
if (message.hasMedia && message.media) {
console.log(`Mídia recebida do tipo: ${message.media.mimetype}`);
// Baixa a mídia usando o helper integrado
const attachments = await message.media.getAttachments();
const base64Data = attachments.toBase64();
console.log(`Tamanho do buffer de mídia: ${attachments.buffer.length} bytes`);
}
});
// Trata erros ou desconexões inesperadas
client.on(Events.ERROR, (error) => {
console.error('❌ Ocorreu um erro no cliente:', error);
});
// Inicia o processo de conexão
client.connect();Ao instanciar a classe UnityChat, você pode customizar o comportamento da conexão passando as seguintes opções no construtor:
| Opção | Tipo | Padrão | Descrição |
|---|---|---|---|
sessionName |
string |
'session' |
Identificador único da sessão para isolar dados de autenticação. |
dataPath |
string |
'data/sessions' |
Caminho base onde as credenciais das sessões serão persistidas. |
printQRInTerminal |
boolean |
false |
Se true, imprime o QR code para autenticação diretamente no console. |
loggerLevel |
string |
'error' |
Nível do log interno (ex: 'debug', 'info', 'warn', 'error'). |
restartOnClose |
boolean |
false |
Tenta restabelecer a conexão automaticamente caso ocorra uma queda de rede/serviço. |
markOnlineOnConnect |
boolean |
false |
Mantém o status do bot como "Online" logo após conectar. |
environment |
Array |
['Mac OS', 'Chrome', '144.0.7559.110'] |
Array customizado para simular a plataforma do navegador da sessão. |
waVersion |
Array |
null |
Sobrescreve a versão padrão do WhatsApp Web (Array de 3 números). |
store |
object |
MessageStore |
Instância customizada para leitura e gravação em cache/banco de mensagens. |
A classe UnityChat disponibiliza diversos métodos principais para gerenciar o ciclo de vida da conexão, obter informações do bot e realizar operações auxiliares:
connect():- Retorno:
Promise<void> - Descrição: Inicializa as credenciais de autenticação da sessão, configura o socket e inicia a conexão aos servidores do WhatsApp. Gerencia reconexões e novas tentativas de pareamento automaticamente.
- Retorno:
disconnect():- Retorno:
void - Descrição: Encerra a conexão socket ativa com o WhatsApp de forma limpa, definindo internamente a flag de desconexão manual para evitar novas conexões automáticas. Não apaga credenciais locais.
- Retorno:
logout():- Retorno:
Promise<void> - Descrição: Realiza o logout da conta conectada no WhatsApp e encerra o socket de conexão, invalidando a sessão.
- Retorno:
itsMe():- Retorno:
Promise<object> - Descrição: Retorna o perfil normalizado do próprio bot conectado (contendo informações de perfil, grupos e newsletters participantes).
- Retorno:
composing(jid, ts):- Parâmetros:
jid(string),ts(number) - Retorno:
Promise<void> - Descrição: Aciona visualmente o estado "digitando..." para o destinatário especificado pelo
jid.
- Parâmetros:
getMessages(jid, limit):- Parâmetros:
jid(string),limit(number, padrão50) - Retorno:
Promise<Array> - Descrição: Recupera o histórico local ou remoto de mensagens brutas associadas a um chat.
- Parâmetros:
decryptPollVote(vote, voteParams):- Parâmetros:
vote(object),voteParams(object) - Retorno:
Promise<object> - Descrição: Descriptografa votos recebidos em enquetes.
- Parâmetros:
getAggregateVotesInPollMessage(pollParams):- Parâmetros:
pollParams(object) - Retorno:
Promise<object> - Descrição: Agrega e contabiliza os votos descriptografados de uma enquete.
- Parâmetros:
getAggregateResponsesInEventMessage(eventParams):- Parâmetros:
eventParams(object) - Retorno:
Promise<object> - Descrição: Analisa e decodifica as presenças/respostas a um evento criado no chat.
- Parâmetros:
jidNormalizedUser(id):- Parâmetros:
id(string) - Retorno:
string - Descrição: Normaliza e unifica IDs do WhatsApp, removendo identificadores secundários de múltiplos dispositivos.
- Parâmetros:
downloadContentFromMessage(content, type):- Parâmetros:
content(object),type(string) - Retorno:
Promise<Buffer> - Descrição: Efetua o download binário de um anexo ou mídia de uma mensagem bruta.
- Parâmetros:
getContentType(message):- Parâmetros:
message(object) - Retorno:
string - Descrição: Retorna o tipo de conteúdo de uma mensagem bruta (ex:
text,image).
- Parâmetros:
A classe UnityChat herda do EventEmitter do Node.js e emite eventos semânticos correspondentes ao ciclo de vida da aplicação:
init: Iniciando o processo de carregamento de credenciais.connecting: Tentando estabelecer conexão de socket com os servidores do WhatsApp.status_change: Disparado quando ocorre mudança no status geral do cliente.pairing_code: QR Code gerado. Retorna um objeto contendo{ base64, qr, attempts }.pairing_success: QR Code escaneado com sucesso e login concluído.connected: Conexão estabelecida e autenticação pronta. Retorna o perfil do bot normalizado.disconnected: Desconectado dos servidores. Retorna{ statusCode, statusType, reason, details }.
message_received: Nova mensagem recebida do usuário (Normalizada).message_sent: Mensagem enviada pelo próprio bot (Normalizada).message_update: Mensagem editada ou atualizada no chat (Ex: recebimento de confirmações).message_delete: Mensagem excluída da conversa.message_reaction: Reação com emoji recebida/enviada.messages_history_sync_done: Sincronização de histórico concluída com sucesso.broadcast_message: Mensagem recebida via lista de transmissão ou Status.notification: Notificação interna de sistema ou protocolo.
incoming_call: Nova chamada de voz/vídeo recebida pelo número.presence_update: Mudança no status de presença de contatos (digitando, gravando, online).contacts_upsert/contacts_update: Atualizações na lista ou metadados de contatos.groups_upsert/groups_update: Criação ou alteração de informações nos grupos participantes.group_participants_update: Mudanças nos membros de um grupo (entrada, saída, promoções).group_member_tag_update: Atualização de etiquetas/papéis dos membros do grupo.blocklist_update: Atualização na lista de contatos bloqueados.chat_update/chat_delete: Modificações em chats locais da conta.
Todas as mensagens emitidas nos eventos message_received e message_sent são processadas através do MessageNormalizer, gerando um objeto padronizado com a seguinte estrutura:
{
id: "3EB0...", // Identificador único da mensagem
chat: { // Objeto de contato normalizado associado ao chat
id: "559199999999@s.whatsapp.net",
name: "João Silva",
type: "personal" // 'personal' | 'business' | 'group' | 'newsletter'
},
fromMe: false, // Define se a mensagem partiu do bot
from: "559199999999@...", // Quem enviou a mensagem
fromPushName: "João", // Nome de exibição configurado no perfil do emissor
to: "559188888888@...", // Destinatário da mensagem
type: "text", // Tipo amigável ('text', 'image', 'audio', 'document', 'sticker', 'location', 'contact', 'interactive_reply', etc)
body: "Olá, mundo!", // Corpo de texto principal extraído da mensagem
hasMedia: false, // Flag indicando a presença de mídia para download
media: null, // Objeto com metadados de mídia (caso hasMedia seja true)
location: null, // Objeto contendo { latitude, longitude } para mensagens de localização
contacts: [], // Lista de contatos formatados se recebido um vCard
isReply: false, // Indica se é uma resposta citada (quoted)
quotedMessage: null, // Mensagem citada recursivamente normalizada
isForwarded: false, // Indica se a mensagem foi encaminhada
mentions: [], // Lista de JIDs mencionados na mensagem
isMentioningMe: false, // Indica se o JID do próprio bot foi mencionado
isEdited: false, // Se a mensagem foi editada posteriormente
interactiveReply: null, // ID e texto do botão clicado caso seja uma resposta interativa
reaction: null, // Estrutura de emoji e timestamp caso seja reação
poll: null, // Dados de criação de enquete
pollUpdate: null, // Votos decodificados recebidos em enquetes
timestamp: Date, // Objeto Date representando quando a mensagem foi criada
raw: { ... } // Objeto bruto original fornecido pela Baileys (útil para uso avançado)
}Quando hasMedia é true, você pode acessar message.media.getAttachments() para obter um conjunto de helpers utilitários para manipulação do buffer:
const attachments = await message.media.getAttachments();
attachments.mimetype; // Mimetype do arquivo (ex: 'image/png')
attachments.extension; // Extensão sugerida (ex: 'png')
attachments.buffer; // Buffer binário completo do arquivo
// Métodos utilitários:
attachments.toBase64(); // Converte para String Base64
attachments.toDataUri(); // Retorna formato Data URI
attachments.toArrayBuffer(); // Retorna ArrayBuffer
await attachments.save(caminho);// Grava a mídia em um caminho local e retorna o nome e arquivo.A biblioteca separa responsabilidades organizando seus recursos em handlers acessíveis diretamente pela instância do client.
Responsável por todas as operações de envio, respostas, download e modificações de mensagens nos chats.
sendMessage(jid, content, options): Envia um payload bruto customizado da Baileys para o JID especificado.- Opções especiais:
{ composing: { timeout: MS } }ou{ recording: { timeout: MS } }simula o estado "digitando" ou "gravando áudio" porMSmilissegundos antes de enviar a mensagem.
- Opções especiais:
sendTextMessage(jid, text, options): Envia uma mensagem de texto simples.reply(originalMessage, content): Responde (marcando e citando) a uma mensagem recebida.sendImage(jid, media, caption, options): Envia uma imagem (parâmetromediaaceita URL pública ou Buffer).- Opção:
{ viewOnce: true }para envio temporário.
- Opção:
sendVideo(jid, media, caption, options): Envia um vídeo (parâmetromediaaceita URL ou Buffer).- Opção:
{ viewOnce: true }para visualização única.
- Opção:
sendAudio(jid, media, ptt, options): Envia um áudio. Definaptt: truepara simular gravação de mensagem de voz no WhatsApp.sendDocument(jid, media, mimetype, fileName, caption, options): Envia um arquivo/documento genérico.sendLocation(jid, latitude, longitude, name, address): Envia uma mensagem contendo pin de mapa.sendContacts(jid, contacts): Envia cartões de contatos estruturados (vCards). O parâmetrocontactsé um array de objetos{ fullName, waid, organization }.sendPoll(jid, pollName, pollValues, options): Cria uma enquete com opções de voto.sendLink(jid, url, options): Envia um link ativando a renderização prévia de metadados da URL (preview).forwardMessage(jid, messageToForward): Encaminha uma mensagem existente para outro chat.editMessage(originalMessageKey, newText): Edita o texto de uma mensagem anteriormente enviada pelo bot.react(messageKey, emoji): Adiciona uma reação com emoji a uma mensagem.delete(messageKey): Apaga uma mensagem enviada pelo bot para todos os participantes do chat.read(messageKey): Envia a confirmação de leitura da mensagem.composing(jid, ts): Aciona o estado "digitando..." para o destinatário JID.getMessages(jid, limit): Busca o histórico local ou remoto de mensagens de um chat (limite padrão de 50 mensagens).getAttachments(message): Efetua o download e retorna helpers para a mídia contida em um payload de mensagem bruto.
Contém as operações de criação, modificação de metadados e moderação de membros em grupos.
getMetadata(groupId): Retorna as configurações e lista de participantes ativos em um grupo. Utiliza cache integrado de 5 minutos.getAllGroups(): Retorna uma lista com todos os grupos que o bot faz parte.getProfilePicture(jid): Obtém o link público para a foto de perfil do grupo.create(subject, participantsJids): Cria um novo grupo.leave(groupId): Sai de um grupo.updateName(groupId, newName): Altera o título de exibição de um grupo.updateDescription(groupId, newDescription): Atualiza a descrição textual do grupo.updateParticipants(groupId, participantsJids, action): Gerencia membros. Valores aceitos para a ação:'add' | 'remove' | 'promote' | 'demote'.addParticipants(groupId, participantsJids): Atalho direto para adicionar novos membros.removeParticipants(groupId, participantsJids): Atalho direto para remover membros.promoteParticipants(groupId, participantsJids): Concede privilégios de administrador do grupo a membros específicos.demoteParticipants(groupId, participantsJids): Retira os privilégios de administrador de membros específicos.getInviteCode(groupId): Retorna o sufixo alfanumérico do link de convite do grupo.revokeInviteCode(groupId): Invalida o código/link de convite antigo e gera um novo.updateMemberLabel(groupId, label): Define a etiqueta/papel de membro próprio do bot no grupo.
Handlers focados no gerenciamento de contatos, privacidade e metadados de contas pessoais ou comerciais.
getMetadata(jid): Retorna dados estruturados de um contato (nome, foto, tipo).getStatus(id): Retorna a frase de "Recado" cadastrada no perfil do contato.getPnForLid(lid): Retorna o JID convencional (baseado em número de telefone) associado a um identificador interno LID do WhatsApp.getMyStatus(): Retorna o status de "Recado" da conta do bot.getBusinessProfile(jid): Retorna dados comerciais adicionais se for uma conta comercial (descrição, endereço, e-mail, etc).getProfilePicture(jid): Obtém a imagem de exibição do usuário.isOnWhatsApp(number): Verifica se um número de telefone está cadastrado no WhatsApp (normalizando DDI e o nono dígito).updateProfileName(newName): Atualiza o nome de perfil público da conta do bot.updateProfileStatus(newStatus): Atualiza a frase de recado da conta do bot.block(jid)/unblock(jid): Bloqueia ou desbloqueia um contato.getBlocklist(): Retorna todos os contatos bloqueados pela conta do bot.sendPresence(jid, presenceStatus): Atualiza a presença visível do bot em relação a um chat (valores doPresenceStatus:'available','unavailable','composing','recording').updateLastSeenPrivacy(value): Atualiza configuração de privacidade do Visto por Último ('all' | 'contacts' | 'contact_blacklist' | 'none').updateOnlinePrivacy(value): Atualiza configuração de privacidade do Visto Online ('all' | 'match_last_seen').updateReadReceiptsPrivacy(value): Atualiza configuração de privacidade das confirmações de leitura ('all' | 'none').
get(jid): Recupera um contato diretamente do cache local em memória.getAll(): Retorna todos os contatos presentes no cache em memória.set(jid, contact): Adiciona ou atualiza manualmente um contato na estrutura de cache do cliente.normalize(message): Efetua varredura na mensagem para extrair, carregar metadados externos (como imagem de perfil e status) e formatar um contato estruturado.
Permite a interação básica de leitura e criação de Canais do WhatsApp.
getMetadata(id): Retorna metadados de um Canal através do ID ou link de convite.getAllNewsletters(): Retorna a lista de canais nos quais o bot está inscrito.follow(id)/unfollow(id): Inscreve-se ou cancela a inscrição em um canal.mute(jid, duration)/unmute(jid): Configura silenciamento de notificações do canal.create(name, description, picture): Cria um novo canal próprio do bot.delete(jid): Exclui permanentemente um canal criado pelo bot.updateName(jid, name): Atualiza o nome do canal.updateDescription(jid, description): Altera a descrição do canal.updatePicture(jid, picture): Atualiza o avatar do canal.update(jid, { name, description, picture }): Método utilitário para atualizar múltiplos dados ao mesmo tempo.updateReactionMode(jid, mode): Configura a regra de reações em posts do canal. Valores:'ALL' | 'BASIC' | 'NONE'.
reject(call): Recusa uma chamada telefônica de voz/vídeo recebida pelo bot.
Responsável por enviar, gerenciar e excluir publicações de Stories (Status) no WhatsApp.
send(jids, content, options): Envia uma publicação de stories para uma lista de contatos.jids: Array de JIDs que receberão ou serão mencionados nos stories.content: Conteúdo da mensagem a ser enviada (texto, imagem, vídeo, etc.).- Opções:
sendMentions(boolean): Setrue, realiza a menção nos stories (limita o array de JIDs a no máximo 5 elementos devido a restrições do WhatsApp).backgroundColor(string): Cor de fundo para os stories de texto (padrão:'#288d7c85').font(number): Estilo de fonte para os stories de texto (padrão:1).
delete(msg): Exclui uma publicação de stories enviada anteriormente.
Gerenciamento de Etiquetas do WhatsApp Business.
createLabel(name, color): Cria uma etiqueta com nome e cor especificados (cores de 0 a 19).updateLabel(id, name, color): Atualiza o nome e a cor de uma etiqueta existente.deleteLabel(id): Remove permanentemente uma etiqueta da conta comercial.addChatLabel(jid, labelId): Associa uma etiqueta a uma conversa.removeChatLabel(jid, labelId): Remove a etiqueta de uma conversa.addMessageLabel(jid, msgId, labelId): Associa uma etiqueta a uma mensagem específica.removeMessageLabel(jid, msgId, labelId): Remove a etiqueta de uma mensagem específica.
Gerenciamento de recursos comerciais (Catálogo, Produtos, Perfil e Capa Comercial).
updateBusinessProfile(profile): Atualiza endereço, e-mail, websites, descrição e horários do perfil comercial do bot.updateCoverPhoto(path): Define ou altera a foto de capa comercial (URL ou Buffer).removeCoverPhoto(coverPhotoId): Remove a foto de capa comercial atual.getCatalog(options): Busca a lista de produtos de um contato comercial ou do próprio bot.getCollections(jid, count): Retorna as coleções de produtos do catálogo de um contato.getOrderDetails(orderId, orderToken): Obtém os detalhes completos de um pedido a partir do carrinho.productCreate(product): Adiciona um novo produto ao catálogo comercial.productUpdate(productId, product): Atualiza os dados de um produto existente.productDelete(productIds): Exclui permanentemente produtos do catálogo (aceita array de IDs).
A biblioteca disponibiliza classes auxiliares estruturadas para a criação de mensagens interativas avançadas com facilidade.
Gera botões de clique rápido que enviam o texto correspondente de volta ao chat ao serem tocados.
const { InteractiveMessage, QuickReplyButton } = require('@areumtecnologia/unitychat');
const message = new InteractiveMessage()
.withText('Olá! Escolha uma das opções abaixo:')
.withFooter('Responda clicando em um dos botões')
.addButton(new QuickReplyButton('id_opcao_1', 'Falar com Atendente'))
.addButton(new QuickReplyButton('id_opcao_2', 'Ver Menu Principal'));
await client.messages.sendMessage(jid, message.build());Exibe botões especiais para direcionamento para sites externos, chamadas de voz normais da operadora, cópia de códigos PIX/Cupons e compartilhamento de localização:
const { InteractiveMessage, UrlButton, CopyCodeButton, CallButton, LocationButton } = require('@areumtecnologia/unitychat');
const message = new InteractiveMessage()
.withText('Aqui estão seus links especiais:')
.addButton(new UrlButton('Acessar Site', 'https://unitychat.areum.com.br'))
.addButton(new CopyCodeButton('Copiar Código PIX', 'pix-payload-key-12345'))
.addButton(new CallButton('Ligar para o Suporte', '559199999999'))
.addButton(new LocationButton('Compartilhar Localização'));
await client.messages.sendMessage(jid, message.build());Gera botões interativos para pagamento PIX estático e faturamento integrado de checkout:
const { InteractiveMessage, PixButton, CheckoutButton } = require('@areumtecnologia/unitychat');
// Exemplo 1: Botão PIX Estático
const pixMessage = new InteractiveMessage()
.withText('Efetue o pagamento via PIX clicando no botão abaixo:')
.addButton(new PixButton('Áreum Tecnologia LTDA', 'financeiro@areum.com.br', 'EMAIL'));
await client.messages.sendMessage(jid, pixMessage.build());
// Exemplo 2: Checkout / Faturamento
const checkoutMessage = new InteractiveMessage()
.withText('Fatura gerada com sucesso!')
.addButton(new CheckoutButton({
currency: 'BRL',
totalAmount: { value: '15000', offset: '100' },
referenceId: 'REF_PEDIDO_12345',
items: [{
retailer_id: 'item_01',
name: 'Licença Anual WaSockets',
amount: { value: '15000', offset: '100' },
quantity: '1'
}],
additionalNote: 'Agradecemos a sua preferência!'
}));
await client.messages.sendMessage(jid, checkoutMessage.build());Permite enviar uma lista completa dividida por seções para seleções únicas:
const { InteractiveMessage, ListButton, ListSection, ListRow } = require('@areumtecnologia/unitychat');
const listMenu = new InteractiveMessage()
.withText('Selecione o produto de interesse:')
.withFooter('Escolha uma das linhas abaixo')
.addButton(
new ListButton('Ver Catálogo')
.addSection(
new ListSection('Aparelhos Celulares')
.addRow(new ListRow('iphone_15', 'iPhone 15 Pro', 'Mais recente lançamento Apple'))
.addRow(new ListRow('s24_ultra', 'Galaxy S24 Ultra', 'Processador Snapdragon e AI integrada'))
)
.addSection(
new ListSection('Acessórios')
.addRow(new ListRow('airpods_3', 'AirPods 3', 'Áudio espacial de alta qualidade'))
)
);
await client.messages.sendMessage(jid, listMenu.build());Este projeto está licenciado sob a licença ISC. Consulte o arquivo LICENSE para obter detalhes.
Desenvolvido com carinho por Áreum Tecnologia.