presenceBot.js

 avatar
unknown
javascript
10 months ago
4.9 kB
5
Indexable
const { Client, GatewayIntentBits, EmbedBuilder } = require("discord.js");
const { Pool } = require("pg");
const fs = require("fs");
const cron = require("node-cron");

const config = JSON.parse(fs.readFileSync("config.json", "utf-8"));
const {
  DB_USER,
  DB_PASSWORD,
  DB_DATABASE,
  DB_HOST,
  DESTINATION_CHANNEL_ID,
  TEXT_CHANNEL_ID,
} = config;

const INTERVALS = [
  {
    start: "10:04",
    end: "10:06",
    title: "Players WB Lab. Manhã:",
    wb_interval: "Lab Manhã",
  },
  {
    start: "12:04",
    end: "12:05",
    title: "Players WB Vales Manhã:",
    wb_interval: "Vales Manhã",
  },
  {
    start: "20:04",
    end: "20:05",
    title: "Players WB Lab. Noite:",
    wb_interval: "Lab Noite",
  },
  {
    start: "22:04",
    end: "22:05",
    title: "Players WB Vales Noite:",
    wb_interval: "Vales Noite",
  },
  {
    start: "23:04",
    end: "23:05",
    title: "Players WB Mina:",
    wb_interval: "Mina Abandonada",
  },
];

const MAX_MEMBERS_PER_FIELD = 25;

class PresenceBot {
  constructor() {
    this.client = new Client({
      intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildVoiceStates,
        GatewayIntentBits.MessageContent,
      ],
    });

    this.pool = new Pool({
      user: DB_USER,
      host: DB_HOST,
      database: DB_DATABASE,
      password: DB_PASSWORD,
      port: 5432,
    });

    this.setupEvents();
    this.setupCronJobs();
  }

  setupEvents() {
    this.client.once("ready", () => {
      console.log(`Logged in as ${this.client.user.tag}`);
      this.checkUsers.start();
    });

    this.client.login(config.BOT_TOKEN);
  }

  setupCronJobs() {
    this.sentEmbeds = new Set();
    this.registeredUsers = new Map();

    this.checkUsers = cron.schedule("* * * * *", async () => {
      const now = new Date();
      const currentTime = now.toTimeString().slice(0, 5);

      for (const { start, end, title, wb_interval } of INTERVALS) {
        const isWithinInterval = currentTime >= start && currentTime <= end;

        if (isWithinInterval && !this.sentEmbeds.has(wb_interval)) {
          this.sentEmbeds.add(wb_interval);

          const destinationChannel = await this.client.channels.fetch(
            DESTINATION_CHANNEL_ID
          );
          if (!destinationChannel) {
            console.log("Destination channel not found.");
            return;
          }

          const membersList = Array.from(
            destinationChannel.members.values()
          ).map((member) => member.nickname || member.user.username);

          if (!membersList.length) return;

          const currentRegistered =
            this.registeredUsers.get(wb_interval) || new Set();

          for (const member of destinationChannel.members.values()) {
            const memberId = member.user.id;

            if (!currentRegistered.has(memberId)) {
              await this.registerPresence(member, wb_interval);
              currentRegistered.add(memberId);
            }
          }

          this.registeredUsers.set(wb_interval, currentRegistered);

          await this.sendEmbeds(title, membersList, currentTime);
        } else if (currentTime > end) {
          this.sentEmbeds.delete(wb_interval);
          this.registeredUsers.delete(wb_interval);
        }
      }
    });
  }

  async sendEmbeds(title, membersList, footerText) {
    const embedChunks = [];
    const memberChunks = [];

    for (let i = 0; i < membersList.length; i += MAX_MEMBERS_PER_FIELD) {
      memberChunks.push(membersList.slice(i, i + MAX_MEMBERS_PER_FIELD));
    }

    // Número inicial para a contagem
    let userIndex = 1;

    memberChunks.forEach((chunk, i) => {
      const embed = new EmbedBuilder()
        .setTitle(title)
        .setDescription("[🔗Veja o ranking do WB aqui](https:/site.com)")
        .addFields({
          name: `Members (part ${i + 1} of ${memberChunks.length})`,
          value: chunk
            .map((member) => `\`${userIndex++}. ${member}\``)
            .join("\n"),
        })
        .setFooter({
          text: `${footerText} - Part ${i + 1}/${memberChunks.length}`,
        });

      embedChunks.push(embed);
    });

    const textChannel = await this.client.channels.fetch(TEXT_CHANNEL_ID);
    for (const embed of embedChunks) {
      await textChannel.send({ embeds: [embed] });
    }
  }

  async registerPresence(member, wb_interval) {
    const horario = new Date();
    const memberName = member.nickname || member.user.username;

    const query =
      "INSERT INTO presenca (usuario_id, wb_interval, horario) VALUES ($1, $2, $3)";
    await this.pool.query(query, [memberName, wb_interval, horario]);
  }
}

module.exports = PresenceBot;
Editor is loading...
Leave a Comment