From aec828beb56a0c2735f47d286912b90a8c838de5 Mon Sep 17 00:00:00 2001 From: derpystuff <3515180-derpystuff@users.noreply.gitlab.com> Date: Tue, 24 May 2022 21:22:47 +0200 Subject: [PATCH] h --- commands/message/core/undo.js | 1 - commands/message/dev/debug/attachment.js | 1 - commands/message/dev/eval.js | 2 +- .../message/image/photofunia/retro-wave.js | 47 ++++++++ commands/message/info/avatar.js | 3 +- commands/message/info/guild.js | 110 ++++++++++++++++++ commands/message/info/user.js | 80 +++++++++++++ commands/message/utils/ocr.js | 35 ++++++ labscore/api/endpoints.js | 5 +- labscore/api/index.js | 16 +++ labscore/constants.js | 54 +++++++++ labscore/utils/attachment.js | 33 ++++-- labscore/utils/markdown.js | 4 + labscore/utils/users.js | 55 +++++++-- 14 files changed, 421 insertions(+), 25 deletions(-) create mode 100644 commands/message/image/photofunia/retro-wave.js create mode 100644 commands/message/info/guild.js create mode 100644 commands/message/info/user.js create mode 100644 commands/message/utils/ocr.js diff --git a/commands/message/core/undo.js b/commands/message/core/undo.js index 70b160e..d6db24e 100644 --- a/commands/message/core/undo.js +++ b/commands/message/core/undo.js @@ -42,7 +42,6 @@ module.exports = { "content": `${icon("success_simple")} Deleted ${highlight(found)} command replies.` }) - console.log(resp) setTimeout(async () => { await context.channel.deleteMessage(resp.id) }, 5000) diff --git a/commands/message/dev/debug/attachment.js b/commands/message/dev/debug/attachment.js index 78823a7..c451c35 100644 --- a/commands/message/dev/debug/attachment.js +++ b/commands/message/dev/debug/attachment.js @@ -14,7 +14,6 @@ module.exports = { try{ let image = await getRecentImage(context, 50) - console.log(image) if(!image) return editOrReply(context, { embeds: [createEmbed("warning", context, "No images found.")] }) return editOrReply(context, { embeds: [createEmbed("default", context, { image: { diff --git a/commands/message/dev/eval.js b/commands/message/dev/eval.js index adeeb38..b394e03 100644 --- a/commands/message/dev/eval.js +++ b/commands/message/dev/eval.js @@ -10,7 +10,7 @@ module.exports = { name: "dev", metadata: { description: 'Evaluate code.', - examples: ['eval console.log(\'ping\'); -async false'], + examples: ['dev console.log(\'ping\'); -async false'], category: 'dev', usage: 'eval [-async ] [-noreply ] [-jsonspacing ]' }, diff --git a/commands/message/image/photofunia/retro-wave.js b/commands/message/image/photofunia/retro-wave.js new file mode 100644 index 0000000..e67fabc --- /dev/null +++ b/commands/message/image/photofunia/retro-wave.js @@ -0,0 +1,47 @@ +const { createEmbed } = require('../../../../labscore/utils/embed') +const { editOrReply } = require('../../../../labscore/utils/message') +const { STATICS } = require('../../../../labscore/utils/statics') + +const { retroWave } = require('../../../../labscore/api') + +module.exports = { + name: 'retro', + label: 'text', + metadata: { + description: 'cyberspace', + examples: ['retro cyberspace|chaos|crazy'], + category: 'image', + usage: 'retro [-background <1-5>] [-style <1-4>]' + }, + args: [ + {default: 5, name: 'background', type: 'integer'}, + {default: 4, name: 'style', type: 'integer'}, + ], + run: async (context, args) => { + context.triggerTyping(); + if(!args.text) return editOrReply(context, {embeds:[createEmbed("warning", context, `Missing Parameter (text).`)]}) + if(args.background > 5 || args.background < 1) return editOrReply(context, {embeds:[createEmbed("warning", context, `Invalid Parameter (background).`)]}) + if(args.style > 4 || args.style < 1) return editOrReply(context, {embeds:[createEmbed("warning", context, `Invalid Parameter (style).`)]}) + let lines = `${args.text}| | `.split('|') + try{ + let res = await retroWave(context, args.background, args.style, lines[2], lines[0], lines[1]) + + if(res.response.body.status == 1) return editOrReply(context, {embeds:[createEmbed("warning", context, res.response.body.errors[0])]}) + + image = res.response.body.data.images[res.response.body.data.best_quality] + return editOrReply(context, {embeds:[createEmbed("default", context, { + image: { + url: image + }, + footer: { + iconUrl: STATICS.photofunia, + text: `PhotoFunia • ${context.application.name} • Took ${res.timings}s` + } + })]}) + }catch(e){ + console.log(e) + if(e.response?.body?.message) return editOrReply(context, {embeds:[createEmbed("error", context, e.response.body.message)]}) + return editOrReply(context, {embeds:[createEmbed("error", context, `Unable to generate image.`)]}) + } + } +}; \ No newline at end of file diff --git a/commands/message/info/avatar.js b/commands/message/info/avatar.js index 1b71430..912d176 100644 --- a/commands/message/info/avatar.js +++ b/commands/message/info/avatar.js @@ -12,7 +12,8 @@ module.exports = { category: 'info', usage: 'avatar []' }, - run: async (context, args) => { + run: async (context, args) => { + context.triggerTyping(); let u; if(!args.user) { u = context.user } else { u = await getUser(context, args.user) } if(!u) return editOrReply(context, { embeds: [createEmbed("warning", context, "No users found.")] }) diff --git a/commands/message/info/guild.js b/commands/message/info/guild.js new file mode 100644 index 0000000..cea6b50 --- /dev/null +++ b/commands/message/info/guild.js @@ -0,0 +1,110 @@ +const { GUILD_FEATURES } = require("../../../labscore/constants"); +const { createEmbed } = require("../../../labscore/utils/embed"); +const { icon, highlight, timestamp, codeblock } = require("../../../labscore/utils/markdown"); +const { editOrReply } = require("../../../labscore/utils/message"); +const { getUser, renderBadges } = require("../../../labscore/utils/users"); + +const array_chunks = (array, chunk_size) => Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) => index * chunk_size).map(begin => array.slice(begin, begin + chunk_size)); + +module.exports = { + name: 'server', + label: 'user', + aliases: ['guild', 'guildinfo'], + metadata: { + description: 'server', + examples: ['guild'], + category: 'info', + usage: 'server' + }, + run: async (context, args) => { + context.triggerTyping(); + try{ + const emojis = context.message.guild.emojis + const animojis = emojis.filter(emoji => emoji.animated).length + + const channels = context.message.guild.channels + + const categoryChannels = channels.filter((channel) => channel.isGuildCategory).length; + const newsChannels = channels.filter((channel) => channel.isGuildNews).length; + const textChannels = channels.filter((channel) => channel.isGuildText).length; + const voiceChannels = channels.filter((channel) => channel.isGuildVoice).length; + const stageChannels = channels.filter((channel) => channel.isGuildStageVoice).length; + + const g = context.guild + // Guild Card + let guildCard = createEmbed("default", context, { + description: `${icon("house")} **${g.name}** ${highlight(`(${g.id})`)}\n\n${icon("calendar")} **Created at: **${timestamp(g.createdAt)}\n\n<:lc_guild_owner:674652779406426122> **Server Owner: **<@${g.owner.id}>`, + thumbnail: { + url: g.iconUrl + `?size=4096` + }, + fields: [] + }) + + // TODO: make a proper utility function to pad these codeblocks properly + + // Channel Container + guildCard.fields.push({ + name: `${icon("channel")} Channels`, + value: codeblock("py", [ + `Text Channels ${textChannels}`, + `Voice Channels ${voiceChannels}`, + `Stage Channels ${stageChannels}`, + `Announcement Channels ${newsChannels}`, + `Categories ${categoryChannels}`, + ``, + `Total ${channels.length}`, + ]), + inline: true + }) + + // Emoji Container + guildCard.fields.push({ + name: `${icon("emoji")} Emoji`, + value: codeblock("py", [ + `Regular ${emojis.length - animojis}`, + `Animated ${animojis}`, + ``, + `Total ${emojis.length}`, + ]), + inline: true + }) + + // Guild Features + + if(g.features.length >= 1){ + // Create an empty field so everything properly aligns on desktop + guildCard.fields.push({ + name: `​`, + value: `​`, + inline: true + }) + guildFeatures = g.features.sort((a, b) => a.normalize().localeCompare(b.normalize())); + + let featureCards = [] + while(guildFeatures.length){ + ff = guildFeatures.splice(0, 10) + let f = []; + for(const feat of ff){ + if(GUILD_FEATURES[feat]){ + f.push(GUILD_FEATURES[feat]) + } else { + f.push(`<:UNKNOWN:878298902971965520> ${feat}`) + } + } + featureCards.push({ + name: `​`, + value: f.join('\n'), + inline: true + }) + } + + featureCards[0].name = `${icon("activity")} Guild Features` + guildCard.fields = guildCard.fields.concat(featureCards) + } + + return editOrReply(context, { embeds: [guildCard] }) + }catch(e){ + console.log(e) + } + }, +}; \ No newline at end of file diff --git a/commands/message/info/user.js b/commands/message/info/user.js new file mode 100644 index 0000000..bf67f70 --- /dev/null +++ b/commands/message/info/user.js @@ -0,0 +1,80 @@ +const { createEmbed } = require("../../../labscore/utils/embed"); +const { icon, highlight, timestamp } = require("../../../labscore/utils/markdown"); +const { editOrReply } = require("../../../labscore/utils/message"); +const { getUser, renderBadges } = require("../../../labscore/utils/users"); + +const { Constants } = require('detritus-client') +const { UserFlags } = Constants + +module.exports = { + name: 'user', + label: 'user', + aliases: ['u'], + metadata: { + description: 'user', + examples: ['user labsCore'], + category: 'info', + usage: 'user []' + }, + run: async (context, args) => { + context.triggerTyping(); + try{ + let u; + if(!args.user) { args.user = context.user.id } + user = await getUser(context, args.user) + u = user.user + if(!u) return editOrReply(context, { embeds: [createEmbed("warning", context, "No users found.")] }) + let m = user.member + + // User Card + + // TODO: create bot tag emoji for this + let botTag = '' + if(u.bot) botTag = "" + if(u.hasFlag(UserFlags.VERIFIED_BOT)) botTag = "" + + let userCard = createEmbed("default", context, { + description: `${icon("person")} **${u.name}#${u.discriminator}**${botTag} ${highlight(`(${u.id})`)}`, + thumbnail: { + url: u.avatarUrl + `?size=4096` + }, + fields: [{ + name: `${icon("calendar")} Dates`, + value: `**Account Created: **${timestamp(u.createdAt)}`, + inline: false + }] + }) + if(u.banner) userCard.image = { url: u.bannerUrl + `?size=4096`} + + // Guild Container + if(m){ + userCard.fields[0].value = userCard.fields[0].value + `\n**Joined Guild: **${timestamp(m.joinedAt)}` + let guildFields = [] + + // TODO: make this an icon() + if(m.isOwner) guildFields.push(`**Server Owner** <:lc_guild_owner:674652779406426122>`) + if(m.roles.length >= 1) guildFields.push(`**Roles: ** ${m.roles.length}/${context.guild.roles.length}`) + if(m.premiumSince) guildFields.push(`**Boosting since: ** ${m.premiumSince.toLocaleString('en-US')}`) // TODO: make this a timestamp + userCard.fields.push({ + name: `${icon("house")} Server`, + value: guildFields.join('\n'), + inline: true + }) + } + + // Badge Container + let b = renderBadges(u) + if(u.avatarUrl.endsWith('.gif') || u.banner){ b.push('<:badge_nitro:917012997463998485>' )} + if(b.length >= 1){ + userCard.fields.push({ + name: `${icon("nitro")} Badges`, + value: b.join(''), + inline: true + }) + } + return editOrReply(context, { embeds: [userCard] }) + }catch(e){ + console.log(e) + } + }, +}; \ No newline at end of file diff --git a/commands/message/utils/ocr.js b/commands/message/utils/ocr.js new file mode 100644 index 0000000..bf4f1f6 --- /dev/null +++ b/commands/message/utils/ocr.js @@ -0,0 +1,35 @@ +const { googleVisionOcr } = require("../../../labscore/api"); +const { getRecentImage } = require("../../../labscore/utils/attachment"); +const { createEmbed } = require("../../../labscore/utils/embed"); +const { codeblock } = require("../../../labscore/utils/markdown"); +const { editOrReply } = require("../../../labscore/utils/message"); +const { STATICS } = require("../../../labscore/utils/statics"); + +module.exports = { + name: 'ocr', + metadata: { + description: 'Optical Character Recognition', + examples: ['ocr'], + category: 'utils', + usage: 'ocr ' + }, + run: async (context) => { + context.triggerTyping(); + let image = await getRecentImage(context, 50) + if (!image) return editOrReply(context, { embeds: [createEmbed("warning", context, "No images found.")] }) + + let ocr = await googleVisionOcr(context, image) + return editOrReply(context, { + embeds: [createEmbed("default", context, { + thumbnail: { + url: image + }, + description: codeblock("ansi", [ocr.response.body.text]), + footer: { + iconUrl: STATICS.google, + text: `Google Cloud Vision • ${context.application.name} • Took ${ocr.timings}s` + } + })] + }) + }, +}; \ No newline at end of file diff --git a/labscore/api/endpoints.js b/labscore/api/endpoints.js index a8d0613..f2bc20f 100644 --- a/labscore/api/endpoints.js +++ b/labscore/api/endpoints.js @@ -8,6 +8,8 @@ const Hosts = Object.freeze({ const Api = Object.freeze({ HOST: Hosts.prod, + GOOGLE_VISION_OCR: '/google/vision/ocr', + SEARCH_LYRICS: '/search/lyrics', SEARCH_GOOGLE: '/search/google', @@ -17,8 +19,9 @@ const Api = Object.freeze({ SEARCH_WOLFRAM_ALPHA: '/search/wolfram-alpha', PHOTOFUNIA_YACHT: '/photofunia/yacht', + PHOTOFUNIA_RETRO_WAVE: '/photofunia/retro-wave', - INFERKIT: '/inferkit', + INFERKIT: '/utils/inferkit', }) const Static = Object.freeze({ diff --git a/labscore/api/index.js b/labscore/api/index.js index c21fab2..b4a7c4a 100644 --- a/labscore/api/index.js +++ b/labscore/api/index.js @@ -40,6 +40,12 @@ async function request(path, type, headers, args, host) { throw new Error("unsupported, must either use GET or POST"); } +module.exports.googleVisionOcr = async function(context, url){ + return await request(Api.GOOGLE_VISION_OCR, "GET", {}, { + url: url + }) +} + module.exports.lyrics = async function(context, query){ return await request(Api.SEARCH_LYRICS, "GET", {}, { q: query @@ -82,6 +88,16 @@ module.exports.yacht = async function(context, text){ }) } +module.exports.retroWave = async function(context, background = 5, textStyle= 4, text1 = " ", text2 = " ", text3 = " "){ + return await request(Api.PHOTOFUNIA_RETRO_WAVE, "GET", {}, { + text1: text1, + text2: text2, + text3: text3, + background: background, + text_style: textStyle + }) +} + module.exports.inferkit = async function(context, input){ return await request(Api.INFERKIT, "GET", {}, { input: input diff --git a/labscore/constants.js b/labscore/constants.js index 73c9092..1289f97 100644 --- a/labscore/constants.js +++ b/labscore/constants.js @@ -60,4 +60,58 @@ module.exports.WEB_ASSETS = Object.freeze({ "weather": "aab92e69374e4c7b8c6741fe02e574b9" }) +module.exports.GUILD_FEATURES = Object.freeze({ + "MEMBER_VERIFICATION_GATE_ENABLED": "<:MEMBERSHIP_GATING:816573784819630100> Membership Screening Enabled", + "INVITE_SPLASH": "<:BOOST_IMAGE:816574652780249108> Invite Splash Background", + "BANNER": "<:BOOST_IMAGE:816574652780249108> Guild Banner", + "ANIMATED_ICON": "<:BOOST_GIF:816575965559914516> Animated Server Icon", + "VANITY_URL": "<:BOOST_STAR:816575966498258974> Vanity Url", + "MEMBER_LIST_DISABLED": "<:MEMBERLISTDISABLED:816582167287169094> Member List Disabled", + "PARTNERED": "<:PARTNERED:816581753472155648> Partnered Server", + "VERIFIED": "<:VERIFIED:816581753358909440> Verified Server", + "PREVIEW_ENABLED": "<:PREVIEW_ENABLED:819472065986953266> Preview Enabled", + "RELAY_ENABLED": "<:PEOPLE:816579869168893962> Relay Enabled", + "WELCOME_SCREEN_ENABLED": "<:WELCOME:816581124125097994> Welcome Screen", + "FORCE_RELAY": "<:PEOPLE:816579869168893962> Forced Relay Enabled", + "DISCOVERABLE_DISABLED": "<:PUBLIC_DISABLED:839197973958623272> Discovery Disabled", + "ENABLED_DISCOVERABLE_BEFORE": "<:DISCOVERY:816577881647087617> Old Discovery Enabled", + "DISCOVERABLE": "<:DISCOVERY:816577881647087617> Discovery Enabled", + "COMMUNITY": "<:COMMUNITY:816577159924678676> Community Server", + "COMMERCE": "<:COMMERCE:816577415227899914> Store Channels", + "NEWS": "<:NEWS:816583763731152896> Announcement Channels", + "VIP_REGIONS": "<:BOOST_VOICE:816575966452252723> 384kbps Bitrate", + "MORE_EMOJI": "<:BOOST_EMOJI:816575966666948619> More Emoji Slots", + "FEATURABLE": "<:DISCOVERY:816577881647087617> Available on Featured Discovery", + "MORE_STICKERS": "<:MORE_STICKERS:878297552863260742> More Sticker Slots", + "MONETIZATION_ENABLED": "<:MONETIZATION_ENABLED:850454393386958928> Server Monetization Enabled", + "TICKETED_EVENTS_ENABLED": "<:TICKETED_STAGES_ENABLED:850454393530875944> Ticketed Stages Enabled", + "SEVEN_DAY_THREAD_ARCHIVE": "<:THREAD_ARCHIVING:878297227729174568> 7 Day Thread Archiving", + "THREE_DAY_THREAD_ARCHIVE": "<:THREAD_ARCHIVING:878297227729174568> 3 Day Thread Archiving", + "PRIVATE_THREADS": "<:PRIVATE_THREADS:878297227729174569> Private Threads", + "THREADS_ENABLED_TESTING": "<:lc_thread:749595231376375829> Threads Testing Enabled", + "THREADS_ENABLED": "<:lc_thread:749595231376375829> Threads Enabled", + "NEW_THREAD_PERMISSIONS": "<:lc_thread:881925657150504970> New Thread Permissions Enabled", + "ROLE_ICONS": "<:ROLE_ICONS:878297142022795275> Role Icons", + "ROLE_SUBSCRIPTIONS_ENABLED": "<:ROLE_SUBSCRIPTIONS_ENABLED:888440487101485116> Role Subscriptions Enabled", + "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE": "<:ROLE_SUBSCRIPTIONS_ENABLED:888440487101485116> Role Subscriptions Available for Purchase", + "PREMIUM_TIER_3_OVERRIDE": "<:lc_boosting:699936318398136341> Forced Boosting Level 3", + "TEXT_IN_VOICE_ENABLED": "<:TEXT_IN_VOICE_ENABLED:903643253033803796> Voice Channel Text Chat Enabled", + "MEMBER_PROFILES": "<:MEMBER_PROFILES:903643209517907988> Member Profiles", + "ANIMATED_BANNER": "<:BOOST_GIF:816575965559914516> Animated Banner", + "INTERNAL_EMPLOYEE_ONLY": "<:badge_staff:903276633161609246> Internal Employee Server", + "CHANNEL_BANNER": "<:BOOST_IMAGE:816574652780249108> Channel Banners", + "HUB": "<:HUB:915365729447063632> School Hub", + "HAS_DIRECTORY_ENTRY": "<:DIRECTORY:915365390836695040> Linked to School Hub", + "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT": "<:ACTIVITY_FEATURE:937826423337529354> Exposed to Activities WTP Experiment", + "EXPOSED_TO_BOOSTING_TIERS_EXPERIMENT": "<:lc_boosting:699936318398136341> Exposed to Activities Boosting Tier Experiment", + "HAD_EARLY_ACTIVITIES_ACCESS": "<:ACTIVITY_FEATURE:937826423337529354> Had Activities Early Access", + "THREAD_DEFAULT_AUTO_ARCHIVE_DURATION": "<:TEXT_IN_VOICE_ENABLED:903643253033803796> Thread Default Auto Archive Duration", + "AUTO_MODERATION": "<:lc_icon_mod:704269746312446013> Auto Moderation", + "CREATOR_MONETIZABLE": "<:MONETIZATION_ENABLED:850454393386958928> Creator Monetizable", + "CREATOR_MONETIZABLE_DISABLED": "<:MONETIZATION_ENABLED:850454393386958928> Creator Monetizable Disabled", + "BOOSTING_TIERS_EXPERIMENT_SMALL_GUILD": "<:lc_boosting:699936318398136341> Boosting Tiers Experiment Small Guild", + "BOOSTING_TIERS_EXPERIMENT_MEDIUM_GUILD": "<:lc_boosting:699936318398136341> Boosting Tiers Experiment Medium Guild", + "BOT_DEVELOPER_EARLY_ACCESS": "<:i:903276631173509130> Forum Channels Early Access" +}) + module.exports.DISCORD_INVITE = `https://discord.gg/8c4p6xcjru` \ No newline at end of file diff --git a/labscore/utils/attachment.js b/labscore/utils/attachment.js index d8981c9..3c96fe5 100644 --- a/labscore/utils/attachment.js +++ b/labscore/utils/attachment.js @@ -4,30 +4,41 @@ const attachmentTypes = Object.freeze({ image: ["image/png", "image/jpeg", "image/gif"] }) -async function getRecentMedia(context, limit){ +async function getRecentMedia(context, limit) { if (!context.message.channel) { return undefined; } else if (context.message.attachments.length > 0) { return context.message.attachments.first(); } - const messages = await context.message.channel.fetchMessages({ - limit - }); + + let messages = []; + + // Handle Replies + if (context.message.messageReference) { + messages = [[context.message.messageReference.messageId, await context.message.channel.fetchMessage(context.message.messageReference.messageId)]] // somewhat hacky but it works lol + } else { + messages = await context.message.channel.fetchMessages({ + limit: limit, + before: context.message.id + }) + } if (!messages) { return undefined; } let attachments = []; - for(const m of messages){ + for (const m of messages) { let message = m[1] if ( // First the attachment on the message message.attachments.first() - ) { attachments.push(message.attachments.first()) + ) { + attachments.push(message.attachments.first()) } else if ( // Then the embed image message.embeds.length > 0 && message.embeds.toArray()[0].image - ) { attachments.push(message.embeds.toArray()[0].image) + ) { + attachments.push(message.embeds.toArray()[0].image) } else if ( message.embeds.length > 0 && message.embeds.toArray()[0].thumbnail @@ -38,14 +49,14 @@ async function getRecentMedia(context, limit){ // simple helpers -async function getRecentImage(context, limit){ +async function getRecentImage(context, limit) { let attachments = await getRecentMedia(context, limit) let at; let validImages = attachmentTypes.image - for(const a of attachments){ - if(a.contentType && validImages.includes(a.contentType) && at === undefined){ // discord attachment + for (const a of attachments) { + if (a.contentType && validImages.includes(a.contentType) && at === undefined) { // discord attachment at = a.url - } else if (!a.content_type && at === undefined){ // other form of media + } else if (!a.content_type && at === undefined) { // other form of media at = a.url } } diff --git a/labscore/utils/markdown.js b/labscore/utils/markdown.js index 85dea48..c84f775 100644 --- a/labscore/utils/markdown.js +++ b/labscore/utils/markdown.js @@ -16,4 +16,8 @@ module.exports.codeblock = function(type, content){ module.exports.link = function(url, masked){ if(masked) return `[${masked}](${url})` return url +} + +module.exports.timestamp = function(time, flag = "t"){ + return `<${flag}:${Math.floor(time/1000)}>` } \ No newline at end of file diff --git a/labscore/utils/users.js b/labscore/utils/users.js index e59dcf2..c57deb3 100644 --- a/labscore/utils/users.js +++ b/labscore/utils/users.js @@ -1,28 +1,65 @@ async function getUser(context, query){ let user; - if(/[0-9]{18}/.test(query)){ // User ID supplied, use that + let member; + if(/[0-9]{18}/.test(query)){ let uid = query.match(/[0-9]{18}/) try{ user = await context.client.rest.fetchUser(uid) + if(context.guild) member = await getMember(context, user.id) } catch(e){ user = undefined } } else { - user = await getMember(context, query) - if(user) user = user.user + member = await getMember(context, query) + if(member) user = await context.client.rest.fetchUser(member.user.id) } - return user; + return {user: user, member: member}; } async function getMember(context, query){ if(!context.guild) return; - let members = await context.guild.fetchMembersSearch({ query }) - console.log(members) - if(members) return members.first() - return; + if(/[0-9]{18}/.test(query)){ + let uid = query.match(/[0-9]{18}/) + try{ + member = await context.guild.fetchMember(uid) + return member; + } catch(e){ + return; + } + } else { + let members = await context.guild.fetchMembersSearch({ query }) + if(members) return members.first() + return; + } +} + +const { Constants } = require('detritus-client') +const { UserFlags } = Constants + +const BADGES = Object.freeze({ + [UserFlags.STAFF]: '<:badge_staff:903276633161609246>', + [UserFlags.PARTNER]: '<:badge_partner:903276631559389196', + [UserFlags.DISCORD_CERTIFIED_MODERATOR]: '<:badge_mod:903276631198695467>', + [UserFlags.HYPESQUAD]: '<:badge_hypesquad:903276631408394351>', + [UserFlags.HYPESQUAD_ONLINE_HOUSE_1]: '<:badge_hypesquad_bravery:903276631790059540>', + [UserFlags.HYPESQUAD_ONLINE_HOUSE_2]: '<:badge_hypesquad_brilliance:903276631261597706>', + [UserFlags.HYPESQUAD_ONLINE_HOUSE_3]: '<:badge_hypesquad_balance:903276631211249674>', + [UserFlags.BUG_HUNTER_LEVEL_1]: '<:badge_bughunter:903276631173509131>', + [UserFlags.BUG_HUNTER_LEVEL_2]: '<:badge_bughunter_2:903276883523797033>', + [UserFlags.VERIFIED_DEVELOPER]: '<:badge_botdev:903276631173509130>', + [UserFlags.PREMIUM_EARLY_SUPPORTER]: '<:badge_earlysupporter:903277590956101672>' +}) + +function renderBadges(user){ + let badges = []; + for(const flag of Object.keys(BADGES)){ + if(user.hasFlag(parseInt(flag))) badges.push(BADGES[flag]) + } + return badges; } module.exports = { getUser, - getMember + getMember, + renderBadges } \ No newline at end of file