/[sudobot]/branches/4.x/src/commands/information/UserLookupCommand.ts
ViewVC logotype

Contents of /branches/4.x/src/commands/information/UserLookupCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months, 1 week ago) by rakinar2
File MIME type: application/typescript
File size: 8574 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
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 import { formatDistanceStrict, formatDistanceToNowStrict } from "date-fns";
21 import { APIEmbedField } from "discord-api-types/v9";
22 import { Util, Message, CacheType, CommandInteraction, Permissions } from "discord.js";
23 import Client from "../../client/Client";
24 import MessageEmbed from "../../client/MessageEmbed";
25 import Punishment from "../../models/Punishment";
26 import CommandOptions from "../../types/CommandOptions";
27 import InteractionOptions from "../../types/InteractionOptions";
28 import PunishmentType from "../../types/PunishmentType";
29 import { emoji } from "../../utils/Emoji";
30 import getUser from "../../utils/getUser";
31 import BaseCommand from "../../utils/structures/BaseCommand";
32 import { getUserBadges } from "./ProfileCommand";
33
34 export default class UserLookupCommand extends BaseCommand {
35 permissions = [Permissions.FLAGS.MANAGE_MESSAGES];
36 supportsInteractions: boolean = true;
37
38 constructor() {
39 super("userlookup", "information", ['user', 'ulookup', 'userinfo']);
40 }
41
42 async run(client: Client, message: CommandInteraction<CacheType> | Message<boolean>, options: CommandOptions | InteractionOptions): Promise<void> {
43 if (!options.isInteraction && options.args[0] === undefined) {
44 await message.reply({ ephemeral: true, content: `${emoji("error")} You must specify a user to lookup!` });
45 return;
46 }
47
48 const user = !options.isInteraction ? await getUser(client, message as Message, options, 0) : options.options.getUser("user");
49
50 if (!user) {
51 await message.reply({ content: `${emoji("error")} That user does not exist.` });
52 return;
53 }
54
55 let member = undefined;
56
57 try {
58 member = await message.guild!.members.fetch(user.id);
59
60 if (!member)
61 throw new Error("Member not found");
62 }
63 catch (e) {
64 console.log(e);
65 member = undefined;
66 }
67
68 const embed = new MessageEmbed({
69 author: {
70 name: user.tag,
71 iconURL: user.displayAvatarURL()
72 },
73 footer: {
74 text: `${user.id}`,
75 }
76 });
77
78 const fieldsCommon: APIEmbedField[] = [
79
80 ];
81
82 let fields: APIEmbedField[] = [
83 {
84 name: "Server Member?",
85 value: member ? "Yes" : "No",
86 inline: true
87 },
88 {
89 name: "Bot?",
90 value: user.bot ? "Yes" : "No",
91 inline: true
92 },
93 {
94 name: "Account created",
95 value: user.createdAt.toLocaleString() + " (" + formatDistanceToNowStrict(user.createdAt, { addSuffix: true }) + ")",
96 inline: true
97 }
98 ];
99
100 embed.setThumbnail(user.displayAvatarURL());
101
102 if (member) {
103 fields.push({
104 name: "Joined Server",
105 value: member.joinedAt ? member.joinedAt.toLocaleString() + " (" + formatDistanceToNowStrict(member.joinedAt, { addSuffix: true }) + ")" : "Information not available",
106 inline: true
107 });
108
109 if (member.premiumSince) {
110 fields.push({
111 name: "Boosted Server",
112 value: member.premiumSince.toLocaleString() + " (" + formatDistanceToNowStrict(member.premiumSince, { addSuffix: true }) + ")",
113 inline: true
114 });
115 }
116
117 if (member.communicationDisabledUntil) {
118 fields.push({
119 name: "Timed-out Until",
120 value: member.communicationDisabledUntil.toLocaleString() + " (" + formatDistanceStrict(member.communicationDisabledUntil, new Date()) + ")",
121 inline: true
122 });
123 }
124
125 if (member.displayAvatarURL()) {
126 embed.setThumbnail(member.displayAvatarURL());
127 }
128
129 if (member.nickname) {
130 fields.push({
131 name: "Nickname",
132 value: Util.escapeMarkdown(member.nickname)
133 });
134 }
135
136 if (member.displayHexColor) {
137 fields.push({
138 name: "Guild Profile Theme Color",
139 value: member.displayHexColor
140 });
141 }
142
143 if (member.voice && member.voice.channel) {
144 fields.push({
145 name: "Current Voice Channel",
146 value: member.voice.channel.toString()
147 });
148 }
149
150 fields.push({
151 name: "Completed Membership Screening",
152 value: member.pending ? "No" : "Yes"
153 });
154
155 fields.push({
156 name: "Mention",
157 value: member.toString()
158 });
159
160 if (member.roles.highest.id !== member.guild.id) {
161 fields.push({
162 name: "Highest Role",
163 value: member.roles.highest.toString()
164 });
165 }
166 }
167
168 embed.setColor(member?.user!.hexAccentColor ? member?.user!.hexAccentColor! : '#007bff');
169
170 const badges = getUserBadges(user).join('\n');
171
172 fields.push({
173 name: "Badges",
174 value: badges.trim() === '' ? '*No badges found*' : badges
175 });
176
177 try {
178 const muteCount = await Punishment.countDocuments({
179 guild_id: message.guildId!,
180 type: {
181 $in: [PunishmentType.MUTE, PunishmentType.HARDMUTE, PunishmentType.TIMEOUT]
182 },
183 user_id: user.id,
184 });
185
186 const warnCount = await Punishment.countDocuments({
187 guild_id: message.guildId!,
188 type: {
189 $in: [PunishmentType.WARNING]
190 },
191 user_id: user.id,
192 });
193
194 const banCount = await Punishment.countDocuments({
195 guild_id: message.guildId!,
196 type: {
197 $in: [PunishmentType.KICK, PunishmentType.SOFTBAN, PunishmentType.TEMPBAN, PunishmentType.BAN]
198 },
199 user_id: user.id,
200 });
201
202 const points = (warnCount * 3) + (muteCount * 5) + (banCount * 10);
203
204 let suggestedAction = '*None*';
205
206 if (points >= 1 && points < 5) {
207 suggestedAction = 'Verbal Warning';
208 }
209 else if (points >= 5 && points < 10) {
210 const muteMS = Date.now() + (60_000 * 30 * (points - 4));
211 suggestedAction = `Mute ${member?.roles.cache.has(client.config.props[message.guildId!].mute_role) ? '(Already muted)' : `for ${formatDistanceStrict(new Date(), new Date(muteMS))}`}`;
212 }
213 else if (points >= 10 && points < 15) {
214 const banMS = Date.now() + (60_000 * 60 * 24 * (points - 9));
215 suggestedAction = `Temporary ban for ${formatDistanceStrict(new Date(), new Date(banMS))} or Kick`;
216 }
217 else if (points >= 15) {
218 suggestedAction = "Permanent Ban";
219 }
220
221 fields.push({
222 name: 'Moderation Points',
223 value: points + ''
224 });
225
226 fields.push({
227 name: 'Suggested Action',
228 value: suggestedAction
229 });
230 }
231 catch (e) {
232 console.log(e);
233 }
234
235 fields = [...fields, ...fieldsCommon];
236 embed.setFields(fields);
237 embed.setTimestamp();
238
239 await message.reply({
240 embeds: [
241 embed
242 ]
243 });
244 }
245 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26