const INTERVAL_MS = 2 * 60 * 60 * 1000; // every 2 hours const ANSWER_WINDOW_MS = 10 * 60 * 1000; // 10 minutes to answer before auto-delete const REWARD = 1000000; // $1M let cachedApi = null; const pendingQuestions = new Map(); // messageID -> { threadID, answer, timeoutHandle } function randInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function generateQuestion() { const lang = Math.random() < 0.5 ? "en" : "bn"; const opPick = ["add", "sub", "mul", "div"][randInt(0, 3)]; let a, b, answer, opSymbol; if (opPick === "add") { a = randInt(10, 500); b = randInt(10, 500); answer = a + b; opSymbol = "+"; } else if (opPick === "sub") { a = randInt(50, 900); b = randInt(1, a); answer = a - b; opSymbol = "-"; } else if (opPick === "mul") { a = randInt(2, 30); b = randInt(2, 30); answer = a * b; opSymbol = "ร—"; } else { b = randInt(2, 20); answer = randInt(2, 50); a = b * answer; opSymbol = "รท"; } const text = lang === "en" ? `๐Ÿงฎ What is ${a} ${opSymbol} ${b}?` : `๐Ÿงฎ ${a} ${opSymbol} ${b} = เฆ•เฆค?`; return { text, answer }; } function buildBroadcastMsg(q) { return `๐Ÿ”” ๐— ๐—”๐—ง๐—› ๐—–๐—›๐—”๐—Ÿ๐—Ÿ๐—˜๐—ก๐—š๐—˜! ${q.text} ๐Ÿ’ฐ First correct REPLY wins: $${REWARD.toLocaleString()} โ†ฉ๏ธ Reply to THIS message with the number! โณ 10 minutes โ€” unanswered questions self-delete.`; } function cleanupQuestion(messageID) { const pending = pendingQuestions.get(messageID); if (!pending) return; if (pending.timeoutHandle) clearTimeout(pending.timeoutHandle); pendingQuestions.delete(messageID); if (global.GoatBot?.onReply) global.GoatBot.onReply.delete(messageID); } function scheduleExpiry(messageID) { return setTimeout(async () => { const pending = pendingQuestions.get(messageID); if (!pending) return; cleanupQuestion(messageID); if (cachedApi) { try { await cachedApi.unsendMessage(messageID); } catch (err) { console.error("AutoQuestion: failed to auto-delete expired question:", err.message); } } }, ANSWER_WINDOW_MS); } async function sendQuestionToThread(threadID) { if (!cachedApi) return; const q = generateQuestion(); try { const info = await cachedApi.sendMessage(buildBroadcastMsg(q), threadID); if (!info || !info.messageID) return; global.GoatBot.onReply.set(info.messageID, { commandName: "autoquestion", messageID: info.messageID, answer: q.answer }); pendingQuestions.set(info.messageID, { threadID, answer: q.answer, timeoutHandle: scheduleExpiry(info.messageID) }); } catch (err) { console.error(`AutoQuestion: failed to send to ${threadID}:`, err.message); } } function broadcastToAllThreads() { if (!cachedApi) return; const allThreads = (global.db && global.db.allThreadData) || []; for (const t of allThreads) { sendQuestionToThread(t.threadID); } } // Timer starts as soon as the module loads; it just waits for cachedApi // to become available (set on the first message the bot sees). setInterval(broadcastToAllThreads, INTERVAL_MS); module.exports = { config: { name: "autoquestion", aliases: ["aq", "mathquiz"], version: "2.0.0", author: "๐‘จ๐‘น๐‘ฐ๐’€๐‘จ๐‘ต", countDown: 3, role: 0, category: "Fun", description: "๐Ÿ”” Auto-broadcasts a math question to every group every 2 hours", guide: "{pn} status - Show system info\n{pn} test - (admin) Force-send a question to this chat now" }, onStart: async function ({ args, message, event, api }) { if (!cachedApi) cachedApi = api; const sub = args[0]?.toLowerCase(); if (sub === "test") { const adminBotList = (global.GoatBot?.config?.adminBot || []).map(String); if (!adminBotList.includes(String(event.senderID))) { return message.reply("โŒ Only bot admins can force-send a test question."); } return sendQuestionToThread(event.threadID); } return message.reply( `๐Ÿ”” Auto Math Question System โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” โ€ข Runs every 2 hours in every active group โ€ข Reply to the question with the correct number โ€” first correct reply wins $${REWARD.toLocaleString()} โ€ข Questions are randomly generated (English/Bangla mixed) โ€” never repeat verbatim โ€ข Unanswered after 10 minutes โ†’ message auto-deletes` ); }, onReply: async function ({ event, api, Reply, usersData, message }) { if (!Reply || Reply.commandName !== "autoquestion") return; if (!cachedApi) cachedApi = api; const pending = pendingQuestions.get(Reply.messageID); if (!pending) return; // already answered or expired const submitted = parseInt(String(event.body || "").trim()); if (isNaN(submitted) || submitted !== Reply.answer) return; // wrong guess, let others keep trying // Correct! First reply wins โ€” clean up immediately so late replies can't also win. cleanupQuestion(Reply.messageID); const userData = await usersData.get(event.senderID) || {}; const newBalance = (userData.money || 0) + REWARD; await usersData.set(event.senderID, { money: newBalance }); let winnerName = "Someone"; try { const info = await api.getUserInfo(event.senderID); winnerName = info?.[event.senderID]?.name || winnerName; } catch (err) { /* ignore */ } return message.reply( `๐ŸŽ‰ CORRECT! ${winnerName} got it first! โœ… Answer: ${Reply.answer} ๐Ÿ’ฐ Won: $${REWARD.toLocaleString()} ๐Ÿ’ณ New Balance: $${newBalance.toLocaleString()}` ); } };