From 06c955e1b7310d692d1b06fca95b643543822b0b Mon Sep 17 00:00:00 2001 From: wont-stream <143244075+wont-stream@users.noreply.github.com> Date: Sat, 19 Apr 2025 21:20:21 -0400 Subject: [PATCH] Add Discord Badges --- .env.example | 2 + config/environment.ts | 9 ++ public/badges/discord/ACTIVE_DEVELOPER.svg | 3 + public/badges/discord/BUG_HUNTER_LEVEL_1.svg | 1 + public/badges/discord/BUG_HUNTER_LEVEL_2.svg | 1 + public/badges/discord/CERTIFIED_MODERATOR.svg | 1 + public/badges/discord/HYPESQUAD.svg | 1 + .../discord/HYPESQUAD_ONLINE_HOUSE_1.svg | 1 + .../discord/HYPESQUAD_ONLINE_HOUSE_2.svg | 1 + .../discord/HYPESQUAD_ONLINE_HOUSE_3.svg | 1 + public/badges/discord/NITRO.svg | 1 + public/badges/discord/PARTNER.svg | 1 + .../discord/PREMIUM_EARLY_SUPPORTER.svg | 1 + public/badges/discord/STAFF.svg | 1 + public/badges/discord/SUPPORTS_COMMANDS.svg | 1 + public/badges/discord/USES_AUTOMOD.svg | 19 +++ public/badges/discord/VERIFIED_DEVELOPER.svg | 1 + src/helpers/badges.ts | 119 +++++++++++++++++- types/config.d.ts | 1 + 19 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 public/badges/discord/ACTIVE_DEVELOPER.svg create mode 100644 public/badges/discord/BUG_HUNTER_LEVEL_1.svg create mode 100644 public/badges/discord/BUG_HUNTER_LEVEL_2.svg create mode 100644 public/badges/discord/CERTIFIED_MODERATOR.svg create mode 100644 public/badges/discord/HYPESQUAD.svg create mode 100644 public/badges/discord/HYPESQUAD_ONLINE_HOUSE_1.svg create mode 100644 public/badges/discord/HYPESQUAD_ONLINE_HOUSE_2.svg create mode 100644 public/badges/discord/HYPESQUAD_ONLINE_HOUSE_3.svg create mode 100644 public/badges/discord/NITRO.svg create mode 100644 public/badges/discord/PARTNER.svg create mode 100644 public/badges/discord/PREMIUM_EARLY_SUPPORTER.svg create mode 100644 public/badges/discord/STAFF.svg create mode 100644 public/badges/discord/SUPPORTS_COMMANDS.svg create mode 100644 public/badges/discord/USES_AUTOMOD.svg create mode 100644 public/badges/discord/VERIFIED_DEVELOPER.svg diff --git a/.env.example b/.env.example index 21aae90..1a62aa4 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,5 @@ PORT=8080 REDIS_URL=redis://username:password@localhost:6379 REDIS_TTL=3600 # seconds + +DISCORD_TOKEN=discord_bot_token \ No newline at end of file diff --git a/config/environment.ts b/config/environment.ts index 03a3107..71f0eb2 100644 --- a/config/environment.ts +++ b/config/environment.ts @@ -18,21 +18,30 @@ export const badgeServices: badgeURLMap[] = [ { service: "Vencord", url: "https://badges.vencord.dev/badges.json", + authType: "none" }, { service: "Equicord", // Ekwekord ! WOOP url: "https://raw.githubusercontent.com/Equicord/Equibored/refs/heads/main/badges.json", + authType: "none" }, { service: "Nekocord", url: "https://nekocord.dev/assets/badges.json", + authType: "none" }, { service: "ReviewDb", url: "https://manti.vendicated.dev/api/reviewdb/badges", + authType: "none" }, // { // service: "ClientMods", // url: getClientModBadgesUrl, // } + { + service: "Discord", + url: (id) => `https://discord.com/api/v10/users${id}`, + authType: "DISCORD" + } ]; diff --git a/public/badges/discord/ACTIVE_DEVELOPER.svg b/public/badges/discord/ACTIVE_DEVELOPER.svg new file mode 100644 index 0000000..80aa677 --- /dev/null +++ b/public/badges/discord/ACTIVE_DEVELOPER.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/badges/discord/BUG_HUNTER_LEVEL_1.svg b/public/badges/discord/BUG_HUNTER_LEVEL_1.svg new file mode 100644 index 0000000..ca75a4e --- /dev/null +++ b/public/badges/discord/BUG_HUNTER_LEVEL_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/BUG_HUNTER_LEVEL_2.svg b/public/badges/discord/BUG_HUNTER_LEVEL_2.svg new file mode 100644 index 0000000..1c80182 --- /dev/null +++ b/public/badges/discord/BUG_HUNTER_LEVEL_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/CERTIFIED_MODERATOR.svg b/public/badges/discord/CERTIFIED_MODERATOR.svg new file mode 100644 index 0000000..6f634b2 --- /dev/null +++ b/public/badges/discord/CERTIFIED_MODERATOR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/HYPESQUAD.svg b/public/badges/discord/HYPESQUAD.svg new file mode 100644 index 0000000..85bec04 --- /dev/null +++ b/public/badges/discord/HYPESQUAD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_1.svg b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_1.svg new file mode 100644 index 0000000..91fd024 --- /dev/null +++ b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_2.svg b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_2.svg new file mode 100644 index 0000000..d0713bb --- /dev/null +++ b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_3.svg b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_3.svg new file mode 100644 index 0000000..01e4805 --- /dev/null +++ b/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/NITRO.svg b/public/badges/discord/NITRO.svg new file mode 100644 index 0000000..98b54ab --- /dev/null +++ b/public/badges/discord/NITRO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/PARTNER.svg b/public/badges/discord/PARTNER.svg new file mode 100644 index 0000000..35facaf --- /dev/null +++ b/public/badges/discord/PARTNER.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/PREMIUM_EARLY_SUPPORTER.svg b/public/badges/discord/PREMIUM_EARLY_SUPPORTER.svg new file mode 100644 index 0000000..8cd0cda --- /dev/null +++ b/public/badges/discord/PREMIUM_EARLY_SUPPORTER.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/STAFF.svg b/public/badges/discord/STAFF.svg new file mode 100644 index 0000000..d65b724 --- /dev/null +++ b/public/badges/discord/STAFF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/SUPPORTS_COMMANDS.svg b/public/badges/discord/SUPPORTS_COMMANDS.svg new file mode 100644 index 0000000..55e0c7b --- /dev/null +++ b/public/badges/discord/SUPPORTS_COMMANDS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/badges/discord/USES_AUTOMOD.svg b/public/badges/discord/USES_AUTOMOD.svg new file mode 100644 index 0000000..e220934 --- /dev/null +++ b/public/badges/discord/USES_AUTOMOD.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/badges/discord/VERIFIED_DEVELOPER.svg b/public/badges/discord/VERIFIED_DEVELOPER.svg new file mode 100644 index 0000000..4ec174f --- /dev/null +++ b/public/badges/discord/VERIFIED_DEVELOPER.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/helpers/badges.ts b/src/helpers/badges.ts index 892233d..63da2ba 100644 --- a/src/helpers/badges.ts +++ b/src/helpers/badges.ts @@ -1,6 +1,94 @@ import { badgeServices, redisTtl } from "@config/environment"; import { fetch, redis } from "bun"; +const DISCORD_BADGES = { + // User badges + HYPESQUAD: 2 << 2, + HYPESQUAD_ONLINE_HOUSE_1: 2 << 6, + HYPESQUAD_ONLINE_HOUSE_2: 2 << 7, + HYPESQUAD_ONLINE_HOUSE_3: 2 << 8, + + STAFF: 2 << 0, + PARTNER: 2 << 1, + CERTIFIED_MODERATOR: 2 << 18, + + VERIFIED_DEVELOPER: 2 << 17, + ACTIVE_DEVELOPER: 2 << 22, + + PREMIUM_EARLY_SUPPORTER: 2 << 9, + + BUG_HUNTER_LEVEL_1: 2 << 3, + BUG_HUNTER_LEVEL_2: 2 << 14, + + // Bot badges + SUPPORTS_COMMANDS: 2 << 23, + USES_AUTOMOD: 2 << 24, +}; + +const DISCORD_BADGE_DETAILS = { + HYPESQUAD: { + tooltip: "HypeSquad Events", + icon: "/public/badges/discord/HYPESQUAD.svg", + }, + HYPESQUAD_ONLINE_HOUSE_1: { + tooltip: "HypeSquad Bravery", + icon: "/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_1.svg", + }, + HYPESQUAD_ONLINE_HOUSE_2: { + tooltip: "HypeSquad Brilliance", + icon: "/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_2.svg", + }, + HYPESQUAD_ONLINE_HOUSE_3: { + tooltip: "HypeSquad Balance", + icon: "/public/badges/discord/HYPESQUAD_ONLINE_HOUSE_3.svg", + }, + + STAFF: { + tooltip: "Discord Staff", + icon: "/public/badges/discord/STAFF.svg", + }, + PARTNER: { + tooltip: "Discord Partner", + icon: "/public/badges/discord/PARTNER.svg", + }, + CERTIFIED_MODERATOR: { + tooltip: "Certified Moderator", + icon: "/public/badges/discord/CERTIFIED_MODERATOR.svg", + }, + + VERIFIED_DEVELOPER: { + tooltip: "Verified Bot Developer", + icon: "/public/badges/discord/VERIFIED_DEVELOPER.svg", + }, + ACTIVE_DEVELOPER: { + tooltip: "Active Developer", + icon: "/public/badges/discord/ACTIVE_DEVELOPER.svg", + }, + + PREMIUM_EARLY_SUPPORTER: { + tooltip: "Premium Early Supporter", + icon: "/public/badges/discord/PREMIUM_EARLY_SUPPORTER.svg", + }, + + BUG_HUNTER_LEVEL_1: { + tooltip: "Bug Hunter (Level 1)", + icon: "/public/badges/discord/BUG_HUNTER_LEVEL_1.svg", + }, + BUG_HUNTER_LEVEL_2: { + tooltip: "Bug Hunter (Level 2)", + icon: "/public/badges/discord/BUG_HUNTER_LEVEL_2.svg", + }, + + SUPPORTS_COMMANDS: { + tooltip: "Supports Commands", + icon: "/public/badges/discord/SUPPORTS_COMMANDS.svg", + }, + USES_AUTOMOD: { + tooltip: "Uses AutoMod", + icon: "/public/badges/discord/USES_AUTOMOD.svg", + }, +} + export async function fetchBadges( userId: string, services: string[], @@ -33,20 +121,47 @@ export async function fetchBadges( } let url: string; + let headers: Record = {}; if (typeof entry.url === "function") { url = entry.url(userId); } else { url = entry.url; } + if (entry.authType === "DISCORD") { + headers = { + Authorization: `Bot ${process.env.DISCORD_TOKEN}` + }; + } + try { - const res = await fetch(url); + const res = await fetch(url, { headers }); if (!res.ok) return; const data = await res.json(); const result: Badge[] = []; switch (serviceKey) { + case "discord": { + if (data.avatar.startsWith("a_")) { + result.push({ + tooltip: "Discord Nitro", + badge: "/public/badges/discord/NITRO.svg", + }); + } + + for (const [flag, bitwise] of Object.entries(DISCORD_BADGES)) { + if (data.flags & bitwise) { + const badge = DISCORD_BADGE_DETAILS[flag as keyof typeof DISCORD_BADGE_DETAILS]; + result.push({ + tooltip: badge.tooltip, + badge: badge.icon, + }); + } + } + break; + } + case "vencord": case "equicord": { const userBadges = data[userId]; @@ -97,7 +212,7 @@ export async function fetchBadges( await redis.expire(cacheKey, redisTtl); } } - } catch (_) {} + } catch (_) { } }), ); diff --git a/types/config.d.ts b/types/config.d.ts index 2d583ee..d5810b4 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -7,4 +7,5 @@ type Environment = { type badgeURLMap = { service: string; url: string | ((userId: string) => string); + authType: "none" | "DISCORD"; };