add userinfo
This commit is contained in:
		
							parent
							
								
									017c1839fc
								
							
						
					
					
						commit
						6717e96dfe
					
				
					 1 changed files with 323 additions and 0 deletions
				
			
		
							
								
								
									
										323
									
								
								src/modules/utility/userinfo.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								src/modules/utility/userinfo.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,323 @@
 | 
			
		|||
const Command = require("@lib/command.js");
 | 
			
		||||
 | 
			
		||||
const {
 | 
			
		||||
  ActivityTypeNames,
 | 
			
		||||
  APIEndpoints,
 | 
			
		||||
  ApplicationFlags,
 | 
			
		||||
  BadgeURLs,
 | 
			
		||||
  CDNEndpoints,
 | 
			
		||||
  UserFlags,
 | 
			
		||||
} = require("@util/dconstants.js");
 | 
			
		||||
const {
 | 
			
		||||
  RegExp: {Snowflake: SNOWFLAKE_REGEX},
 | 
			
		||||
  Icons,
 | 
			
		||||
} = require("@util/constants.js");
 | 
			
		||||
 | 
			
		||||
const {formatUsername, getDefaultAvatar} = require("@util/misc.js");
 | 
			
		||||
const {snowflakeToTimestamp} = require("@util/time.js");
 | 
			
		||||
 | 
			
		||||
const ONE_MONTH = 2628000;
 | 
			
		||||
 | 
			
		||||
const userinfo = new Command("userinfo");
 | 
			
		||||
userinfo.category = "utility";
 | 
			
		||||
userinfo.helpText = "Get information on a user";
 | 
			
		||||
userinfo.usage = "<user id>";
 | 
			
		||||
userinfo.addAlias("user");
 | 
			
		||||
userinfo.addAlias("uinfo");
 | 
			
		||||
userinfo.addAlias("ui");
 | 
			
		||||
userinfo.addAlias("profile");
 | 
			
		||||
userinfo.addAlias("whois");
 | 
			
		||||
