1 |
rakin |
290 |
import { CommandInteraction, GuildMember, Message, User, UserFlags } from 'discord.js'; |
2 |
rakin |
51 |
import BaseCommand from '../../utils/structures/BaseCommand'; |
3 |
|
|
import DiscordClient from '../../client/Client'; |
4 |
|
|
import CommandOptions from '../../types/CommandOptions'; |
5 |
|
|
import InteractionOptions from '../../types/InteractionOptions'; |
6 |
|
|
import MessageEmbed from '../../client/MessageEmbed'; |
7 |
|
|
import getMember from '../../utils/getMember'; |
8 |
|
|
import { timeSince } from '../../utils/util'; |
9 |
|
|
import { roleMention } from '@discordjs/builders'; |
10 |
|
|
|
11 |
rakin |
290 |
export const getUserBadges = (user: User) => { |
12 |
|
|
const { FLAGS } = UserFlags; |
13 |
|
|
|
14 |
|
|
const badges = []; |
15 |
|
|
|
16 |
|
|
if (user.flags?.has(FLAGS.BUGHUNTER_LEVEL_1)) |
17 |
|
|
badges.push('Bughunter Level 1'); |
18 |
|
|
if (user.flags?.has(FLAGS.BUGHUNTER_LEVEL_2)) |
19 |
|
|
badges.push('Bughunter Level 2'); |
20 |
|
|
if (user.flags?.has(FLAGS.DISCORD_CERTIFIED_MODERATOR)) |
21 |
|
|
badges.push('Discord Certified Moderator'); |
22 |
|
|
if (user.flags?.has(FLAGS.DISCORD_EMPLOYEE)) |
23 |
|
|
badges.push('Discord Staff'); |
24 |
|
|
if (user.flags?.has(FLAGS.EARLY_SUPPORTER)) |
25 |
|
|
badges.push('Early Nitro Supporter'); |
26 |
|
|
if (user.flags?.has(FLAGS.EARLY_VERIFIED_BOT_DEVELOPER)) |
27 |
|
|
badges.push('Early Verified Bot Developer'); |
28 |
|
|
if (user.flags?.has(FLAGS.HOUSE_BALANCE)) |
29 |
|
|
badges.push('HypeSquad Balance'); |
30 |
|
|
if (user.flags?.has(FLAGS.HOUSE_BRILLIANCE)) |
31 |
|
|
badges.push('HypeSquad Brilliance'); |
32 |
|
|
if (user.flags?.has(FLAGS.HOUSE_BRAVERY)) |
33 |
|
|
badges.push('HypeSquad Bravery'); |
34 |
|
|
if (user.flags?.has(FLAGS.HYPESQUAD_EVENTS)) |
35 |
|
|
badges.push('HypeSquad Events'); |
36 |
|
|
if (user.flags?.has(FLAGS.PARTNERED_SERVER_OWNER)) |
37 |
|
|
badges.push('Partnered Server Owner'); |
38 |
|
|
if (user.flags?.has(FLAGS.BOT_HTTP_INTERACTIONS)) |
39 |
|
|
badges.push('Supports Interactions'); |
40 |
|
|
if (user.flags?.has(FLAGS.VERIFIED_BOT)) |
41 |
|
|
badges.push('Verified Bot'); |
42 |
|
|
|
43 |
|
|
return badges.map(b => `🔵 ${b}`); |
44 |
|
|
}; |
45 |
|
|
|
46 |
rakin |
51 |
export default class ProfileCommand extends BaseCommand { |
47 |
|
|
supportsInteractions: boolean = true; |
48 |
|
|
|
49 |
|
|
constructor() { |
50 |
|
|
super('profile', 'information', []); |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
54 |
|
|
let user: GuildMember | null = null; |
55 |
|
|
|
56 |
|
|
if (msg instanceof CommandInteraction && options.isInteraction) { |
57 |
|
|
if (options.options.getMember('user')) |
58 |
|
|
user = <GuildMember> await options.options.getMember('user'); |
59 |
|
|
else |
60 |
|
|
user = <GuildMember> msg.member!; |
61 |
|
|
} |
62 |
|
|
else if (msg instanceof Message && !options.isInteraction) { |
63 |
|
|
if (options.normalArgs[0]) { |
64 |
|
|
try { |
65 |
|
|
const tempMember = await getMember(msg, options); |
66 |
|
|
|
67 |
|
|
if (!tempMember) |
68 |
|
|
throw new Error(); |
69 |
|
|
|
70 |
|
|
user = tempMember; |
71 |
|
|
} |
72 |
|
|
catch (e) { |
73 |
|
|
console.log(e); |
74 |
|
|
|
75 |
|
|
await msg.reply({ |
76 |
|
|
embeds: [ |
77 |
|
|
new MessageEmbed() |
78 |
|
|
.setColor('#f14a60') |
79 |
|
|
.setDescription(':x: The user doesn\'t exist or not a member of this server.') |
80 |
|
|
] |
81 |
|
|
}); |
82 |
|
|
|
83 |
|
|
return; |
84 |
|
|
} |
85 |
|
|
} |
86 |
|
|
else { |
87 |
|
|
user = msg.member!; |
88 |
|
|
} |
89 |
|
|
} |
90 |
|
|
|
91 |
rakin |
64 |
const status = (s: 'idle' | 'online' | 'dnd' | 'invisible' | null | undefined): string => { |
92 |
|
|
if (s === 'idle') |
93 |
|
|
return 'Idle'; |
94 |
|
|
else if (s === 'dnd') |
95 |
|
|
return 'Do not disturb'; |
96 |
|
|
else if (s === 'online') |
97 |
|
|
return 'Online'; |
98 |
|
|
else if (s === undefined || s === null || s === 'invisible') |
99 |
|
|
return 'Offline/Invisible'; |
100 |
|
|
|
101 |
|
|
return s; |
102 |
|
|
}; |
103 |
|
|
|
104 |
|
|
const statusText = '' + ((user?.presence?.clientStatus?.desktop ? 'Desktop (' + status(user?.presence?.clientStatus?.desktop) + ')\n' : '') + (user?.presence?.clientStatus?.web ? 'Web (' + status(user?.presence?.clientStatus?.web) + ')\n' : '') + (user?.presence?.clientStatus?.mobile ? 'Mobile (' + status(user?.presence?.clientStatus?.mobile) + ')' : '')); |
105 |
rakin |
264 |
// const state = user?.presence?.activities.find(a => a.type === 'CUSTOM')?.state; |
106 |
|
|
let activities: string[] | string = []; |
107 |
rakin |
64 |
|
108 |
rakin |
264 |
if (user?.presence) { |
109 |
|
|
for (const a of user?.presence?.activities.values()!) { |
110 |
|
|
console.log(a); |
111 |
|
|
|
112 |
|
|
if (a.type === 'CUSTOM') { |
113 |
rakin |
282 |
activities.push(`${a.emoji ? `${a.emoji.toString()} ` : ''}${a.state}`); |
114 |
rakin |
264 |
} |
115 |
|
|
else if (a.type === 'LISTENING') { |
116 |
|
|
if (a.name === 'Spotify') { |
117 |
|
|
activities.push(`:notes: Listening to **Spotify**: **${a.state?.replace(/\;/, ',')} - ${a.details}**`); |
118 |
|
|
continue; |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
activities.push(`:musical_note: Listening to **${a.name}**`); |
122 |
|
|
} |
123 |
|
|
else if (a.type === 'COMPETING') { |
124 |
|
|
activities.push(`:fire: Competing **${a.name}**`); |
125 |
|
|
} |
126 |
|
|
else if (a.type === 'PLAYING') { |
127 |
|
|
activities.push(`:video_game: Playing **${a.name}**`); |
128 |
|
|
} |
129 |
|
|
else if (a.type === 'STREAMING') { |
130 |
|
|
activities.push(`:video_camera: Streaming **${a.name}**`); |
131 |
|
|
} |
132 |
|
|
else if (a.type === 'WATCHING') { |
133 |
|
|
activities.push(`:tv: Watching **${a.name}**`); |
134 |
|
|
} |
135 |
|
|
} |
136 |
|
|
} |
137 |
|
|
|
138 |
|
|
activities = activities.join('\n'); |
139 |
|
|
|
140 |
|
|
const fields = [ |
141 |
|
|
{ |
142 |
|
|
name: "Nickname", |
143 |
|
|
value: `${user!.nickname?.replace(/\*\<\>\@\_\~\|/g, '') ?? '*Nickname not set*'}` |
144 |
|
|
}, |
145 |
|
|
{ |
146 |
|
|
name: "Account Created", |
147 |
|
|
value: `${user!.user.createdAt.toLocaleDateString('en-US')} (${timeSince(user!.user.createdTimestamp)})` |
148 |
|
|
}, |
149 |
|
|
{ |
150 |
|
|
name: "Joined at", |
151 |
|
|
value: `${user!.joinedAt!.toLocaleDateString('en-US')} (${timeSince(user!.joinedTimestamp!)})` |
152 |
|
|
}, |
153 |
|
|
{ |
154 |
|
|
name: 'Active Devices', |
155 |
|
|
value: `${statusText === '' ? 'Offline/Invisible' : statusText}` |
156 |
|
|
}, |
157 |
|
|
{ |
158 |
|
|
name: 'Status', |
159 |
|
|
value: `${activities?.trim() === '' ? '*No status set*' : activities}` |
160 |
|
|
}, |
161 |
|
|
{ |
162 |
|
|
name: 'Roles', |
163 |
|
|
value: user?.roles.cache.filter(role => role.id !== msg.guild!.id).sort((role1, role2) => { |
164 |
|
|
return role2.position - role1.position; |
165 |
|
|
}).reduce((acc, value) => `${acc} ${roleMention(value.id)}`, '')!.trim()! |
166 |
|
|
} |
167 |
|
|
]; |
168 |
|
|
|
169 |
|
|
const badges = getUserBadges(user!.user); |
170 |
|
|
|
171 |
|
|
if (badges.length > 0) { |
172 |
|
|
fields.push({ |
173 |
|
|
name: 'Badges', |
174 |
|
|
value: badges.join("\n") |
175 |
|
|
}); |
176 |
|
|
} |
177 |
|
|
|
178 |
rakin |
51 |
await msg.reply({ |
179 |
|
|
embeds: [ |
180 |
|
|
new MessageEmbed() |
181 |
|
|
.setColor(user!.user!.hexAccentColor ? user!.user!.hexAccentColor! : '#007bff') |
182 |
|
|
.setAuthor({ |
183 |
|
|
name: user?.user.tag!, |
184 |
rakin |
64 |
iconURL: user!.user.displayAvatarURL() |
185 |
rakin |
51 |
}) |
186 |
rakin |
264 |
.setThumbnail(user!.displayAvatarURL({ |
187 |
rakin |
51 |
size: 4096 |
188 |
|
|
})) |
189 |
rakin |
264 |
.setFields(fields) |
190 |
|
|
.setFooter({ |
191 |
|
|
text: `${user!.id} - ${user?.user.bot ? 'Bot' : 'User'}` |
192 |
|
|
}) |
193 |
rakin |
51 |
] |
194 |
|
|
}); |
195 |
|
|
} |
196 |
|
|
} |