From 5d41ada7037eb681f8a46bb1aae60ede719dd870 Mon Sep 17 00:00:00 2001 From: SKINMAKER Date: Sat, 10 Jun 2023 22:29:51 +0900 Subject: [PATCH] feat: get display name on query (#565) * feat: get display name on query * chore: use global_name instead of display_name * feat: show username on Owner * chore: remove unused import * feat: user page * chore: remove logging * feat: navbar * feat: Seo * feat: logging * feat: addbot * feat: security credit * feat: report * feat: transfer owner * feat: seo * feat: report * chore: do not get channel from guild * chore: remove displayname * chore: remove unused import --- components/Navbar.tsx | 2 +- components/Owner.tsx | 10 ++++----- pages/addbot.tsx | 2 +- pages/api/v2/bots/[id]/index.ts | 2 +- pages/api/v2/users/[id]/report.ts | 2 +- pages/bots/[id]/edit.tsx | 2 +- pages/bots/[id]/index.tsx | 1 + pages/pendingBots/[id]/[date].tsx | 1 + pages/security.tsx | 2 +- pages/servers/[id]/index.tsx | 2 ++ pages/users/[id]/index.tsx | 17 ++++++++++------ pages/users/[id]/report.tsx | 4 ++-- types/index.ts | 1 + utils/DiscordBot.ts | 10 ++++----- utils/Query.ts | 34 ++++++++++++++++++++----------- 15 files changed, 56 insertions(+), 36 deletions(-) diff --git a/components/Navbar.tsx b/components/Navbar.tsx index ca280b2..ffeb21a 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -32,7 +32,7 @@ const Navbar: React.FC = ({ token }) => { if(data.code !== 200) return setUserCache(JSON.parse(localStorage.userCache = JSON.stringify({ id: data.data.id, - username: data.data.username, + username: data.data.globalName, tag: data.data.tag, version: 2 }))) diff --git a/components/Owner.tsx b/components/Owner.tsx index d3ab3fb..57ad20f 100644 --- a/components/Owner.tsx +++ b/components/Owner.tsx @@ -1,7 +1,7 @@ import Link from 'next/link' import DiscordAvatar from '@components/DiscordAvatar' -const Owner: React.FC = ({ id, username, tag, crown=false }) => { +const Owner: React.FC = ({ id, globalName, username, tag, crown=false }) => { return ( @@ -9,9 +9,8 @@ const Owner: React.FC = ({ id, username, tag, crown=false }) => {
-

{ crown && }{username}

- #{tag} - +

{ crown && }{globalName}

+ {tag !== '0' ? '#' + tag : '@' + username}
@@ -22,7 +21,8 @@ export default Owner interface OwnerProps { id: string - tag: string username: string + tag: string + globalName: string crown?: boolean } diff --git a/pages/addbot.tsx b/pages/addbot.tsx index 5cbc7e2..ba10804 100644 --- a/pages/addbot.tsx +++ b/pages/addbot.tsx @@ -82,7 +82,7 @@ const AddBot:NextPage = ({ logged, user, csrfToken, theme }) => { }} />

새로운 봇 추가하기

