RnDAO/tc-botComm

View on GitHub
index.js

Summary

Maintainability
A
0 mins
Test Coverage
const fs = require("node:fs");const path = require("node:path");
const {
  fetchSettings,
  updateGuild,
  getRange,
} = require("./database/dbservice.js");

const { connectDB, removeConnection } = require("./database/connection");
const {
  trackMessages,
  updateChannelInfo,
  updateAccountInfo,
} = require("./action/export.js");

const { Client, Intents } = require("discord.js");
require("dotenv").config();

const intents = new Intents(32767);
const client = new Client({ intents });

// login to discord
const discordLogin = async () => {
  const eventsPath = path.join(__dirname, "events");
  const eventFiles = fs
    .readdirSync(eventsPath)
    .filter((file) => file.endsWith(".js"));

  client.once("ready", () => {
    console.log(`Ready! Logged in as ${client.user.tag}`);
    // once discord bot login then extract
    extract();
  });
  await client.login(process.env.TOKEN);
};

/**
 * @feature Track messages from discord between given time range
 * @feature Insert messages rawinfo into database
 * @feature Update account information
 */
const messageAction = async (setting) => {
  const { guildId, selectedChannels, period } = setting;
  try {
    const channels = selectedChannels.map((item) => item.channelId);
    const guild = await client.guilds.fetch(guildId);
    const date = new Date(period);
    const timeStamp = date.getTime();
    const storedIdRange = await getRange(guild.id);
    const [before, after] = [
      storedIdRange[0]?.messageId,
      storedIdRange[1]?.messageId,
    ];
    const messages = await trackMessages(guild, null, "channels", {
      channels: channels,
      since: timeStamp,
      before,
      after,
    });
    return messages;
  } catch (e) {
    console.log(e);
    return [];
  }
};

// check the bot is connected to the guilds and update status
const checkBotStatus = async (settings) => {
  const promises = settings.map(async (setting) => {
    const { guildId } = setting;
    const guild = client.guilds.cache.get(guildId);
    if (!guild) {
      setting.isDisconnected = true;
      await updateGuild(guildId, setting);
    }
  });
  return await Promise.all(promises);
};

// toggle bot status when extracting and after that
const toggleExtraction = async (setting, status) => {
  const { guildId } = setting;
  setting.isInProgress = status;
  await updateGuild(guildId, setting);
};

// get guildid from command
const getGuildFromCmd = () => {
  const args = process.argv.slice(2);

  const portArg = args.find((arg) => arg.startsWith("--guild="));
  const guild = portArg ? portArg.split("=")[1] : null;
  return guild;
};

// extract messages from connected servers
const extract = async () => {
  // only fetch connected guilds
  const customGuildId = getGuildFromCmd();
  const settings = await fetchSettings(customGuildId);
  await checkBotStatus(settings);
  console.info(settings.length, "connected discord servers");

  for (const setting of settings) {
    const { guildId, name } = setting;
    console.info("start extraction from ", name);

    console.info("make isProgress true in this server");
    await toggleExtraction(setting, true);

    console.info("sync channel id and channel name");
    await updateChannelInfo(client, guildId);

    console.info("sync account information");
    await updateAccountInfo(client, guildId);

    console.info("tracking messages from discord server ", name);
    await messageAction(setting);

    console.info("make isProgress false in this server");
    await toggleExtraction(setting, false);

    removeConnection(guildId);
  }
  process.exit(0);
};

/**
 * extract messages from guild setting
 * input: npm start -- --guild=853132782821703751       -> extract messages from only one guild(853132782821703751)
 *        npm start                                     -> extract messages from all guilds
 */
const app = async () => {
  await connectDB();
  await discordLogin();
};

app();