/[sudobot]/trunk/src/commands/information/ProfileCommand.ts
ViewVC logotype

Annotation of /trunk/src/commands/information/ProfileCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 453 - (hide annotations)
Mon Jul 29 17:30:19 2024 UTC (8 months, 2 weeks ago) by rakin
File MIME type: application/typescript
File size: 9322 byte(s)
feat: make the spotify status song name clickable
1 rakin 393 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2022 OSN Inc.
5     *
6     * SudoBot is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU Affero General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * SudoBot is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU Affero General Public License for more details.
15     *
16     * You should have received a copy of the GNU Affero General Public License
17     * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18     */
19    
20 rakin 290 import { CommandInteraction, GuildMember, Message, User, UserFlags } from 'discord.js';
21 rakin 51 import BaseCommand from '../../utils/structures/BaseCommand';
22     import DiscordClient from '../../client/Client';
23     import CommandOptions from '../../types/CommandOptions';
24     import InteractionOptions from '../../types/InteractionOptions';
25     import MessageEmbed from '../../client/MessageEmbed';
26     import getMember from '../../utils/getMember';
27     import { timeSince } from '../../utils/util';
28     import { roleMention } from '@discordjs/builders';
29    
30 rakin 290 export const getUserBadges = (user: User) => {
31     const { FLAGS } = UserFlags;
32    
33     const badges = [];
34    
35     if (user.flags?.has(FLAGS.BUGHUNTER_LEVEL_1))
36     badges.push('Bughunter Level 1');
37     if (user.flags?.has(FLAGS.BUGHUNTER_LEVEL_2))
38     badges.push('Bughunter Level 2');
39     if (user.flags?.has(FLAGS.DISCORD_CERTIFIED_MODERATOR))
40     badges.push('Discord Certified Moderator');
41     if (user.flags?.has(FLAGS.DISCORD_EMPLOYEE))
42     badges.push('Discord Staff');
43     if (user.flags?.has(FLAGS.EARLY_SUPPORTER))
44     badges.push('Early Nitro Supporter');
45     if (user.flags?.has(FLAGS.EARLY_VERIFIED_BOT_DEVELOPER))
46     badges.push('Early Verified Bot Developer');
47     if (user.flags?.has(FLAGS.HOUSE_BALANCE))
48     badges.push('HypeSquad Balance');
49     if (user.flags?.has(FLAGS.HOUSE_BRILLIANCE))
50     badges.push('HypeSquad Brilliance');
51     if (user.flags?.has(FLAGS.HOUSE_BRAVERY))
52     badges.push('HypeSquad Bravery');
53     if (user.flags?.has(FLAGS.HYPESQUAD_EVENTS))
54     badges.push('HypeSquad Events');
55     if (user.flags?.has(FLAGS.PARTNERED_SERVER_OWNER))
56     badges.push('Partnered Server Owner');
57     if (user.flags?.has(FLAGS.BOT_HTTP_INTERACTIONS))
58     badges.push('Supports Interactions');
59     if (user.flags?.has(FLAGS.VERIFIED_BOT))
60     badges.push('Verified Bot');
61    
62     return badges.map(b => `🔵 ${b}`);
63     };
64    
65 rakin 51 export default class ProfileCommand extends BaseCommand {
66     supportsInteractions: boolean = true;
67    
68     constructor() {
69     super('profile', 'information', []);
70     }
71    
72     async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
73     let user: GuildMember | null = null;
74    
75     if (msg instanceof CommandInteraction && options.isInteraction) {
76     if (options.options.getMember('user'))
77     user = <GuildMember> await options.options.getMember('user');
78     else
79     user = <GuildMember> msg.member!;
80     }
81     else if (msg instanceof Message && !options.isInteraction) {
82     if (options.normalArgs[0]) {
83     try {
84     const tempMember = await getMember(msg, options);
85    
86     if (!tempMember)
87     throw new Error();
88    
89     user = tempMember;
90     }
91     catch (e) {
92     console.log(e);
93    
94     await msg.reply({
95     embeds: [
96     new MessageEmbed()
97     .setColor('#f14a60')
98     .setDescription(':x: The user doesn\'t exist or not a member of this server.')
99     ]
100     });
101    
102     return;
103     }
104     }
105     else {
106     user = msg.member!;
107     }
108     }
109    
110 rakin 64 const status = (s: 'idle' | 'online' | 'dnd' | 'invisible' | null | undefined): string => {
111     if (s === 'idle')
112     return 'Idle';
113     else if (s === 'dnd')
114     return 'Do not disturb';
115     else if (s === 'online')
116     return 'Online';
117     else if (s === undefined || s === null || s === 'invisible')
118     return 'Offline/Invisible';
119    
120     return s;
121     };
122    
123     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) + ')' : ''));
124 rakin 264 // const state = user?.presence?.activities.find(a => a.type === 'CUSTOM')?.state;
125     let activities: string[] | string = [];
126 rakin 64
127 rakin 264 if (user?.presence) {
128     for (const a of user?.presence?.activities.values()!) {
129     console.log(a);
130    
131     if (a.type === 'CUSTOM') {
132 rakin 282 activities.push(`${a.emoji ? `${a.emoji.toString()} ` : ''}${a.state}`);
133 rakin 264 }
134     else if (a.type === 'LISTENING') {
135     if (a.name === 'Spotify') {
136 rakin 453 const url = a.syncId ? `https://open.spotify.com/track/${a.syncId}` : null;
137     activities.push(`:notes: Listening to **Spotify**: ${url ? '[' : '**'}${a.state?.replace(/\;/, ',')} - ${a.details}${url ? '](' + url + ')' : '**'}`);
138 rakin 264 continue;
139     }
140    
141     activities.push(`:musical_note: Listening to **${a.name}**`);
142     }
143     else if (a.type === 'COMPETING') {
144     activities.push(`:fire: Competing **${a.name}**`);
145     }
146     else if (a.type === 'PLAYING') {
147     activities.push(`:video_game: Playing **${a.name}**`);
148     }
149     else if (a.type === 'STREAMING') {
150     activities.push(`:video_camera: Streaming **${a.name}**`);
151     }
152     else if (a.type === 'WATCHING') {
153     activities.push(`:tv: Watching **${a.name}**`);
154     }
155     }
156     }
157    
158     activities = activities.join('\n');
159    
160 rakin 416 const allRoles = [...user!.roles.cache.values()].filter(role => role.id !== msg.guild!.id).sort((role1, role2) => {
161     return role2.position - role1.position;
162     });
163     const limit = 10;
164     const roles = (allRoles.length > limit ? allRoles.slice(0, limit) : allRoles).reduce((acc, value) => `${acc} ${roleMention(value.id)}`, '')!.trim()!;
165 rakin 264 const fields = [
166     {
167     name: "Nickname",
168     value: `${user!.nickname?.replace(/\*\<\>\@\_\~\|/g, '') ?? '*Nickname not set*'}`
169     },
170     {
171     name: "Account Created",
172     value: `${user!.user.createdAt.toLocaleDateString('en-US')} (${timeSince(user!.user.createdTimestamp)})`
173     },
174     {
175     name: "Joined at",
176     value: `${user!.joinedAt!.toLocaleDateString('en-US')} (${timeSince(user!.joinedTimestamp!)})`
177     },
178     {
179     name: 'Active Devices',
180     value: `${statusText === '' ? 'Offline/Invisible' : statusText}`
181     },
182     {
183     name: 'Status',
184     value: `${activities?.trim() === '' ? '*No status set*' : activities}`
185     },
186     {
187     name: 'Roles',
188 rakin 416 value: roles === '' ? '*No roles assigned*' : `${roles} ${allRoles.length > limit ? `**+ ${allRoles.length - limit} More**` : ''}`
189 rakin 264 }
190     ];
191    
192     const badges = getUserBadges(user!.user);
193    
194     if (badges.length > 0) {
195     fields.push({
196     name: 'Badges',
197     value: badges.join("\n")
198     });
199     }
200    
201 rakin 416 let banner: string | undefined;
202    
203     try {
204     await user?.user.fetch(true);
205     banner = user!.user!.bannerURL({ size: 4096 }) ?? undefined;
206     }
207     catch (e) {
208     console.log(e);
209     }
210    
211     console.log("Banner", banner, user!.user!.banner);
212    
213 rakin 51 await msg.reply({
214     embeds: [
215 rakin 416 new MessageEmbed({
216     image: {
217     url: banner,
218     }
219     })
220 rakin 51 .setColor(user!.user!.hexAccentColor ? user!.user!.hexAccentColor! : '#007bff')
221     .setAuthor({
222     name: user?.user.tag!,
223 rakin 64 iconURL: user!.user.displayAvatarURL()
224 rakin 51 })
225 rakin 264 .setThumbnail(user!.displayAvatarURL({
226 rakin 51 size: 4096
227     }))
228 rakin 264 .setFields(fields)
229     .setFooter({
230 rakin 416 text: `${user?.user.bot ? 'Bot' : 'User'} • ${user!.id}`
231 rakin 264 })
232 rakin 51 ]
233     });
234     }
235     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26