- 안녕하세요, {user.username}#{user.tag}님! 본인이 아니신가요? + 안녕하세요, {user.tag === '0' ? `@${user.username}` : `${user.globalName}#${user.tag}`}님! 본인이 아니신가요?
{ data ? data.code == 200 && data.data ? diff --git a/pages/api/v2/bots/[id]/index.ts b/pages/api/v2/bots/[id]/index.ts index 2ca6a26..27ce5b9 100644 --- a/pages/api/v2/bots/[id]/index.ts +++ b/pages/api/v2/bots/[id]/index.ts @@ -95,7 +95,7 @@ const Bots = RequestHandler() embeds: [ new EmbedBuilder() .setAuthor({ - name: `${userinfo.username}#${userinfo.tag}`, + name: userinfo.tag === '0' ? `${userinfo.globalName} (@${userinfo.username})` : `${userinfo.username}#${userinfo.tag}`, iconURL: KoreanbotsEndPoints.URL.root + KoreanbotsEndPoints.CDN.avatar(userinfo.id, { format: 'png', size: 256 }), url: KoreanbotsEndPoints.URL.user(userinfo.id) }) diff --git a/pages/api/v2/users/[id]/report.ts b/pages/api/v2/users/[id]/report.ts index ae7c4de..c20d8ca 100644 --- a/pages/api/v2/users/[id]/report.ts +++ b/pages/api/v2/users/[id]/report.ts @@ -37,7 +37,7 @@ const UserReport = RequestHandler().post(limiter) }) if(!validated) return - await getReportChannel().send({ content: `Reported by <@${user}> (${user})\nReported **${userInfo.username}**#${userInfo.tag} <@${userInfo.id}> (${userInfo.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }}) + await getReportChannel().send({ content: `Reported by <@${user}> (${user})\nReported **${userInfo.tag === '0' ? userInfo.globalName + ' @' + userInfo.username : userInfo.globalName + '#' + userInfo.tag} <@${userInfo.id}> (${userInfo.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }}) return ResponseWrapper(res, { code: 200, message: '성공적으로 처리되었습니다.' }) }) diff --git a/pages/bots/[id]/edit.tsx b/pages/bots/[id]/edit.tsx index f93cf74..0236e75 100644 --- a/pages/bots/[id]/edit.tsx +++ b/pages/bots/[id]/edit.tsx @@ -205,7 +205,7 @@ const ManageBotPage:NextPage = ({ bot, user, csrfToken, theme })
{ (values.owners as User[]).map((el, n) => - {el.username}#{el.tag} + {el.tag === '0' ? `${el.globalName} (@${el.username})` : `${el.username}#${el.tag}`} { n !== 0 &&
-
-

{data.username}

- #{data.tag} -
+ { + (data.tag !== '0') ?
+

{data.globalName}

+ #{data.tag} +
:
+

{data.globalName}

+ @{data.username} +
+ }
{checkUserFlag(data.flags, 'staff') && ( diff --git a/pages/users/[id]/report.tsx b/pages/users/[id]/report.tsx index eb4d4d9..ff965ae 100644 --- a/pages/users/[id]/report.tsx +++ b/pages/users/[id]/report.tsx @@ -39,9 +39,9 @@ const ReportUser: NextPage = ({ data, user, csrfToken }) => {
return - + - {data.username}{getJosaPicker('로')(data.username)} 돌아가기 + {data.globalName}{getJosaPicker('로')(data.globalName)} 돌아가기 { reportRes?.code === 200 ? diff --git a/types/index.ts b/types/index.ts index dd16252..fd3afc1 100644 --- a/types/index.ts +++ b/types/index.ts @@ -77,6 +77,7 @@ export interface User { avatar: string tag: string username: string + globalName: string flags: number github: string bots: Bot[] | string[] diff --git a/utils/DiscordBot.ts b/utils/DiscordBot.ts index cc3e938..05bb571 100644 --- a/utils/DiscordBot.ts +++ b/utils/DiscordBot.ts @@ -24,11 +24,11 @@ ServerListDiscordBot.login(process.env.DISCORD_SERVERLIST_TOKEN) export const getMainGuild = () => DiscordBot.guilds.cache.get(process.env.GUILD_ID) export const getReviewGuild = () => DiscordBot.guilds.cache.get(process.env.REVIEW_GUILD_ID) -export const getReportChannel = (): Discord.TextChannel => getMainGuild().channels.cache.get(process.env.REPORT_CHANNEL_ID) as Discord.TextChannel -export const getLoggingChannel = (): Discord.TextChannel => getMainGuild().channels.cache.get(process.env.LOGGING_CHANNEL_ID) as Discord.TextChannel -export const getStatsLoggingChannel = (): Discord.TextChannel => getMainGuild().channels.cache.get(process.env.STATS_LOGGING_CHANNEL_ID) as Discord.TextChannel -export const getBotReviewLogChannel = (): Discord.TextChannel => getReviewGuild().channels.cache.get(process.env.REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel -export const getOpenBotReviewLogChannel = (): Discord.TextChannel => getMainGuild().channels.cache.get(process.env.OPEN_REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel +export const getReportChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.REPORT_CHANNEL_ID) as Discord.TextChannel +export const getLoggingChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.LOGGING_CHANNEL_ID) as Discord.TextChannel +export const getStatsLoggingChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.STATS_LOGGING_CHANNEL_ID) as Discord.TextChannel +export const getBotReviewLogChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel +export const getOpenBotReviewLogChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.OPEN_REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel export const discordLog = async (type: string, issuerID: string, embed?: Discord.EmbedBuilder, attachment?: { content: string, format: string}, content?: string): Promise => { getLoggingChannel().send({ diff --git a/utils/Query.ts b/utils/Query.ts index 0698fe3..22c93b6 100644 --- a/utils/Query.ts +++ b/utils/Query.ts @@ -1,7 +1,7 @@ import fetch from 'node-fetch' import { TLRU } from 'tlru' import DataLoader from 'dataloader' -import { ActivityType, GuildFeature, GuildMember, User as DiscordUser, UserFlags } from 'discord.js' +import { ActivityType, GuildFeature, GuildMember, User as DiscordUser, APIUser as APIDiscordUser, UserFlags } from 'discord.js' import { Bot, Server, User, ListType, List, TokenRegister, BotFlags, DiscordUserFlags, SubmittedBot, DiscordTokenInfo, ServerData, ServerFlags, RawGuild, Nullable, Webhook, BotSpec, ServerSpec } from '@types' import { botCategories, DiscordEnpoints, imageSafeHost, serverCategories, SpecialEndPoints, VOTE_COOLDOWN } from './Constants' @@ -46,19 +46,21 @@ async function getBot(id: string, topLevel=true):Promise { .orWhere({ vanity: id, trusted: true }) .orWhere({ vanity: id, partnered: true }) if (res[0]) { - const discordBot = await DiscordBot.users.fetch(res[0].id).then(r=> r).catch(() => null) as DiscordUser + const discordBot = await get.discord._rawUser.load(res[0].id) if(!discordBot) return null const botMember = await getMainGuild()?.members?.fetch(res[0].id).catch(e=> e) as GuildMember - res[0].flags = res[0].flags | (discordBot.flags?.bitfield & DiscordUserFlags.VERIFIED_BOT ? BotFlags.verified : 0) | (res[0].trusted ? BotFlags.trusted : 0) | (res[0].partnered ? BotFlags.partnered : 0) + const name = discordBot.global_name ?? discordBot.username + res[0].flags = res[0].flags | (discordBot.flags & DiscordUserFlags.VERIFIED_BOT ? BotFlags.verified : 0) | (res[0].trusted ? BotFlags.trusted : 0) | (res[0].partnered ? BotFlags.partnered : 0) res[0].tag = discordBot.discriminator res[0].avatar = discordBot.avatar - res[0].name = discordBot.username + res[0].name = name res[0].category = JSON.parse(res[0].category) res[0].owners = JSON.parse(res[0].owners) - if(botMember) { - if(discordBot.flags.has(UserFlags.BotHTTPInteractions)) { - res[0].status = 'online' - } else if(!botMember.presence) { + + if(discordBot.flags & UserFlags.BotHTTPInteractions) { + res[0].status = 'online' + } else if(botMember) { + if(!botMember.presence) { res[0].status = 'offline' } else { res[0].status = botMember.presence.activities.some(r => r.type === ActivityType.Streaming) ? 'streaming' : botMember.presence.status @@ -75,7 +77,7 @@ async function getBot(id: string, topLevel=true):Promise { res[0].owners = res[0].owners.filter((el: User | null) => el).map((row: User) => ({ ...row })) } - await knex('bots').update({ name: discordBot.username }).where({ id }) + await knex('bots').update({ name }).where({ id }) } @@ -153,9 +155,10 @@ async function getUser(id: string, topLevel = true):Promise { .where('owners', 'like', `%${id}%`) .orderBy('date', 'asc') - const discordUser = await get.discord.user.load(id) + const discordUser = await get.discord._rawUser.load(id) res[0].tag = discordUser?.discriminator || '0000' res[0].username = discordUser?.username || 'Unknown User' + res[0].globalName = discordUser?.global_name || discordUser?.username || 'Unknown User' if (topLevel) { res[0].bots = (await Promise.all(ownedBots.map(async b => await get._rawBot.load(b.id)))).filter((el: Bot | null) => el) res[0].servers = (await Promise.all(ownedServer.map(async b => await get._rawServer.load(b.id)))).filter((el: Server | null) => el) @@ -607,7 +610,10 @@ async function getImage(url: string) { return await res.buffer() } -async function getDiscordUser(id: string):Promise { +async function getDiscordUser(id: string, raw = false):Promise { + if(raw) { + return await DiscordBot.rest.get(`/users/${id}`).catch(() => null) as APIDiscordUser & { global_name: string } + } return await DiscordBot.users.fetch(id, {cache: true}).then(u => u).catch(()=>null) } @@ -752,7 +758,11 @@ export const get = { discord: { user: new DataLoader( async (ids: string[]) => - (await Promise.all(ids.map(async (id: string) => await getDiscordUser(id)))) + (await Promise.all(ids.map(async (id: string) => await getDiscordUser(id, false) as DiscordUser))) + , { cacheMap: new TLRU({ maxStoreSize: 5000, maxAgeMs: 43200000 }) }), + _rawUser: new DataLoader( + async (ids: string[]) => + (await Promise.all(ids.map(async (id: string) => await getDiscordUser(id, true) as APIDiscordUser & { global_name: string }))) , { cacheMap: new TLRU({ maxStoreSize: 5000, maxAgeMs: 43200000 }) }), }, bot: new DataLoader(