Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb50d4b8f8 | ||
|
|
f2e6c12af4 | ||
|
|
308db818da | ||
|
|
541f11af6d |
14
deploy.sh
14
deploy.sh
@@ -24,13 +24,6 @@ EOF
|
||||
# mudar para a branch
|
||||
git checkout $BRANCH || { echo "Error ao change to $BRANCH"; exit 1; }
|
||||
|
||||
# adicionar alterações e commit
|
||||
git add .
|
||||
git commit -m "$COMMIT_MSG"
|
||||
|
||||
# push
|
||||
git push origin $BRANCH
|
||||
|
||||
# se for master, atualizar versão
|
||||
if [ "$BRANCH" == "master" ] && [ -n "$VERSION" ]; then
|
||||
echo "Updating version to $VERSION"
|
||||
@@ -41,4 +34,11 @@ if [ "$BRANCH" == "master" ] && [ -n "$VERSION" ]; then
|
||||
git push origin $VERSION
|
||||
fi
|
||||
|
||||
# adicionar alterações e commit
|
||||
git add .
|
||||
git commit -m "$COMMIT_MSG"
|
||||
|
||||
# push
|
||||
git push origin $BRANCH
|
||||
|
||||
echo "Deploy completed."
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "whatsapp-bot",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "whatsapp-bot",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^7",
|
||||
"node-gyp": "^12.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "whatsapp-bot",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^7",
|
||||
|
||||
@@ -51,7 +51,7 @@ async function convertVideoToGif(inputPath, outputPath, fps = 12) {
|
||||
|
||||
await execFileAsync(FFMPEG, [
|
||||
"-i", inputPath,
|
||||
"-filter_complex", filter, // <-- era -vf, tem que ser -filter_complex pro split funcionar
|
||||
"-filter_complex", filter,
|
||||
"-loop", "0",
|
||||
"-y",
|
||||
outputPath
|
||||
@@ -63,7 +63,7 @@ async function resizeToSticker(inputPath, outputPath) {
|
||||
|
||||
await execFileAsync(FFMPEG, [
|
||||
"-i", inputPath,
|
||||
"-vf", "scale=512:512:flags=lanczos", // lanczos = melhor qualidade no resize
|
||||
"-vf", "scale=512:512:flags=lanczos",
|
||||
"-y",
|
||||
outputPath
|
||||
]);
|
||||
@@ -98,33 +98,40 @@ async function createStickerWithFallback(stickerInputPath, isAnimated) {
|
||||
|
||||
// ───────────────── Sessão ─────────────────
|
||||
|
||||
export function iniciarSessao(chatId, author) {
|
||||
export const help =
|
||||
"📌 *Como criar figurinhas:*\n\n" +
|
||||
"1️⃣ Digite `!figurinha` para iniciar\n" +
|
||||
"2️⃣ Envie as imagens, GIFs ou vídeos que quer transformar\n" +
|
||||
"3️⃣ Digite `!figurinha criar` para gerar as figurinhas\n\n" +
|
||||
"⏳ A sessão expira em 2 minutos se nenhuma mídia for enviada.";
|
||||
|
||||
export function iniciarSessao(chatId, author, msg) {
|
||||
if (stickerSessions.has(chatId)) return false;
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
|
||||
const timeout = setTimeout(async () => {
|
||||
stickerSessions.delete(chatId);
|
||||
client.sendMessage(chatId, botMsg("Sessão de figurinha expirou."));
|
||||
|
||||
try {
|
||||
await msg.reply(botMsg(
|
||||
"⏰ *Sessão expirada!*\n\n" +
|
||||
"Você demorou mais de 2 minutos para enviar as mídias.\n" +
|
||||
"Digite `!figurinha` para começar de novo."
|
||||
));
|
||||
} catch (err) {
|
||||
console.error("Erro ao notificar expiração:", err.message);
|
||||
}
|
||||
}, SESSION_TIMEOUT);
|
||||
|
||||
stickerSessions.set(chatId, {
|
||||
author,
|
||||
medias: [],
|
||||
timeout
|
||||
});
|
||||
|
||||
stickerSessions.set(chatId, { author, medias: [], timeout });
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// ───────────────── Coleta de mídia ─────────────────
|
||||
|
||||
export async function coletarMidia(msg) {
|
||||
|
||||
;
|
||||
// figurinha.js — coletarMidia
|
||||
const chat = await msg.getChat();
|
||||
const chatId = chat.id._serialized;
|
||||
const chatId = chat.id._serialized; // ← volta pra isso
|
||||
|
||||
const session = stickerSessions.get(chatId);
|
||||
if (!session) return;
|
||||
@@ -158,33 +165,40 @@ export async function coletarMidia(msg) {
|
||||
// ───────────────── Criar stickers ─────────────────
|
||||
|
||||
export async function gerarSticker(msg, chatId) {
|
||||
console.log("[gerarSticker] chatId:", chatId);
|
||||
|
||||
const sender = msg.author || msg.from;
|
||||
const session = stickerSessions.get(chatId);
|
||||
|
||||
if (!session) {
|
||||
return msg.reply(botMsg("Nenhuma sessão de figurinha ativa."));
|
||||
return msg.reply(botMsg(
|
||||
"❌ *Nenhuma sessão ativa.*\n\n" + help
|
||||
));
|
||||
}
|
||||
|
||||
if (session.author !== sender) {
|
||||
return msg.reply(botMsg("Apenas quem iniciou a sessão pode criar as figurinhas."));
|
||||
return msg.reply(botMsg(
|
||||
"🚫 Só quem digitou `!figurinha` pode usar `!figurinha criar`."
|
||||
));
|
||||
}
|
||||
|
||||
const medias = session.medias;
|
||||
|
||||
if (!medias.length) {
|
||||
return msg.reply(botMsg("Nenhuma imagem recebida."));
|
||||
return msg.reply(botMsg(
|
||||
"📭 *Você ainda não enviou nenhuma mídia!*\n\n" + help
|
||||
));
|
||||
}
|
||||
|
||||
clearTimeout(session.timeout);
|
||||
|
||||
console.log("midias:", medias.length);
|
||||
|
||||
await msg.reply(botMsg("Aguarde! Estou criando as suas figurinhas..."));
|
||||
await msg.reply(botMsg("⏳ Gerando suas figurinhas, aguarde um momento..."));
|
||||
|
||||
ensureDownloadsDir();
|
||||
|
||||
for (const media of medias) {
|
||||
for (const media of medias) {
|
||||
try {
|
||||
const ext = media.mimetype.split("/")[1];
|
||||
const isVideo = media.mimetype.startsWith("video/");
|
||||
@@ -198,7 +212,6 @@ export async function gerarSticker(msg, chatId) {
|
||||
|
||||
fs.writeFileSync(inputPath, Buffer.from(media.data, "base64"));
|
||||
|
||||
// LOG 1 — arquivo de entrada
|
||||
const inputSize = fs.statSync(inputPath).size;
|
||||
console.log(`[1] mimetype: ${media.mimetype} | isAnimated: ${isAnimated} | inputPath: ${inputPath} | size: ${inputSize} bytes`);
|
||||
|
||||
@@ -208,7 +221,6 @@ export async function gerarSticker(msg, chatId) {
|
||||
console.log("[2] Convertendo para GIF...");
|
||||
await convertVideoToGif(inputPath, gifPath, isVideo ? 12 : 24);
|
||||
|
||||
// LOG 2 — gif gerado
|
||||
if (fs.existsSync(gifPath)) {
|
||||
console.log(`[2] GIF gerado: ${fs.statSync(gifPath).size} bytes`);
|
||||
} else {
|
||||
@@ -229,12 +241,10 @@ export async function gerarSticker(msg, chatId) {
|
||||
stickerInputPath = resizedPath;
|
||||
}
|
||||
|
||||
// LOG 3 — antes de criar o sticker
|
||||
console.log(`[3] stickerInputPath: ${stickerInputPath} | exists: ${fs.existsSync(stickerInputPath)} | size: ${fs.existsSync(stickerInputPath) ? fs.statSync(stickerInputPath).size : "N/A"} bytes`);
|
||||
|
||||
const stickerBuffer = await createStickerWithFallback(stickerInputPath, isAnimated);
|
||||
|
||||
// LOG 4 — sticker gerado
|
||||
console.log(`[4] Sticker buffer: ${stickerBuffer.length} bytes`);
|
||||
|
||||
const stickerMedia = new MessageMedia("image/webp", stickerBuffer.toString("base64"));
|
||||
@@ -244,11 +254,17 @@ export async function gerarSticker(msg, chatId) {
|
||||
|
||||
} catch (err) {
|
||||
console.error("Erro ao gerar sticker:", err);
|
||||
await msg.reply(botMsg("Erro ao gerar uma das figurinhas."));
|
||||
await msg.reply(botMsg(
|
||||
"⚠️ Não consegui criar uma das figurinhas.\n" +
|
||||
"Tente reenviar essa mídia ou use outro formato (JPG, PNG, GIF, MP4)."
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
await msg.reply(botMsg("Figurinhas geradas com sucesso!"));
|
||||
await msg.reply(botMsg(
|
||||
"✅ *Figurinhas criadas com sucesso!*\n" +
|
||||
"Salve as que quiser no seu WhatsApp. 😄"
|
||||
));
|
||||
|
||||
stickerSessions.delete(chatId);
|
||||
emptyFolder("downloads");
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { enqueueDownload } from "../download/queue.js";
|
||||
import { iniciarSessao, gerarSticker } from "./figurinha.js";
|
||||
import { iniciarSessao, gerarSticker, help } from "./figurinha.js";
|
||||
import { botMsg } from "../utils/botMsg.js";
|
||||
import { iniciarJogo, pararJogo } from "../games/adivinhacao.js";
|
||||
import { processarInfo } from "./info.js";
|
||||
import client from "../client/whatsappClient.js";
|
||||
|
||||
export const stickerSessions = new Map();
|
||||
|
||||
@@ -34,88 +35,93 @@ export async function processarComando(msg, chat, chatId) {
|
||||
switch (cmd) {
|
||||
case "!many":
|
||||
await chat.sendMessage(botMsg(
|
||||
"Comandos:\n\n" +
|
||||
"- `!ping`\n" +
|
||||
"- `!video <link>`\n" +
|
||||
"- `!audio <link>`\n" +
|
||||
"- `!figurinha`\n" +
|
||||
"- `!adivinhação começar|parar`\n" +
|
||||
"- `!info <comando>`"
|
||||
"*Comandos disponíveis:*\n\n" +
|
||||
"🎬 `!video <link>` — baixa um vídeo\n" +
|
||||
"🎵 `!audio <link>` — baixa um áudio\n" +
|
||||
"🖼️ `!figurinha` — cria figurinhas\n" +
|
||||
"🎮 `!adivinhação começar|parar` — jogo de adivinhar número\n"
|
||||
));
|
||||
break;
|
||||
|
||||
case "!ping":
|
||||
await msg.reply(botMsg("pong 🏓"));
|
||||
log.ok("pong enviado");
|
||||
break;
|
||||
|
||||
case "!video":
|
||||
if (!tokens[1]) { log.warn("!video sem link"); return; }
|
||||
await msg.reply(botMsg("⏳ Baixando vídeo..."));
|
||||
if (!tokens[1]) {
|
||||
await msg.reply(botMsg("❌ Você precisa informar um link.\n\nExemplo: `!video https://youtube.com/...`"));
|
||||
log.warn("!video sem link");
|
||||
return;
|
||||
}
|
||||
await msg.reply(botMsg("⏳ Baixando o vídeo, aguarde..."));
|
||||
enqueueDownload("video", tokens[1], msg, chatId);
|
||||
log.ok("vídeo enfileirado →", tokens[1]);
|
||||
break;
|
||||
|
||||
case "!audio":
|
||||
if (!tokens[1]) { log.warn("!audio sem link"); return; }
|
||||
await msg.reply(botMsg("⏳ Baixando áudio..."));
|
||||
if (!tokens[1]) {
|
||||
await msg.reply(botMsg("❌ Você precisa informar um link.\n\nExemplo: `!audio https://youtube.com/...`"));
|
||||
log.warn("!audio sem link");
|
||||
return;
|
||||
}
|
||||
await msg.reply(botMsg("⏳ Baixando o áudio, aguarde..."));
|
||||
enqueueDownload("audio", tokens[1], msg, chatId);
|
||||
log.ok("áudio enfileirado →", tokens[1]);
|
||||
break;
|
||||
|
||||
case "!figurinha":
|
||||
const author = msg.author || msg.from;
|
||||
const name = msg._data?.notifyName || author.replace(/(:\d+)?@.*$/, "");
|
||||
const groupId = chat.id._serialized; // < fonte única de verdade
|
||||
|
||||
if (tokens[1] === "criar") {
|
||||
await gerarSticker(msg, chatId);
|
||||
await gerarSticker(msg, groupId);
|
||||
} else {
|
||||
if (stickerSessions.has(chatId)) {
|
||||
return msg.reply(botMsg("Já existe uma sessão ativa."));
|
||||
if (stickerSessions.has(groupId)) {
|
||||
return msg.reply(botMsg(
|
||||
"⚠️ Já existe uma sessão aberta.\n\n" +
|
||||
"Envie as mídias e depois use `!figurinha criar`.\n" +
|
||||
"Ou aguarde 2 minutos para a sessão expirar."
|
||||
));
|
||||
}
|
||||
|
||||
iniciarSessao(chatId, author);
|
||||
|
||||
iniciarSessao(groupId, author, msg);
|
||||
await msg.reply(botMsg(
|
||||
`Sessão de figurinha iniciada por @${author.split("@")[0]}. Envie no máximo 10 imagens, quando estiver pronto mande \`!figurinha criar\``,
|
||||
null,
|
||||
{ mentions: [author] }
|
||||
`✅ Sessão iniciada por *${name}*!\n\n` + help
|
||||
));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "!adivinhação":
|
||||
if (!tokens[1]) {
|
||||
await chat.sendMessage(botMsg("`!adivinhação começar`\n`!adivinhação parar`"));
|
||||
await chat.sendMessage(botMsg(
|
||||
"🎮 *Jogo de adivinhação:*\n\n" +
|
||||
"`!adivinhação começar` — inicia o jogo\n" +
|
||||
"`!adivinhação parar` — encerra o jogo"
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (tokens[1] === "começar") {
|
||||
iniciarJogo();
|
||||
await chat.sendMessage(botMsg("Jogo iniciado! Tente adivinhar o número de 1 a 100."));
|
||||
await chat.sendMessage(botMsg(
|
||||
"🎮 *Jogo iniciado!*\n\n" +
|
||||
"Estou pensando em um número de 1 a 100.\n" +
|
||||
"Tente adivinhar! 🤔"
|
||||
));
|
||||
log.ok("jogo iniciado");
|
||||
} else if (tokens[1] === "parar") {
|
||||
pararJogo();
|
||||
await chat.sendMessage(botMsg("Jogo parado."));
|
||||
await chat.sendMessage(botMsg("🛑 Jogo encerrado."));
|
||||
log.ok("jogo parado");
|
||||
} else {
|
||||
await chat.sendMessage(botMsg(
|
||||
`❌ Subcomando *${tokens[1]}* não existe.\n\n` +
|
||||
"Use `!adivinhação começar` ou `!adivinhação parar`."
|
||||
));
|
||||
log.warn("!adivinhação — subcomando desconhecido:", tokens[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case "!info":
|
||||
if (!tokens[1]) {
|
||||
await chat.sendMessage(botMsg("Use:\n`!info <comando>`"));
|
||||
return;
|
||||
}
|
||||
processarInfo(tokens[1], chat);
|
||||
log.ok("info →", tokens[1]);
|
||||
break;
|
||||
|
||||
case "!obrigado":
|
||||
case "!valeu":
|
||||
case "!brigado":
|
||||
await msg.reply(botMsg("Por nada!"));
|
||||
await msg.reply(botMsg("😊 Por nada!"));
|
||||
break;
|
||||
|
||||
case "a":
|
||||
@@ -124,6 +130,9 @@ export async function processarComando(msg, chat, chatId) {
|
||||
}
|
||||
} catch (err) {
|
||||
log.error("Falha em", cmd, "—", err.message);
|
||||
await chat.sendMessage(botMsg("Erro:\n`" + err.message + "`"));
|
||||
await chat.sendMessage(botMsg(
|
||||
"❌ Algo deu errado ao executar esse comando.\n" +
|
||||
"Tente novamente em instantes."
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,30 @@ import os from "os";
|
||||
const so = os.platform();
|
||||
|
||||
export async function get_audio(url, id) {
|
||||
const video = await get_video(url, id);
|
||||
const output = `downloads/${id}.mp3`;
|
||||
const cmd = so === "win32" ? ".\\bin\\ffmpeg.exe" : "./bin/ffmpeg";
|
||||
const args = ['-i', video, '-vn', '-acodec', 'libmp3lame', '-q:a', '2', output];
|
||||
const video = await get_video(url, id);
|
||||
const output = `downloads/${id}.mp3`;
|
||||
|
||||
await runCmd(cmd, args);
|
||||
return output;
|
||||
const cmd = so === "win32" ? ".\\bin\\ffmpeg.exe" : "./bin/ffmpeg";
|
||||
const args = ["-i", video, "-vn", "-acodec", "libmp3lame", "-q:a", "2", output];
|
||||
|
||||
await runCmd(cmd, args);
|
||||
return output;
|
||||
}
|
||||
|
||||
async function runCmd(cmd, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(cmd, args);
|
||||
proc.stdout.on("data", data => console.log("[cmd]", data.toString()));
|
||||
proc.stderr.on("data", data => console.error("[cmd ERR]", data.toString()));
|
||||
proc.on("close", code => code === 0 ? resolve() : reject(new Error("Processo saiu com código "+code)));
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(cmd, args);
|
||||
|
||||
proc.stdout.on("data", data => console.log("[cmd]", data.toString()));
|
||||
proc.stderr.on("data", data => console.error("[cmd ERR]", data.toString()));
|
||||
|
||||
proc.on("close", code => {
|
||||
if (code !== 0) {
|
||||
return reject(new Error(
|
||||
"Não foi possível converter o áudio. Tente novamente com outro link."
|
||||
));
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,42 +1,53 @@
|
||||
import { get_video } from "./video.js";
|
||||
import { get_audio } from "./audio.js";
|
||||
import pkg from "whatsapp-web.js";
|
||||
const { MessageMedia } = pkg;
|
||||
import fs from "fs";
|
||||
import { botMsg } from "../utils/botMsg.js";
|
||||
import { emptyFolder } from "../utils/file.js";
|
||||
import client from "../client/whatsappClient.js";
|
||||
|
||||
const { MessageMedia } = pkg;
|
||||
|
||||
let downloadQueue = [];
|
||||
let processingQueue = false;
|
||||
|
||||
export function enqueueDownload(type, url, msg, chatId) {
|
||||
downloadQueue.push({ type, url, msg, chatId });
|
||||
if (!processingQueue) processQueue();
|
||||
downloadQueue.push({ type, url, msg, chatId });
|
||||
if (!processingQueue) processQueue();
|
||||
}
|
||||
|
||||
async function processQueue() {
|
||||
processingQueue = true;
|
||||
while (downloadQueue.length) {
|
||||
const job = downloadQueue.shift();
|
||||
try {
|
||||
let path;
|
||||
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);
|
||||
processingQueue = true;
|
||||
|
||||
const file = fs.readFileSync(path);
|
||||
const media = new MessageMedia(
|
||||
job.type === "video" ? "video/mp4" : "audio/mpeg",
|
||||
file.toString("base64"),
|
||||
path.split("/").pop()
|
||||
);
|
||||
await client.sendMessage(job.chatId, media);
|
||||
fs.unlinkSync(path);
|
||||
emptyFolder("downloads");
|
||||
while (downloadQueue.length) {
|
||||
const job = downloadQueue.shift();
|
||||
const label = job.type === "video" ? "vídeo" : "áudio";
|
||||
|
||||
} catch (err) {
|
||||
await client.sendMessage(job.chatId, botMsg(`❌ Erro ao baixar ${job.type}\n\`${err.message}\``));
|
||||
}
|
||||
try {
|
||||
const filePath = job.type === "video"
|
||||
? await get_video(job.url, job.msg.id._serialized)
|
||||
: await get_audio(job.url, job.msg.id._serialized);
|
||||
|
||||
const file = fs.readFileSync(filePath);
|
||||
const media = new MessageMedia(
|
||||
job.type === "video" ? "video/mp4" : "audio/mpeg",
|
||||
file.toString("base64"),
|
||||
filePath.split("/").pop()
|
||||
);
|
||||
|
||||
await client.sendMessage(job.chatId, media);
|
||||
fs.unlinkSync(filePath);
|
||||
emptyFolder("downloads");
|
||||
|
||||
} catch (err) {
|
||||
console.error(`[queue] Erro ao baixar ${label}:`, err.message);
|
||||
await job.msg.reply(botMsg(
|
||||
`❌ Não consegui baixar o ${label}.\n\n` +
|
||||
"Verifique se o link é válido e tente novamente.\n" +
|
||||
"Se o problema persistir, o conteúdo pode estar indisponível ou protegido."
|
||||
));
|
||||
}
|
||||
processingQueue = false;
|
||||
}
|
||||
|
||||
processingQueue = false;
|
||||
}
|
||||
@@ -6,50 +6,54 @@ import os from "os";
|
||||
const platform = os.platform();
|
||||
|
||||
export async function get_video(url, id) {
|
||||
// garante que a pasta exista
|
||||
const downloadsDir = path.resolve("downloads");
|
||||
fs.mkdirSync(downloadsDir, { recursive: true });
|
||||
const downloadsDir = path.resolve("downloads");
|
||||
fs.mkdirSync(downloadsDir, { recursive: true });
|
||||
|
||||
const cmd = platform === "win32" ? ".\\bin\\yt-dlp.exe" : "./bin/yt-dlp";
|
||||
const args = [
|
||||
'--extractor-args', 'youtube:player_client=android',
|
||||
'-f', 'bv+ba/best',
|
||||
'--print', 'after_move:filepath',
|
||||
'--output', path.join(downloadsDir, `${id}.%(ext)s`),
|
||||
'--cookies', 'cookies.txt',
|
||||
'--add-header', 'User-Agent:Mozilla/5.0',
|
||||
'--add-header', 'Referer:https://www.youtube.com/',
|
||||
'--retries', '4',
|
||||
'--fragment-retries', '5',
|
||||
'--socket-timeout', '15',
|
||||
'--sleep-interval', '1', '--max-sleep-interval', '4',
|
||||
'--no-playlist',
|
||||
url
|
||||
];
|
||||
const cmd = platform === "win32" ? ".\\bin\\yt-dlp.exe" : "./bin/yt-dlp";
|
||||
const args = [
|
||||
"--extractor-args", "youtube:player_client=android",
|
||||
"-f", "bv+ba/best",
|
||||
"--print", "after_move:filepath",
|
||||
"--output", path.join(downloadsDir, `${id}.%(ext)s`),
|
||||
"--cookies", "cookies.txt",
|
||||
"--add-header", "User-Agent:Mozilla/5.0",
|
||||
"--add-header", "Referer:https://www.youtube.com/",
|
||||
"--retries", "4",
|
||||
"--fragment-retries", "5",
|
||||
"--socket-timeout", "15",
|
||||
"--sleep-interval", "1", "--max-sleep-interval", "4",
|
||||
"--no-playlist",
|
||||
url,
|
||||
];
|
||||
|
||||
return await runCmd(cmd, args);
|
||||
return await runCmd(cmd, args);
|
||||
}
|
||||
|
||||
async function runCmd(cmd, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(cmd, args);
|
||||
let stdout = "";
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(cmd, args);
|
||||
let stdout = "";
|
||||
|
||||
proc.stdout.on("data", data => stdout += data.toString());
|
||||
proc.stderr.on("data", data => console.error("[yt-dlp ERR]", data.toString()));
|
||||
proc.stdout.on("data", data => stdout += data.toString());
|
||||
proc.stderr.on("data", data => console.error("[yt-dlp ERR]", data.toString()));
|
||||
|
||||
proc.on("close", code => {
|
||||
if (code !== 0) return reject(new Error("yt-dlp saiu com código " + code));
|
||||
proc.on("close", code => {
|
||||
if (code !== 0) {
|
||||
return reject(new Error(
|
||||
"Não foi possível baixar o vídeo. Verifique se o link é válido e tente novamente."
|
||||
));
|
||||
}
|
||||
|
||||
// Pega a última linha, que é o caminho final do arquivo
|
||||
const lines = stdout.trim().split("\n").filter(l => l.trim());
|
||||
const filepath = lines[lines.length - 1];
|
||||
const lines = stdout.trim().split("\n").filter(l => l.trim());
|
||||
const filepath = lines[lines.length - 1];
|
||||
|
||||
if (!fs.existsSync(filepath)) {
|
||||
return reject(new Error("Arquivo não encontrado: " + filepath));
|
||||
}
|
||||
if (!fs.existsSync(filepath)) {
|
||||
return reject(new Error(
|
||||
"O download foi concluído, mas o arquivo não foi encontrado. Tente novamente."
|
||||
));
|
||||
}
|
||||
|
||||
resolve(filepath);
|
||||
});
|
||||
resolve(filepath);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -3,27 +3,33 @@ import { botMsg } from "../utils/botMsg.js";
|
||||
let jogoAtivo = null;
|
||||
|
||||
export function iniciarJogo() {
|
||||
jogoAtivo = Math.floor(Math.random()*100)+1;
|
||||
return jogoAtivo;
|
||||
jogoAtivo = Math.floor(Math.random() * 100) + 1;
|
||||
return jogoAtivo;
|
||||
}
|
||||
|
||||
export function pararJogo() {
|
||||
jogoAtivo = null;
|
||||
jogoAtivo = null;
|
||||
}
|
||||
|
||||
export async function processarJogo(msg, chat) {
|
||||
if (!jogoAtivo) return;
|
||||
if (!jogoAtivo) return;
|
||||
|
||||
const tentativa = msg.body.trim();
|
||||
if (!/^\d+$/.test(tentativa)) return;
|
||||
const tentativa = msg.body.trim();
|
||||
if (!/^\d+$/.test(tentativa)) return;
|
||||
|
||||
const num = parseInt(tentativa);
|
||||
if (num === jogoAtivo) {
|
||||
await msg.reply(botMsg(`Acertou! Número: ${jogoAtivo}`));
|
||||
pararJogo();
|
||||
} else if (num > jogoAtivo) {
|
||||
await chat.sendMessage(botMsg("Menor."));
|
||||
} else {
|
||||
await chat.sendMessage(botMsg("Maior."));
|
||||
}
|
||||
const num = parseInt(tentativa);
|
||||
|
||||
if (num === jogoAtivo) {
|
||||
await msg.reply(botMsg(
|
||||
`🎉 *Acertou!* O número era ${jogoAtivo}!\n\n` +
|
||||
"Use `!adivinhação começar` para jogar de novo."
|
||||
));
|
||||
pararJogo();
|
||||
} else if (num < 1 || num > 100) {
|
||||
await msg.reply(botMsg("⚠️ Digite um número entre 1 e 100."));
|
||||
} else if (num > jogoAtivo) {
|
||||
await chat.sendMessage(botMsg("📉 Tente um número *menor*!"));
|
||||
} else {
|
||||
await chat.sendMessage(botMsg("📈 Tente um número *maior*!"));
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ const logger = {
|
||||
: `${c.bold}${chatName}${c.reset} ${c.dim}(privado)${c.reset}`;
|
||||
|
||||
const bodyPreview = body?.trim()
|
||||
? `${isCommand ? c.yellow : c.green}"${body.length > 80 ? body.slice(0, 80) + "…" : body}"${c.reset}`
|
||||
? `${isCommand ? c.yellow : c.green}"${body.length > 200 ? body.slice(0, 200) + "..." : body}"${c.reset}`
|
||||
: `${c.dim}<${typeLabel}>${c.reset}`;
|
||||
|
||||
// Resolve reply
|
||||
@@ -70,7 +70,7 @@ const logger = {
|
||||
quotedName = quotedContact?.pushname || quotedContact?.formattedName || quotedNumber;
|
||||
} catch {}
|
||||
const quotedPreview = quoted.body?.trim()
|
||||
? `"${quoted.body.length > 60 ? quoted.body.slice(0, 60) + "…" : quoted.body}"`
|
||||
? `"${quoted.body.length > 80 ? quoted.body.slice(0, 80) + "…" : quoted.body}"`
|
||||
: `<${quoted.type}>`;
|
||||
replyLine =
|
||||
`\n${c.gray} ↩ Para: ${c.reset}${c.white}${quotedName}${c.reset} ${c.dim}+${quotedNumber}${c.reset}` +
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// get_id.js
|
||||
import { CLIENT_ID } from "../config.js";
|
||||
|
||||
|
||||
const arg = process.argv[2]; // argumento passado no node
|
||||
if (!arg) {
|
||||
@@ -12,8 +14,6 @@ import pkg from 'whatsapp-web.js';
|
||||
const { Client, LocalAuth } = pkg;
|
||||
import qrcode from 'qrcode-terminal';
|
||||
|
||||
const CLIENT_ID = "bot_permanente"; // sempre o mesmo
|
||||
|
||||
const client = new Client({
|
||||
authStrategy: new LocalAuth({ clientId: CLIENT_ID }),
|
||||
puppeteer: { headless: true }
|
||||
@@ -24,10 +24,10 @@ client.on('qr', qr => {
|
||||
qrcode.generate(qr, { small: true });
|
||||
});
|
||||
|
||||
client.on('ready', async () => {
|
||||
client.on('change_state', async state => {
|
||||
console.log("[WPP] Conectado");
|
||||
|
||||
const chats = await client.getChats(); // <- precisa do await
|
||||
const chats = await client.getChats();
|
||||
|
||||
let filtered = [];
|
||||
|
||||
@@ -40,18 +40,14 @@ client.on('ready', async () => {
|
||||
filtered = chats.filter(c => (c.name || c.id.user).toLowerCase().includes(search));
|
||||
}
|
||||
|
||||
if (filtered.length === 0) {
|
||||
console.log("Nenhum chat encontrado com esse filtro.");
|
||||
} else {
|
||||
console.log(`Encontrados ${filtered.length} chats:`);
|
||||
filtered.forEach(c => {
|
||||
console.log("================================");
|
||||
console.log("NAME:", c.name || c.id.user);
|
||||
console.log("ID:", c.id._serialized);
|
||||
console.log("GROUP:", c.isGroup);
|
||||
});
|
||||
}
|
||||
filtered.forEach(c => {
|
||||
console.log("================================");
|
||||
console.log("NAME:", c.name || c.id.user);
|
||||
console.log("ID:", c.id._serialized);
|
||||
console.log("GROUP:", c.isGroup);
|
||||
});
|
||||
|
||||
await client.destroy();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user