userinfo.callback = async function (msg, line) {
 | 
			
		||||
  let id;
 | 
			
		||||
  if (!line || line == "") {
 | 
			
		||||
    id = msg.author.id;
 | 
			
		||||
  } else {
 | 
			
		||||
    if (!SNOWFLAKE_REGEX.test(line)) return "Not a snowflake.";
 | 
			
		||||
    id = line.match(SNOWFLAKE_REGEX)[1];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!id) return "Failed to get ID somehow.";
 | 
			
		||||
 | 
			
		||||
  let user;
 | 
			
		||||
  try {
 | 
			
		||||
    user = await hf.bot.requestHandler.request("GET", APIEndpoints.USER(id), false);
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    if (err.code == 10013) {
 | 
			
		||||
      return "User not found.";
 | 
			
		||||
    } else {
 | 
			
		||||
      return `${Icons.silk.error} Failed to get user:\n\`\`\`\n${err}\`\`\``;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!user) return `${Icons.silk.error} Failed to get user without erroring.`;
 | 
			
		||||
 | 
			
		||||
  let guild, member;
 | 
			
		||||
  if (msg.guildID) {
 | 
			
		||||
    guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID);
 | 
			
		||||
    member = guild.members.get(id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // FIXME: horrible, probably needs to be moved out of this function for later
 | 
			
		||||
  const badges = [];
 | 
			
		||||
 | 
			
		||||
  if ((user.flags & UserFlags.STAFF) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.staff}](${BadgeURLs.staff})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.PARTNER) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.partner}](${BadgeURLs.partner})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.CERTIFIED_MODERATOR) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.certified_moderator}](${BadgeURLs.certified_moderator})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.HYPESQUAD) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.hypesquad}](${BadgeURLs.hypesquad})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.HYPESQUAD_ONLINE_HOUSE_1) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.hypesquad_house_1}](${BadgeURLs.hypesquad_house_1})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.HYPESQUAD_ONLINE_HOUSE_2) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.hypesquad_house_2}](${BadgeURLs.hypesquad_house_2})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.HYPESQUAD_ONLINE_HOUSE_3) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.hypesquad_house_3}](${BadgeURLs.hypesquad_house_3})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.BUG_HUNTER_LEVEL_1) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.bug_hunter_level_1}](${BadgeURLs.bug_hunter_level_1})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.BUG_HUNTER_LEVEL_2) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.bug_hunter_level_2}](${BadgeURLs.bug_hunter_level_2})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.ACTIVE_DEVELOPER) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.active_developer}](${BadgeURLs.active_developer})`);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.VERIFIED_DEVELOPER) !== 0) {
 | 
			
		||||
    badges.push(Icons.badges.verified_developer);
 | 
			
		||||
  }
 | 
			
		||||
  if ((user.flags & UserFlags.PREMIUM_EARLY_SUPPORTER) !== 0) {
 | 
			
		||||
    badges.push(`[${Icons.badges.early_supporter}](${BadgeURLs.early_supporter})`);
 | 
			
		||||
  }
 | 
			
		||||
  if (user.banner || user.avatar.startsWith("a_")) {
 | 
			
		||||
    badges.push(`[${Icons.badges.premium}](${BadgeURLs.premium})`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let boosting = member?.premiumSince;
 | 
			
		||||
  let anyMember = member;
 | 
			
		||||
  if (!boosting) {
 | 
			
		||||
    for (const g of hf.bot.guilds.values()) {
 | 
			
		||||
      const m = g.members.get(id);
 | 
			
		||||
      if (!boosting && m?.premiumSince) {
 | 
			
		||||
        boosting = m.premiumSince;
 | 
			
		||||
        anyMember = m;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!anyMember) {
 | 
			
		||||
    for (const g of hf.bot.guilds.values()) {
 | 
			
		||||
      const m = g.members.get(id);
 | 
			
		||||
      if (m != null) {
 | 
			
		||||
        anyMember = m;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (boosting) {
 | 
			
		||||
    let icon = Icons.badges.guild_booster_lvl1;
 | 
			
		||||
    const delta = Date.now() - Math.floor(boosting / 1000);
 | 
			
		||||
    if (delta >= ONE_MONTH * 2) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl2;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 3) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl3;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 6) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl4;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 9) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl5;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 12) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl6;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 15) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl7;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 18) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl8;
 | 
			
		||||
    }
 | 
			
		||||
    if (delta >= ONE_MONTH * 24) {
 | 
			
		||||
      icon = Icons.badges.guild_booster_lvl9;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    badges.push(`[${icon}](${BadgeURLs.premium})`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let botDeleted = false;
 | 
			
		||||
  if (user.bot) {
 | 
			
		||||
    try {
 | 
			
		||||
      const app = await hf.bot.requestHandler.request("GET", APIEndpoints.APPLICATION_RPC(id), false);
 | 
			
		||||
 | 
			
		||||
      if ((app.flags & ApplicationFlags.APPLICATION_COMMAND_BADGE) !== 0) {
 | 
			
		||||
        badges.push(`[${Icons.badges.bot_commands}](${BadgeURLs.bot_commands})`);
 | 
			
		||||
      }
 | 
			
		||||
      if ((app.flags & ApplicationFlags.AUTO_MODERATION_RULE_CREATE_BADGE) !== 0) {
 | 
			
		||||
        badges.push(Icons.badges.automod);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      if (err.code == 10002) {
 | 
			
		||||
        botDeleted = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (user.avatar_decoration_data?.expires_at || user.avatar_decoration_data?.sku_id == "1226939756617793606") {
 | 
			
		||||
    badges.push(`[${Icons.badges.quest_completed}](${BadgeURLs.quest_completed})`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const defaultAvatar = getDefaultAvatar(id, user.discriminator ?? 0);
 | 
			
		||||
  const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(id, user.avatar) : defaultAvatar;
 | 
			
		||||
 | 
			
		||||
  const banner = user.banner && CDNEndpoints.BANNER(id, user.banner);
 | 
			
		||||
 | 
			
		||||
  const images = [];
 | 
			
		||||
 | 
			
		||||
  const avatarRes = await fetch(avatar, {method: "HEAD"});
 | 
			
		||||
  const avatarMod = avatarRes.headers.get("last-modified");
 | 
			
		||||
  let avatarUrl = `[Avatar](${avatar})`;
 | 
			
		||||
  if (avatarMod && avatar != defaultAvatar) {
 | 
			
		||||
    const modDate = Math.floor(new Date(avatarMod).getTime() / 1000);
 | 
			
		||||
    avatarUrl += ` \u2022 Updated <t:${modDate}:R>`;
 | 
			
		||||
  }
 | 
			
		||||
  images.push(avatarUrl);
 | 
			
		||||
 | 
			
		||||
  if (banner) {
 | 
			
		||||
    const bannerRes = await fetch(banner, {method: "HEAD"});
 | 
			
		||||
    const bannerMod = bannerRes.headers.get("last-modified");
 | 
			
		||||
    let bannerUrl = `[Banner](${banner})`;
 | 
			
		||||
    if (bannerMod) {
 | 
			
		||||
      const modDate = Math.floor(new Date(bannerMod).getTime() / 1000);
 | 
			
		||||
      bannerUrl += ` \u2022 Updated <t:${modDate}:R>`;
 | 
			
		||||
    }
 | 
			
		||||
    images.push(bannerUrl);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const guildImages = [];
 | 
			
		||||
  if (member) {
 | 
			
		||||
    const guildAvatar = member.avatar && CDNEndpoints.GUILD_MEMBER_AVATAR(msg.guildID, id, member.avatar);
 | 
			
		||||
    if (guildAvatar) {
 | 
			
		||||
      const avatarRes = await fetch(guildAvatar, {method: "HEAD"});
 | 
			
		||||
      const avatarMod = avatarRes.headers.get("last-modified");
 | 
			
		||||
      let avatarUrl = `[Guild Avatar](${guildAvatar})`;
 | 
			
		||||
      if (avatarMod) {
 | 
			
		||||
        const modDate = Math.floor(new Date(avatarMod).getTime() / 1000);
 | 
			
		||||
        avatarUrl += ` \u2022 Updated <t:${modDate}:R>`;
 | 
			
		||||
      }
 | 
			
		||||
      guildImages.push(avatarUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const memberObj = await hf.bot.requestHandler.request("GET", APIEndpoints.GUILD_MEMBER(msg.guildID, id), true);
 | 
			
		||||
    const guildBanner = memberObj.banner && CDNEndpoints.GUILD_MEMBER_BANNER(msg.guildID, id, memberObj.banner);
 | 
			
		||||
    if (guildBanner) {
 | 
			
		||||
      const bannerRes = await fetch(guildBanner, {method: "HEAD"});
 | 
			
		||||
      const bannerMod = bannerRes.headers.get("last-modified");
 | 
			
		||||
      let bannerUrl = `[Guild Banner](${guildBanner})`;
 | 
			
		||||
      if (bannerMod) {
 | 
			
		||||
        const modDate = Math.floor(new Date(bannerMod).getTime() / 1000);
 | 
			
		||||
        bannerUrl += ` \u2022 Updated <t:${modDate}:R>`;
 | 
			
		||||
      }
 | 
			
		||||
      guildImages.push(bannerUrl);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const shared = Array.from(hf.bot.guilds.values()).filter((g) => g.members.get(id) != null);
 | 
			
		||||
 | 
			
		||||
  const descLines = [];
 | 
			
		||||
  if (badges.length > 0) {
 | 
			
		||||
    descLines.push(badges.join(""));
 | 
			
		||||
  }
 | 
			
		||||
  if (botDeleted) {
 | 
			
		||||
    descLines.push("*This bot's application has been deleted*");
 | 
			
		||||
  }
 | 
			
		||||
  if (user.clan) {
 | 
			
		||||
    // TODO: badge emojis via color aproximation of the default presets
 | 
			
		||||
    descLines.push(`**${user.clan.tag}** (\`${user.clan.identity_guild_id}\`)`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (anyMember) {
 | 
			
		||||
    const icons = [];
 | 
			
		||||
    for (const platform of Object.keys(anyMember.clientStatus)) {
 | 
			
		||||
      const status = anyMember.clientStatus[platform];
 | 
			
		||||
      if (status == "offline") continue;
 | 
			
		||||
 | 
			
		||||
      icons.push(Icons.presence[platform][status]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    descLines.push("");
 | 
			
		||||
    if (icons.length > 0) {
 | 
			
		||||
      descLines.push(icons.join(""));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const activity of anyMember.activities) {
 | 
			
		||||
      if (activity.type == 4 || activity.type == 6) {
 | 
			
		||||
        descLines.push(ActivityTypeNames[activity.type]);
 | 
			
		||||
      } else {
 | 
			
		||||
        descLines.push(`${ActivityTypeNames[activity.type]} **${activity.name}**`);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const embed = {
 | 
			
		||||
    color: user.accent_color,
 | 
			
		||||
    thumbnail: {
 | 
			
		||||
      url: avatar,
 | 
			
		||||
    },
 | 
			
		||||
    image: {
 | 
			
		||||
      url: banner,
 | 
			
		||||
    },
 | 
			
		||||
    title: `${formatUsername(user)} ${user.bot ? Icons.boat : ""}`,
 | 
			
		||||
    description: descLines.join("\n"),
 | 
			
		||||
    fields: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "Created",
 | 
			
		||||
        value: `<t:${Math.floor(snowflakeToTimestamp(id) / 1000)}:R>`,
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
      member && {
 | 
			
		||||
        name: "Joined",
 | 
			
		||||
        value: `<t:${Math.floor(member.joinedAt / 1000)}:R>`,
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
      member?.nick && {
 | 
			
		||||
        name: "Nickname",
 | 
			
		||||
        value: member.nick,
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
      member?.roles?.length > 0 && {
 | 
			
		||||
        name: "Roles",
 | 
			
		||||
        value: member.roles
 | 
			
		||||
          .sort((a, b) => guild.roles.get(b).position - guild.roles.get(a).position)
 | 
			
		||||
          .map((role) => `<@&${role}>`)
 | 
			
		||||
          .join(", "),
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
      shared.length > 0 && {
 | 
			
		||||
        name: "Bot Mutual Servers",
 | 
			
		||||
        value: `${shared.length} servers`,
 | 
			
		||||
        inline: false,
 | 
			
		||||
      },
 | 
			
		||||
      images.length > 0 && {
 | 
			
		||||
        name: "\u200b",
 | 
			
		||||
        value: images.join("\n"),
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
      guildImages.length > 0 && {
 | 
			
		||||
        name: "\u200b",
 | 
			
		||||
        value: guildImages.join("\n"),
 | 
			
		||||
        inline: true,
 | 
			
		||||
      },
 | 
			
		||||
    ].filter((x) => !!x),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return {embeds: [embed]};
 | 
			
		||||
};
 | 
			
		||||
hf.registerCommand(userinfo);
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue