RnDAO/tc-botComm

View on GitHub
action/export.js

Summary

Maintainability
C
1 day
Test Coverage
const {
  updateChannel,
  updateAccount,
  processMessages,
} = require("../database/dbservice.js");

/**
 * @dev fetch messages by filter
 * @param guild discord guild
 * @param channel current channel
 * @param type message type. can be an element of ["channels", "date"]
 * @param limit limit fetching messages
 * @param since filtering param by date
 * @param channels filtering param by channel
 * @return messages
 */
const trackMessages = async (
  guild,
  channel,
  type,
  { since = null, channels = null, before, after } = {}
) => {
  let sum_messages = []; // for collecting messages
  if (type === "channels") {
    const channelList = channels;
    // iterate all channels
    const promises = guild.channels.cache.map(async (channel) => {
      const channelId = channel.id;
      if (
        (channel.type === "GUILD_TEXT" || channel.type === "GUILD_VOICE") &&
        (channels == null || channelList.includes(channelId))
      ) {
        try {
          //fetch all messages from the channel
          await trackMessages(guild, channel, "date", {
            since: since,
            before: before,
            after: after,
          });
          // there are only threads in text channel, not in voice channel
          if (channel.type === "GUILD_TEXT") {
            const threads = channel.threads.cache;
            // iterate all threads
            const threadPromises = threads.map(async (thread) => {
              // fetch messages from thread
              await fetchMessages(guild, thread, "date", {
                since: since,
                before: before,
                after: after,
              });
            });
            await Promise.all(threadPromises);
          }
        } catch (e) {
          // bot doesn't have access to channel.
          // console.log(e);
        }
      }
    });
    await Promise.all(promises);
    return sum_messages;
  }
  // extract recent messages from one channel
  before = after = null;
  let last_id = after;
  while (true && after != null) {
    const options = { limit: 100 };
    if (last_id) {
      options.after = last_id;
    }
    let messages = [];
    try {
      const messagesMap = await channel.messages.fetch(options);
      messages = Array.from(messagesMap, ([id, value]) => ({ id, value }));
    } catch (e) {
      // console.log(e);
    }
    if (messages.length === 0) break;
    await processMessages(guild.id, messages);
    last_id = messages[0].id;
  }
  last_id = before;
  // extract old messages from one channel
  while (true) {
    // split for number of messages to fetch with limit
    const options = { limit: 100 };
    if (last_id) {
      options.before = last_id;
    }
    let messages = [];
    try {
      const messagesMap = await channel.messages.fetch(options);
      messages = Array.from(messagesMap, ([id, value]) => ({ id, value }));
    } catch (e) {
      // console.log(e);
    }
    if (messages.length === 0) return sum_messages;
    for (let i = 0; i < messages.length; i++) {
      if (messages[i].value.createdTimestamp < since) {
        await processMessages(guild.id, messages.slice(0, i));
        return; // will return here
      }
    }
    await processMessages(guild.id, messages);
    last_id = messages[messages.length - 1].id;
  }
};

/**
 * @dev send dm to user
 * @param client discord client
 * @param userId id of target user
 * @param message message to be sent
 */
const sendDMtoUser = async (client, userId, message) => {
  try {
    const targetUser = await client.users.fetch(userId);
    console.log(targetUser);
    targetUser
      .send(message)
      .then(() => {
        console.log(
          `Message Sent to ${targetUser.username}#${targetUser.discriminator}`
        );
      })
      .catch((e) => {
        throw e;
      });
  } catch (e) {
    console.log("Can't DM to user", e);
  }
};

/**
 * @dev sync channel id and channel name
 * @param client discord client
 * @param guildId id of guild
 */
const updateChannelInfo = async (client, guildId) => {
  try {
    const guild = client.guilds.cache.get(guildId);
    if (guild) {
      const channels = guild.channels.cache.filter(
        (channel) =>
          channel.type === "GUILD_TEXT" || channel.type === "GUILD_VOICE"
      );
      channels.map(async (channel) => {
        const { id, name } = channel;
        await updateChannel(guildId, id, name);
      });
    }
  } catch (e) {
    console.log("Error in updating channel info", e);
  }
};

/**
 * @dev sync channel id and channel name
 * @param client discord client
 * @param guildId id of guild
 */
const updateAccountInfo = async (client, guildId) => {
  try {
    const guild = client.guilds.cache.get(guildId);
    const accounts = await guild.members.fetch();
    const promises = accounts.map(async (member) => {
      await updateAccount(guildId, member);
    });
    await Promise.all(promises);
  } catch (e) {
    console.log("Error in updating account info", e);
  }
};
module.exports = {
  trackMessages,
  sendDMtoUser,
  updateChannelInfo,
  updateAccountInfo,
};