Zrzur المطوّرون

بوت إشراف

/timeout و/purge مع الفحوص التي يحتاج إليها بوت الإشراف.

قبل أن تبدأ

أنشئ تطبيقًا وثبّته في سيرفر اختبار واضبط ثلاثة متغيرات بيئة (انظر شغّل بوتك):

export ZRZUR_BOT_TOKEN=YOUR_BOT_TOKEN
export ZRZUR_API_URL=https://api.zrzur.com
export ZRZUR_WS_URL=wss://events.zrzur.com

الكود

// Moderation: /timeout and /purge. The server checks the bot's own
// permissions and role order; the bot checks the person who asked, using the
// permissions that come with every interaction.

import { ApiError, Client } from "@zrzur/sdk/bot";

const bot = new Client({
  token: process.env.ZRZUR_BOT_TOKEN,
  apiUrl: process.env.ZRZUR_API_URL,
  wsUrl: process.env.ZRZUR_WS_URL,
});

// Permission bits (see "Roles and permissions")
const TIMEOUT_MEMBERS = 1n << 8n;
const MANAGE_MESSAGES = 1n << 23n;

/** Does the invoking member hold `bit` in this channel? */
const can = (i, bit) => (BigInt(i.raw.user_permissions) & bit) === bit;

function refuse(i, error) {
  const text =
    error instanceof ApiError &&
    ["MissingPermission", "NotElevated"].includes(error.type)
      ? "I am not allowed to do that here (check my role and its position)."
      : "Something went wrong.";
  return i.acknowledged
    ? i.editReply(text)
    : i.reply({ content: text, ephemeral: true });
}

bot.command("timeout", async (i) => {
  if (!can(i, TIMEOUT_MEMBERS))
    return i.reply({ content: "You need Timeout Members.", ephemeral: true });
  const user = i.option("user");
  const minutes = i.option("minutes") ?? 10;
  try {
    await bot.members.timeout(i.serverId, user, minutes * 60);
    await i.reply({
      content: `<@${user}> is timed out for ${minutes} minutes.`,
      ephemeral: true,
    });
  } catch (error) {
    await refuse(i, error);
  }
});

bot.command("purge", async (i) => {
  if (!can(i, MANAGE_MESSAGES))
    return i.reply({ content: "You need Manage Messages.", ephemeral: true });
  await i.defer({ ephemeral: true });
  try {
    const messages = await bot.messages.fetchMany(i.channelId, {
      limit: i.option("count") ?? 10,
    });
    // bulk delete only takes messages younger than a week
    const weekAgo = Date.now() - 7 * 24 * 3600 * 1000;
    const ids = messages
      .filter((m) => idTime(m._id) > weekAgo)
      .map((m) => m._id);
    if (ids.length) await bot.messages.bulkDelete(i.channelId, ids);
    await i.editReply(`Deleted ${ids.length} messages.`);
  } catch (error) {
    await refuse(i, error);
  }
});

/** Milliseconds encoded in the first 10 characters of an id (ULID) */
function idTime(id) {
  const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
  return [...id.slice(0, 10)].reduce(
    (time, char) => time * 32 + alphabet.indexOf(char),
    0,
  );
}

await bot.login();
await bot.syncCommands([
  {
    name: "timeout",
    description: "Time out a member",
    options: [
      { type: "User", name: "user", description: "Member", required: true },
      {
        type: "Integer",
        name: "minutes",
        description: "Minutes",
        min_value: 1,
        max_value: 10080,
      },
    ],
  },
  {
    name: "purge",
    description: "Delete recent messages",
    options: [
      {
        type: "Integer",
        name: "count",
        description: "How many",
        min_value: 1,
        max_value: 100,
      },
    ],
  },
]);
console.log("ready");

شغّله بالأمر node moderation.mjs.

جرّبه

امنح البوت Timeout Members وManage Messages، وارفع دوره فوق الأعضاء الذين يشرف عليهم.

ما يوضحه