Como criar um bot de Sticker para o Whatsapp 📸
Nesse guia vou te mostrar como podemos transformar imagens e link de imagens enviados no Whatsapp em Stickers!
Requisitos
- Instalar o Node.js
Mão na massa!
Como de costume crie uma pasta para seu projeto onde quiser, abra o terminal dentro da pasta e já roda o npm init
para iniciar o processo de criação do projeto. Após finalizar vamos intalar as dependencias que vamos usar.
Instalando dependencias
Use o comando npm i nome-da-lib
para instalar todas as dependencias abaixo. Exemplo npm i whatsapp-web.js
.
1. whatsapp-web.js
Nesse guia não vou utilizar o venom-bot que usei no Guia completo de como integrar o ChatGPT com Whatsapp 🤖, para ensinar outras dependencias legais que fazem a mesma coisa caso voce tenha problemas com o venom-bot. Dessa vez vamos instalar o whatsapp-web.js, já vai no seu terminal e roda o comando npm i whatsapp-web.js
.
3. qrcode-terminal
Vamos precisar dessa lib para transformar o qrcode gerado em base64 do whatsapp-web.js em uma imagem no nosso terminal. Assim facilita a vida e não vamos precisar copiar e colar o base64 em sites de terceiros para gerar nossa imagem.
3. axios
Apenas para facilitar nossa vida com as requisições e ficar menos verboso.
Codando
Vamos começar com o snippet de conexão do whatsapp-web.js utilizando o qrcode-terminal para nos conectar e testar nossa integração. Crie um arquivo index.js
na raiz do seu projeto e implemente o código abaixo.
const { Client } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal')
const client = new Client();
client.on('qr', qr => {
qrcode.generate(qr, {small: true});
});
client.on('ready', () => {
console.log('Client is ready!');
});
/**
* Aqui vem como default 'message', bora trocar para 'message_create',
* dessa forma nós também poderemos dar comandos e não apenas seus
* contatos.
*/
client.on('message_create', message => {
if(message.body === 'Hello') {
message.reply('🤖 world 🌎');
}
});
client.initialize();
Agora que a gente já viu que está tudo funcionando bora criar uma condicional dentro do nosso listener de mensagens para pegar o comando que o usuário mandou e chamar as funções que a gente criar de acordo com o comando.
client.on('message_create', msg => {
const command = msg.body.split(' ')[0];
// Cola seu número onde tem o 84848484, sem o 9
const sender = msg.from.includes("84848484") ? msg.to : msg.from
if (command === "/sticker") generateSticker(msg, sender)
});
Prontinho, bora implementar a função generateSticker()
. Nela vamos validar apenas 1 coisa, se a mensagem enviada contém uma imagem ou um link de uma imagem, já que cada caso precisa ser tratado de uma forma diferente. No caso da imagem crua vamos apenas utilizar a função downloadMedia()
do próprio objeto msg do whatsapp-web.js, e desestruturando o objeto { data }
para pegar a key data que contem nosso base64 para posteriormente criarmos uma instancia da classe MessageMedia que criará um objeto de imagem para nós que possibilitará envia-lo como sticker na função sendMessage()
. Já a url de imagem nós precisamos baixá-la usando o axios e como ela chega para gente como um Buffer que contém uma sequencia de bytes, precisaremos transforma-la em base64 para posteriormente repetir o mesmo processo da imagem crua e envia-la usando a função sendMessage()
.
const generateSticker = async (msg, sender) => {
if(msg.type === "image") {
try {
const { data } = await msg.downloadMedia()
const image = await new MessageMedia("image/jpeg", data, "image.jpg")
await client.sendMessage(sender, image, { sendMediaAsSticker: true })
} catch(e) {
msg.reply("❌ Erro ao processar imagem")
}
} else {
try {
const url = msg.body.substring(msg.body.indexOf(" ")).trim()
const { data } = await axios.get(url, {responseType: 'arraybuffer'})
const returnedB64 = Buffer.from(data).toString('base64');
const image = await new MessageMedia("image/jpeg", returnedB64, "image.jpg")
await client.sendMessage(sender, image, { sendMediaAsSticker: true })
} catch(e) {
msg.reply("❌ Não foi possível gerar um sticker com esse link")
}
}
}
E no fim nosso index.js
ficará assim
const { Client, MessageMedia } = require('whatsapp-web.js')
const qrcode = require('qrcode-terminal')
const axios = require('axios')
const client = new Client({})
client.on('qr', qr => {
qrcode.generate(qr, {small: true})
});
client.on('ready', () => {
console.log('O Wpp-Sticker está pronto 😋 Não esquece da estrelinha no repo ⭐')
});
/**
* Aqui vem como default 'message', bora trocar para 'message_create',
* dessa forma nós também poderemos dar comandos e não apenas seus
* contatos.
*/
client.on('message_create', msg => {
const command = msg.body.split(' ')[0];
// Cola seu número onde tem o 84848484, sem o 9
const sender = msg.from.includes("84848484") ? msg.to : msg.from
if (command === "/sticker") generateSticker(msg, sender)
});
client.initialize();
const generateSticker = async (msg, sender) => {
if(msg.type === "image") {
try {
const { data } = await msg.downloadMedia()
const image = await new MessageMedia("image/jpeg", data, "image.jpg")
await client.sendMessage(sender, image, { sendMediaAsSticker: true })
} catch(e) {
msg.reply("❌ Erro ao processar imagem")
}
} else {
try {
const url = msg.body.substring(msg.body.indexOf(" ")).trim()
const { data } = await axios.get(url, {responseType: 'arraybuffer'})
const returnedB64 = Buffer.from(data).toString('base64');
const image = await new MessageMedia("image/jpeg", returnedB64, "image.jpg")
await client.sendMessage(sender, image, { sendMediaAsSticker: true })
} catch(e) {
msg.reply("❌ Não foi possível gerar um sticker com esse link")
}
}
}
Demo
E bora ver essa belezura rodando com o melhor inicial da Gen 1 do Pokemon e depois o melhor Pokemon de todos os tempos.
Dicas
-
Caso queira formatar sua imagem antes de enviá-la da uma olhada no jimp. Essa lib vai te ajudar a manipular as imagens da forma que quiser.
-
Se quiser que o bot mande comandos apenas para um grupo específico faça o seguinte:
client.on('message_create', msg => {
const command = msg.body.split(' ')[0];
const sender = msg.from.includes("84374282") ? msg.to : msg.from
if (command === "/sticker" && sender === 'ID-DO-SEU-GRUPO') generateSticker(msg, sender)
});
Sim, eu sei o que voce está pensando "-A mas eu não sei o id do meu grupo Harry", faz o seguinte escreve console.log(msg)
dentro do client.on()
vai ficar assim:
client.on('message_create', msg => {
console.log(msg)
const command = msg.body.split(' ')[0];
const sender = msg.from.includes("84374282") ? msg.to : msg.from
if (command === "/sticker" && sender === 'ID-DO-SEU-GRUPO') generateSticker(msg, sender)
});
Manda qualquer mensagem no grupo que voce quer que o bot funcione e procure no seu terminal caso voce tenha enviado, a seguinte key to: '[email protected]',
(talvez seja um número até maior que esse caso tenha mais gente no grupo) e caso tenha sido outra pessoa que enviou a msg ao invés de to vai ser from. Prontinho, ta aí o seu id do grupo.
Ta com preguiça e quer um plug and play?
Sei que eu deveria colocar isso no início pra evitar da galera descobrir só depois de ler tudo mas você também deveria ler mais 👍
Vai lá no repositório pra dar fork e aproveita e deixa a estrela ⭐ https://github.com/victorharry/wpp-sticker
To pensando em criar uns conteúdos legais com projetinhos do tipo no youtube, se inscreve lá pra dar aquela moral se te ajudei de alguma forma Dev Cansado (:
Toss a tabcoin to your Witcher 🪙🎶