
Como Encaminhar Mensagens do WhatsApp Programaticamente
Encaminhe mensagens entre chats do WhatsApp usando sendRawMessage(). Você pode encaminhar texto, mídia, enquetes e qualquer outro tipo de mensagem — com ou sem o rótulo "Encaminhada".
Pré-requisitos
- Uma sessão pareada do whatsmeow-node (Como Parear)
Encaminhar uma Mensagem de Texto
Para encaminhar uma mensagem recebida para outro chat, passe-a via sendRawMessage com a flag isForwarded:
const targetJid = "5598765432@s.whatsapp.net";
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
if (!text) return;
// Forward as a new message with the "Forwarded" label
await client.sendRawMessage(targetJid, {
extendedTextMessage: {
text,
contextInfo: {
isForwarded: true,
forwardingScore: 1,
},
},
});
});
A flag isForwarded: true exibe o rótulo "Encaminhada" na mensagem. O forwardingScore rastreia quantas vezes a mensagem foi encaminhada — o WhatsApp mostra "Encaminhada com frequência" quando atinge 4+.
Encaminhar Sem o Rótulo "Encaminhada"
Para repassar uma mensagem sem o rótulo de encaminhamento, simplesmente envie como uma mensagem nova:
// Send as if it's a new message — no forwarding label
await client.sendMessage(targetJid, { conversation: text });
Encaminhar Mensagens de Mídia
Mensagens de mídia (imagens, vídeos, documentos) podem ser encaminhadas passando o conteúdo original da mensagem. A mídia já está hospedada nos servidores do WhatsApp, então não é necessário reenviar:
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
// Forward images
if (message.imageMessage) {
await client.sendRawMessage(targetJid, {
imageMessage: {
...message.imageMessage,
contextInfo: {
isForwarded: true,
forwardingScore: 1,
},
},
});
return;
}
// Forward videos
if (message.videoMessage) {
await client.sendRawMessage(targetJid, {
videoMessage: {
...message.videoMessage,
contextInfo: {
isForwarded: true,
forwardingScore: 1,
},
},
});
return;
}
// Forward documents
if (message.documentMessage) {
await client.sendRawMessage(targetJid, {
documentMessage: {
...message.documentMessage,
contextInfo: {
isForwarded: true,
forwardingScore: 1,
},
},
});
return;
}
});
Encaminhar Qualquer Tipo de Mensagem
Uma função genérica que encaminha qualquer mensagem detectando o tipo:
const MESSAGE_TYPES = [
"conversation",
"extendedTextMessage",
"imageMessage",
"videoMessage",
"audioMessage",
"documentMessage",
"stickerMessage",
"contactMessage",
"locationMessage",
"pollCreationMessage",
] as const;
async function forwardMessage(
targetJid: string,
message: Record<string, unknown>,
showForwarded = true,
) {
for (const type of MESSAGE_TYPES) {
if (!(type in message)) continue;
if (type === "conversation") {
// Simple text — wrap in extendedTextMessage for contextInfo support
await client.sendRawMessage(targetJid, {
extendedTextMessage: {
text: message.conversation as string,
...(showForwarded && {
contextInfo: { isForwarded: true, forwardingScore: 1 },
}),
},
});
} else {
// Structured message — spread and add contextInfo
const content = message[type] as Record<string, unknown>;
await client.sendRawMessage(targetJid, {
[type]: {
...content,
...(showForwarded && {
contextInfo: {
...(content.contextInfo as Record<string, unknown> ?? {}),
isForwarded: true,
forwardingScore: 1,
},
}),
},
});
}
return;
}
}
Criar um Bot Relay
Encaminhe todas as mensagens de um grupo para outro:
const SOURCE_GROUP = "120363XXXXX@g.us";
const TARGET_GROUP = "120363YYYYY@g.us";
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
if (info.chat !== SOURCE_GROUP) return;
// Add sender attribution
const attribution = `[${info.pushName}]:\n`;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
if (text) {
await client.sendMessage(TARGET_GROUP, {
conversation: `${attribution}${text}`,
});
return;
}
// Forward media with caption attribution
await forwardMessage(TARGET_GROUP, message);
});
Exemplo Completo
Um bot relay que encaminha mensagens entre um chat privado e um grupo:
import { createClient } from "@whatsmeow-node/whatsmeow-node";
const client = createClient({ store: "session.db" });
// Forward messages FROM this chat TO the group
const PRIVATE_CHAT = "5512345678@s.whatsapp.net";
const GROUP_CHAT = "120363XXXXX@g.us";
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
// Private → Group
if (info.chat === PRIVATE_CHAT && text) {
await client.sendMessage(GROUP_CHAT, {
conversation: `[${info.pushName}]: ${text}`,
});
return;
}
// Group → Private
if (info.chat === GROUP_CHAT && text) {
await client.sendMessage(PRIVATE_CHAT, {
conversation: `[${info.pushName} in group]: ${text}`,
});
return;
}
});
async function main() {
const { jid } = await client.init();
if (!jid) {
console.error("Not paired!");
process.exit(1);
}
await client.connect();
await client.sendPresence("available");
console.log("Relay bot is online!");
process.on("SIGINT", async () => {
await client.sendPresence("unavailable");
await client.disconnect();
client.close();
process.exit(0);
});
}
main().catch(console.error);
Erros Comuns
Se você encaminha mensagens de um chat e também ouve o chat de destino, pode criar um loop infinito. Sempre verifique o chat de origem e ignore suas próprias mensagens.
As URLs de mídia do WhatsApp expiram após algum tempo. Se você salvar uma mensagem e tentar encaminhá-la muito depois, a mídia pode não estar mais disponível. Encaminhe mídia rapidamente ou baixe-a primeiro com downloadAny().
Encaminhar muitas mensagens rapidamente vai atingir os rate limits do WhatsApp. Espaçe os envios, especialmente para operações de relay em massa. Veja Rate Limiting.





