diff --git a/config/constants.ts b/config/constants.ts index ac3a5c6..b6ec990 100644 --- a/config/constants.ts +++ b/config/constants.ts @@ -85,16 +85,36 @@ const discordBadgeDetails = { tooltip: "Uses AutoMod", icon: "/public/badges/discord/USES_AUTOMOD.svg", }, + + // Custom + + VENCORD_CONTRIBUTOR: { + tooltip: "Vencord Contributor", + icon: "/public/badges/vencord.png", + }, + EQUICORD_CONTRIBUTOR: { + tooltip: "Equicord Contributor", + icon: "/public/badges/equicord.svg", + }, + + DISCORD_NITRO: { + tooltip: "Discord Nitro", + icon: "/public/badges/discord/NITRO.svg", + }, }; const badgeServices: BadgeService[] = [ { service: "Vencord", url: "https://badges.vencord.dev/badges.json", + pluginsUrl: + "https://raw.githubusercontent.com/Vencord/builds/main/plugins.json", }, { service: "Equicord", // Ekwekord ! WOOP url: "https://raw.githubusercontent.com/Equicord/Equibored/refs/heads/main/badges.json", + pluginsUrl: + "https://raw.githubusercontent.com/Equicord/Equibored/refs/heads/main/plugins.json", }, { service: "Nekocord", @@ -118,9 +138,6 @@ const badgeServices: BadgeService[] = [ }, ]; -const vencordEquicordContributorUrl = - "https://raw.githubusercontent.com/Equicord/Equibored/refs/heads/main/plugins.json"; - function getServiceDescription(service: string): string { const descriptions: Record = { Vencord: "Custom badges from Vencord Discord client", @@ -140,7 +157,6 @@ export { badgeServices, discordBadges, discordBadgeDetails, - vencordEquicordContributorUrl, getServiceDescription, gitUrl, }; diff --git a/config/index.ts b/config/index.ts index 5f7ad84..cd99868 100644 --- a/config/index.ts +++ b/config/index.ts @@ -18,7 +18,7 @@ const badgeFetchInterval: number = process.env.BADGE_FETCH_INTERVAL const botToken: string | undefined = process.env.DISCORD_TOKEN; function verifyRequiredVariables(): void { - const requiredVariables = ["HOST", "PORT", "DISCORD_TOKEN"]; + const requiredVariables = ["HOST", "PORT"]; let hasError = false; diff --git a/public/badges/equicord.svg b/public/badges/equicord.svg new file mode 100644 index 0000000..d60e5ce --- /dev/null +++ b/public/badges/equicord.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/badges/vencord.png b/public/badges/vencord.png new file mode 100644 index 0000000..7f43004 Binary files /dev/null and b/public/badges/vencord.png differ diff --git a/src/lib/badgeCache.ts b/src/lib/badgeCache.ts index 8711187..5821e09 100644 --- a/src/lib/badgeCache.ts +++ b/src/lib/badgeCache.ts @@ -2,9 +2,9 @@ import { echo } from "@atums/echo"; import { badgeFetchInterval, badgeServices, + discordBadgeDetails, gitUrl, redisTtl, - vencordEquicordContributorUrl, } from "@config"; import { redis } from "bun"; @@ -117,8 +117,8 @@ class BadgeCacheManager { } } - if (typeof vencordEquicordContributorUrl === "string") { - const contributorRes = await fetch(vencordEquicordContributorUrl, { + if (typeof service.pluginsUrl === "string") { + const contributorRes = await fetch(service.pluginsUrl, { headers: { "User-Agent": `BadgeAPI/1.0 ${gitUrl}`, }, @@ -136,20 +136,9 @@ class BadgeCacheManager { for (const plugin of pluginData) { if (plugin.authors && Array.isArray(plugin.authors)) { - const isEquicordPlugin = - plugin.filePath && - typeof plugin.filePath === "string" && - plugin.filePath.includes("equicordplugins/"); - - const shouldInclude = - (serviceKey === "equicord" && isEquicordPlugin) || - (serviceKey === "vencord" && !isEquicordPlugin); - - if (shouldInclude) { - for (const author of plugin.authors) { - if (author.id) { - contributors.add(author.id); - } + for (const author of plugin.authors) { + if (author.id) { + contributors.add(author.id); } } } @@ -158,12 +147,14 @@ class BadgeCacheManager { const badgeDetails = serviceKey === "vencord" ? { - tooltip: "Vencord Contributor", - badge: "https://vencord.dev/assets/favicon.png", + tooltip: + discordBadgeDetails.VENCORD_CONTRIBUTOR.tooltip, + badge: discordBadgeDetails.VENCORD_CONTRIBUTOR.icon, } : { - tooltip: "Equicord Contributor", - badge: "https://i.imgur.com/57ATLZu.png", + tooltip: + discordBadgeDetails.EQUICORD_CONTRIBUTOR.tooltip, + badge: discordBadgeDetails.EQUICORD_CONTRIBUTOR.icon, }; for (const authorId of contributors) { diff --git a/src/lib/badges.ts b/src/lib/badges.ts index 284cdcc..f92789e 100644 --- a/src/lib/badges.ts +++ b/src/lib/badges.ts @@ -11,6 +11,8 @@ function getRequestOrigin(request: Request): string { return `${forwardedProto}://${host}`; } +const USER_CACHE_SERVICES = ["discord", "enmity"]; + export async function fetchBadges( userId: string | undefined, services: string[], @@ -26,23 +28,26 @@ export async function fetchBadges( const userCachePromises = services.map(async (service) => { const serviceKey = service.toLowerCase(); + + if (!USER_CACHE_SERVICES.includes(serviceKey) || nocache) { + return false; + } + const userCacheKey = `user_badges:${serviceKey}:${userId}`; - if (!nocache) { - try { - const cached = await redis.get(userCacheKey); - if (cached) { - const parsed: Badge[] = JSON.parse(cached); - results[serviceKey] = parsed; - return true; - } - } catch {} - } + try { + const cached = await redis.get(userCacheKey); + if (cached) { + const parsed: Badge[] = JSON.parse(cached); + results[serviceKey] = parsed; + return true; + } + } catch {} + return false; }); const cacheHits = await Promise.all(userCachePromises); - const servicesToFetch = services.filter((_, index) => !cacheHits[index]); await Promise.all( @@ -68,10 +73,16 @@ export async function fetchBadges( const userBadges = serviceData[userId]; if (Array.isArray(userBadges)) { + const origin = request ? getRequestOrigin(request) : ""; + for (const badgeItem of userBadges) { + const badgeUrl = badgeItem.badge.startsWith("/") + ? `${origin}${badgeItem.badge}` + : badgeItem.badge; + result.push({ tooltip: badgeItem.tooltip, - badge: badgeItem.badge, + badge: badgeUrl, }); } } @@ -199,8 +210,8 @@ export async function fetchBadges( if (data.avatar?.startsWith("a_")) { result.push({ - tooltip: "Discord Nitro", - badge: `${origin}/public/badges/discord/NITRO.svg`, + tooltip: discordBadgeDetails.DISCORD_NITRO.tooltip, + badge: `${origin}${discordBadgeDetails.DISCORD_NITRO.icon}`, }); } @@ -228,17 +239,16 @@ export async function fetchBadges( break; } + results[serviceKey] = result; + if ( - result.length > 0 || - serviceKey === "discord" || - serviceKey === "enmity" + USER_CACHE_SERVICES.includes(serviceKey) && + !nocache && + result.length > 0 ) { - results[serviceKey] = result; - if (!nocache) { - const userCacheKey = `user_badges:${serviceKey}:${userId}`; - await redis.set(userCacheKey, JSON.stringify(result)); - await redis.expire(userCacheKey, Math.min(redisTtl, 900)); - } + const userCacheKey = `user_badges:${serviceKey}:${userId}`; + await redis.set(userCacheKey, JSON.stringify(result)); + await redis.expire(userCacheKey, Math.min(redisTtl, 900)); } } catch (error) { echo.warn({ diff --git a/types/badge.d.ts b/types/badge.d.ts index 08043b9..5f235a7 100644 --- a/types/badge.d.ts +++ b/types/badge.d.ts @@ -19,6 +19,7 @@ type BadgeService = { user: string; badge: (id: string) => string; }); + pluginsUrl?: string; }; interface VencordEquicordData {