← back to browse
goat command

autoquestion

๐Ÿ”” Auto-broadcasts a math question to every group every 2 hours

0
views
0
likes
0
installs

Aliases: aq, mathquiz

raw source
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()}`
    );
  }
};

View raw file