diff --git a/README.md b/README.md index fac1ed1..23af37e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ -# ManyBot! +![ManyBot Logo](logo.png) Criei esse bot para servir um grupo de amigos. Meu foco não é fazer ele funcionar para todo mundo. Ele é 100% local e gratuito, sem necessidade de APIs burocraticas. Usufrui da biblioteca `whatsapp-web.js`, que permite bastante coisa mesmo sem a API oficial. +Você consegue totalmente clonar esse repoistório e rodar seu próprio ManyBot. A licenca MIT permite que você modifique o que quiser e faça seu próprio bot. + Algumas funcionalidades desse bot inclui: - Funciona em multiplos chats em apenas uma única sessão - Comandos de jogos e download com yt-dlp -- \ No newline at end of file +- Gerador de figurinhas +- Ferramenta para pegar IDs dos chats +- Entre outros + diff --git a/deploy.sh b/deploy.sh index 9a72ec2..87753af 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,6 +1,4 @@ #!/bin/bash - - TAG=$(git describe --tags --abbrev=0) npm version $TAG --no-git-tag-version \ No newline at end of file diff --git a/get_id.js b/get_id.js index 3a90a2e..3cfc719 100644 --- a/get_id.js +++ b/get_id.js @@ -20,16 +20,14 @@ const client = new Client({ }); client.on('qr', qr => { - console.log("[BOT] QR Code gerado. Escaneie apenas uma vez:"); + console.log("[WPP] QR Code gerado. Escaneie apenas uma vez:"); qrcode.generate(qr, { small: true }); }); -client.on('ready', () => { - console.log("[BOT] WhatsApp conectado e sessão permanente"); -}); - client.on('ready', async () => { - const chats = await client.getChats(); + console.log("[WPP] Conectado"); + + const chats = await client.getChats(); // <- precisa do await let filtered = []; @@ -54,7 +52,7 @@ client.on('ready', async () => { }); } - process.exit(0); // fecha o script após listar + process.exit(0); }); client.initialize(); \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..59c95b9 Binary files /dev/null and b/logo.png differ diff --git a/main.js b/main.js index b89d10a..0b6b823 100644 --- a/main.js +++ b/main.js @@ -1,64 +1,67 @@ -// main_global.js console.log("[CARREGANDO] Aguarde..."); import pkg from 'whatsapp-web.js'; const { Client, LocalAuth, MessageMedia } = pkg; + import qrcode from 'qrcode-terminal'; import fs from 'fs'; import { exec } from 'child_process'; +import sharp from 'sharp'; -const CLIENT_ID = "bot_permanente"; // sessão única global +import { CHATS } from "./env.js"; + +const CLIENT_ID = "bot_permanente"; const BOT_PREFIX = "🤖 *ManyBot:* "; -// lista fixa de chats que queremos interagir -import { CHATS_PERMITIDOS } from "./env.js" -// parecido com isso: -/* -export const CHATS_PERMITIDOS = [ - "123456789101234567@c.us", // pedrinho - "987654321012345678@g.us" // escola -]; -*/ - let jogoAtivo = null; -// criar client único +if (!fs.existsSync("downloads")) fs.mkdirSync("downloads"); + const client = new Client({ authStrategy: new LocalAuth({ clientId: CLIENT_ID }), puppeteer: { headless: true } }); -client.on('qr', qr => { - console.log("[BOT] QR Code gerado. Escaneie apenas uma vez:"); +function botMsg(texto) { + return `${BOT_PREFIX}\n${texto}`; +} + +function getChatId(chat) { + return chat.id._serialized; +} + +client.on("qr", qr => { + console.log("[BOT] Escaneie o QR Code"); qrcode.generate(qr, { small: true }); }); -client.on('ready', () => { +client.on("ready", () => { exec("clear"); - console.log("[BOT] WhatsApp conectado e sessão permanente"); + console.log("[BOT] WhatsApp conectado."); }); -client.on('disconnected', reason => { - console.warn(`[BOT] Desconectado: ${reason}. Tentando reconectar...`); +client.on("disconnected", reason => { + console.warn("[BOT] Reconectando:", reason); setTimeout(() => client.initialize(), 5000); }); -client.on('message_create', async msg => { +client.on("message_create", async msg => { try { - const chat = await msg.getChat(); - // filtra apenas chats permitidos - if (!CHATS_PERMITIDOS.includes(chat.id._serialized)) return; + const chat = await msg.getChat(); + const chatId = getChatId(chat); + + if (!CHATS.includes(chatId)) return; console.log("=================================="); - console.log(`CHAT NAME : ${chat.name || chat.id.user || "Sem nome"}`); - console.log(`CHAT ID : ${chat.id._serialized}`); + console.log(`CHAT NAME : ${chat.name || chat.id.user}`); + console.log(`CHAT ID : ${chatId}`); console.log(`FROM : ${msg.from}`); console.log(`BODY : ${msg.body}`); console.log("==================================\n"); - await processarComando(msg); - await processarJogo(msg); + await processarComando(msg, chat, chatId); + await processarJogo(msg, chat); } catch (err) { console.error("[ERRO]", err); @@ -66,207 +69,316 @@ client.on('message_create', async msg => { }); -// ---------------- Funções de envio ---------------- +// ---------------- DOWNLOAD ---------------- -async function enviarVideo(cliente, chatId, caminhoArquivo) { - if (!fs.existsSync(caminhoArquivo)) throw new Error(`Arquivo não encontrado: ${caminhoArquivo}`); - - const arquivo = fs.readFileSync(caminhoArquivo); - const media = new MessageMedia('video/mp4', arquivo.toString('base64'), caminhoArquivo.split('/').pop()); - - await cliente.sendMessage(chatId, media, { sendMediaAsDocument: false }); - fs.unlinkSync(caminhoArquivo); - console.log(`[BOT] Vídeo enviado e removido: ${caminhoArquivo}`); -} - -async function enviarAudio(cliente, chatId, caminhoArquivo) { - if (!fs.existsSync(caminhoArquivo)) throw new Error(`Arquivo não encontrado: ${caminhoArquivo}`); - - const arquivo = fs.readFileSync(caminhoArquivo); - const media = new MessageMedia('audio/mpeg', arquivo.toString('base64'), caminhoArquivo.split('/').pop()); - - await cliente.sendMessage(chatId, media, { sendAudioAsVoice: false }); - fs.unlinkSync(caminhoArquivo); - console.log(`[BOT] Áudio enviado e removido: ${caminhoArquivo}`); -} - -function botMsg(texto) { - return `${BOT_PREFIX}\n${texto}`; -} - -function iniciarJogo(chat) { - const numeroSecreto = Math.floor(Math.random() * 100) + 1; - jogoAtivo = numeroSecreto; - - console.log(`[JOGO] ${chat.name}: Número escolhido ${numeroSecreto}`); -} - -// ---------------- Download ---------------- - -let downloadsAtivos = 0; -const MAX_DOWNLOADS = 2; -const downloadQueue = []; +let downloadQueue = []; let processingQueue = false; -// Garantir que a pasta downloads exista -if (!fs.existsSync('downloads')) fs.mkdirSync('downloads'); - -function runYtDlp(cmd1, cmd2) { +function run(cmd) { return new Promise((resolve, reject) => { - exec(cmd1, (error, stdout, stderr) => { - if (!error) return resolve({ stdout, stderr }); - - exec(cmd2, (error2, stdout2, stderr2) => { - if (error2) return reject(error2); - resolve({ stdout: stdout2, stderr: stderr2 }); - }); + exec(cmd, (err, stdout, stderr) => { + if (err) reject(err); + else resolve({ stdout, stderr }); }); }); } -function get_video(url, id) { - downloadsAtivos++; +async function get_video(url, id) { - return new Promise(async (resolve, reject) => { - const cmd1 = `yt-dlp -t mp4 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; - const cmd2 = `.\yt-dlp.exe -t mp4 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; + const cmd = `./yt-dlp --extractor-args "youtube:player_client=android" -f mp4 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; - try { - const { stdout, stderr } = await runYtDlp(cmd1, cmd2); - downloadsAtivos--; + const { stdout } = await run(cmd); - if (stderr) console.error(stderr); + const filepath = stdout.trim(); + if (!filepath) throw new Error("yt-dlp não retornou caminho"); - const filepath = stdout.trim(); - if (!filepath) return reject(new Error("yt-dlp não retornou filepath")); - - resolve(filepath); - } catch (err) { - downloadsAtivos--; - reject(new Error(`yt-dlp falhou: ${err.message}`)); - } - }); + return filepath; } -function get_audio(url, id) { - downloadsAtivos++; +async function get_audio(url, id) { - return new Promise(async (resolve, reject) => { - const cmd1 = `yt-dlp -t mp3 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; - const cmd2 = `.\yt-dlp.exe -t mp3 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; + const cmd = `./yt-dlp --extractor-args "youtube:player_client=android" -t mp3 --print after_move:filepath -o "downloads/${id}.%(ext)s" "${url}"`; - try { - const { stdout, stderr } = await runYtDlp(cmd1, cmd2); - downloadsAtivos--; + const { stdout } = await run(cmd); - if (stderr) console.error(stderr); + const filepath = stdout.trim(); + if (!filepath) throw new Error("yt-dlp não retornou caminho"); - const filepath = stdout.trim(); - if (!filepath) return reject(new Error("yt-dlp não retornou filepath")); - - resolve(filepath); - } catch (err) { - downloadsAtivos--; - reject(new Error(`yt-dlp falhou: ${err.message}`)); - } - }); + return filepath; } -function enqueueDownload(type, url, msg) { - return new Promise((resolve, reject) => { - downloadQueue.push({ type, url, msg, resolve, reject }); - processQueue(); - }); +async function enviarVideo(chatId, path) { + + const file = fs.readFileSync(path); + + const media = new MessageMedia( + "video/mp4", + file.toString("base64"), + path.split("/").pop() + ); + + await client.sendMessage(chatId, media); + + fs.unlinkSync(path); +} + +async function enviarAudio(chatId, path) { + const file = fs.readFileSync(path); + + const media = new MessageMedia( + "audio/mpeg", + file.toString("base64"), + path.split("/").pop() + ); + + await client.sendMessage(chatId, media); + + fs.unlinkSync(path); +} + +function enqueueDownload(type, url, msg, chatId) { + downloadQueue.push({ type, url, msg, chatId }); + if (!processingQueue) processQueue(); } async function processQueue() { - if (processingQueue) return; processingQueue = true; - while (downloadQueue.length) { - const { type, url, msg, resolve, reject } = downloadQueue.shift(); - const chat = await msg.getChat(); - const chatId = chat.id._serialized; + const job = downloadQueue.shift(); + try { - let caminho; - if (type === 'video') caminho = await get_video(url, msg.id._serialized); - else caminho = await get_audio(url, msg.id._serialized); + let path; - if (type === 'video') await enviarVideo(client, chatId, caminho); - else await enviarAudio(client, chatId, caminho); + if (job.type === "video") + path = await get_video(job.url, job.msg.id._serialized); + else + path = await get_audio(job.url, job.msg.id._serialized); + + if (job.type === "video") + await enviarVideo(job.chatId, path); + else + await enviarAudio(job.chatId, path); - resolve(caminho); } catch (err) { - reject(err); - const chat = await msg.getChat(); - chat.sendMessage(botMsg(`❌ Erro ao baixar ${type}: ${err.message}`)); + await client.sendMessage( + job.chatId, + botMsg(`❌ Erro ao baixar ${job.type}\n\`${err.message}\``) + ); } } - processingQueue = false; } -// ---------------- Comandos ---------------- -async function processarComando(msg) { - const tokens = msg.body.trim().split(/\s+/); - if (tokens[0] !== "!many") return; +// ---------------- FIGURINHA ---------------- - const chat = await msg.getChat(); - - if (tokens.length === 1) { - chat.sendMessage(botMsg( - "- `!many ping` -> testa se estou funcionando\n" + - "- `!many adivinhação ` -> jogo de adivinhação\n" + - "- `!many video ` -> baixo um vídeo da internet para você!\n" + - "- `!many audio ` -> baixo um audio da internet para você!" - )); +async function gerarSticker(msg) { + if (!msg.hasMedia) { + await msg.reply(botMsg("Envie uma imagem junto com o comando: `!figurinha`.")); return; } - if (tokens[1] === "ping") chat.sendMessage(botMsg("pong 🏓")); - if (tokens[1] === "adivinhação") { - if (tokens[2] === undefined) { - chat.sendMessage(botMsg("Acho que você se esqueceu de algo! 😅\n" + - "🏁 `!many adivinhação começar` -> começa o jogo\n" + - "🛑 `!many adivinhação parar` -> para o jogo atual" - )); - } else if (tokens[2] === "começar") { - iniciarJogo(chat); - chat.sendMessage(botMsg("Hora do jogo! 🏁 Tentem adivinhar o número de 1 a 100 que eu estou pensando!")); - } else if (tokens[2] === "parar") { - jogoAtivo = null - chat.sendMessage(botMsg("O jogo atual foi interrompido 🛑")); + const media = await msg.downloadMedia(); + + const ext = media.mimetype.split("/")[1]; + + const input = `downloads/${msg.id._serialized}.${ext}`; + const output = `downloads/${msg.id._serialized}.webp`; + + fs.writeFileSync(input, Buffer.from(media.data, "base64")); + + await sharp(input) + .resize(512, 512, { + fit: "contain", + background: { r:0,g:0,b:0,alpha:0 } + }) + .webp() + .toFile(output); + + const data = fs.readFileSync(output); + + const sticker = new MessageMedia( + "image/webp", + data.toString("base64"), + "sticker.webp" + ); + + const chat = await msg.getChat(); + + await client.sendMessage( + chat.id._serialized, + sticker, + { sendMediaAsSticker: true } + ); + + fs.unlinkSync(input); + fs.unlinkSync(output); +} + + +// ---------------- COMANDOS ---------------- + +async function processarComando(msg, chat, chatId) { + const tokens = msg.body.trim().split(/\s+/); + try { + switch(tokens[0]) { + + case "!many": + await chat.sendMessage(botMsg( + "Comandos:\n\n"+ + "`!ping`\n"+ + "`!video `\n"+ + "`!audio `\n"+ + "`!figurinha`\n"+ + "`!adivinhação começar|parar`\n"+ + "`!info `" + )); + break; + + + case "!ping": + await msg.reply(botMsg("pong 🏓")); + break; + + + case "!video": + if (!tokens[1]) return; + + await msg.reply(botMsg("⏳ Baixando vídeo...")); + enqueueDownload("video", tokens[1], msg, chatId); + break; + + + case "!audio": + if (!tokens[1]) return; + + await msg.reply(botMsg("⏳ Baixando áudio...")); + enqueueDownload("audio", tokens[1], msg, chatId); + break; + + case "!figurinha": + await gerarSticker(msg); + break; + + + case "!adivinhação": + if (!tokens[1]) { + await chat.sendMessage(botMsg( + "`!adivinhação começar`\n"+ + "`!adivinhação parar`" + )); + return; + } + + if (tokens[1] === "começar") { + jogoAtivo = Math.floor(Math.random()*100)+1; + + await chat.sendMessage(botMsg( + "Adivinhe o número de 1 a 100!" + )); + } + + if (tokens[1] === "parar") { + jogoAtivo = null; + + await chat.sendMessage(botMsg("Jogo encerrado.")); + } + break; + + + case "A": + if (!tokens[1]) { + msg.reply(botMsg("B!")); + } + break; + case "a": + if (!tokens[1]) { + msg.reply(botMsg("B!")); + } + break; + + case "!info": + + if (!tokens[1]) { + await chat.sendMessage(botMsg( + "Use:\n" + + "`!info `" + )); + return; + } + + switch(tokens[1]) { + + case "ping": + await chat.sendMessage(botMsg( + "> `!ping`\nResponde pong." + )); + break; + + case "video": + await chat.sendMessage(botMsg( + "> `!video `\nBaixa vídeo da internet.\n" + )); + break; + + case "audio": + await chat.sendMessage(botMsg( + "> `!audio `\nBaixa áudio da internet.\n" + )); + break; + + case "figurinha": + await chat.sendMessage(botMsg( + "`!figurinha`\nTransforma imagem/GIF em sticker." + )); + break; + + default: + await chat.sendMessage(botMsg( + `❌ Comando '${tokens[1]}' não encontrado.` + )); + } + + break; } - } - - if (tokens[1] === "video" && tokens[2]) { - chat.sendMessage(botMsg("⏳ Baixando vídeo, aguarde...")); - enqueueDownload('video', tokens[2], msg); - } - - if (tokens[1] === "audio" && tokens[2]) { - chat.sendMessage(botMsg("⏳ Baixando áudio, aguarde...")); - enqueueDownload('audio', tokens[2], msg); + } catch(err) { + console.error(err); + await chat.sendMessage( + botMsg("Erro:\n`"+err.message+"`") + ); } } -// ---------------- Jogo ---------------- -async function processarJogo(msg) { - const chat = await msg.getChat(); +// ---------------- JOGO ---------------- + +async function processarJogo(msg, chat) { + if (!jogoAtivo) return; const tentativa = msg.body.trim(); + if (!/^\d+$/.test(tentativa)) return; - const num = parseInt(tentativa, 10); + const num = parseInt(tentativa); if (num === jogoAtivo) { - chat.sendMessage(botMsg(`Parabéns! Você acertou! Número: ${jogoAtivo}`)); + + await msg.reply(botMsg(`Acertou! Número: ${jogoAtivo}`)); + jogoAtivo = null; - } else if (num > jogoAtivo) chat.sendMessage(botMsg(`Quase! Um pouco menor. Sua resposta: ${num}`)); - else chat.sendMessage(botMsg(`Quase! Um pouco maior. Sua resposta: ${num}`)); + + } + else if (num > jogoAtivo) { + + await chat.sendMessage(botMsg("Menor.")); + + } + else { + + await chat.sendMessage(botMsg("Maior.")); + + } } client.initialize(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a73f836..b7cdeb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,17 @@ { "name": "whatsapp-bot", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { + "name": "whatsapp-bot", + "version": "1.1.0", "dependencies": { "qrcode-terminal": "^0.12.0", - "whatsapp-web.js": "^1.34.6" - }, - "version": "1.1.0" + "sharp": "^0.34.5", + "whatsapp-web.js": "^1.24.0" + } }, "node_modules/@babel/code-frame": { "version": "7.29.0", @@ -33,6 +36,529 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", + "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@pedroslopez/moduleraid": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@pedroslopez/moduleraid/-/moduleraid-5.0.2.tgz", @@ -653,6 +1179,15 @@ "node": ">= 14" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1581282", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz", @@ -1647,6 +2182,50 @@ "license": "MIT", "optional": true }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -2099,6 +2678,5 @@ "url": "https://github.com/sponsors/colinhacks" } } - }, - "version": "1.1.0" + } } diff --git a/package.json b/package.json index 0743d39..f8d92d6 100755 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "1.1.0", "type": "module", "dependencies": { - "whatsapp-web.js": "^1.24.0", - "qrcode-terminal": "^0.12.0" + "qrcode-terminal": "^0.12.0", + "sharp": "^0.34.5", + "whatsapp-web.js": "^1.24.0" } } diff --git a/yt-dlp.exe b/yt-dlp.exe deleted file mode 100644 index 828f154..0000000 Binary files a/yt-dlp.exe and /dev/null differ