-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(core): update prefix CommandData` interface, execute method,…
… util functions (#191) - Added 'Utility' category to CommandData interface - Changed requiredBotPermissions and requiredUserPermissions to be single PermissionsBitField - Updated execute method in BasePrefixCommand to include new functionality - Refactored Util functions in BasePrefixCommand - Updated messages in execute method to use emojis and handle errors
- Loading branch information
Showing
10 changed files
with
239 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import BasePrefixCommand, { CommandData } from '#main/core/BasePrefixCommand.js'; | ||
import { sendHubReport } from '#main/utils/HubLogger/Report.js'; | ||
import { | ||
findOriginalMessage, | ||
getBroadcasts, | ||
getMessageIdFromStr, | ||
getOriginalMessage, | ||
} from '#main/utils/network/messageUtils.js'; | ||
import { GuildTextBasedChannel, Message } from 'discord.js'; | ||
import ms from 'ms'; | ||
|
||
export default class ReportPrefixCommand extends BasePrefixCommand { | ||
public readonly data: CommandData = { | ||
name: 'report', | ||
description: 'Report a message', | ||
category: 'Utility', | ||
usage: 'report ` [message ID or link] ` ` reason ` ', | ||
examples: [ | ||
'report 123456789012345678', | ||
'report https://discord.com/channels/123456789012345678/123456789012345678/123456789012345678', | ||
'report 123456789012345678 Spamming', | ||
], | ||
aliases: ['r'], | ||
totalArgs: 1, | ||
cooldown: ms('30s'), | ||
}; | ||
|
||
protected async run(message: Message<true>, args: string[]) { | ||
const msgId = message.reference?.messageId ?? getMessageIdFromStr(args[0] ?? args[1]); | ||
const originalMsg = msgId ? await this.getOriginalMessage(msgId) : null; | ||
const broadcastMsgs = originalMsg | ||
? await getBroadcasts(originalMsg.messageId, originalMsg.hubId) | ||
: null; | ||
|
||
if (!broadcastMsgs || !originalMsg) { | ||
await message.channel.send('Please provide a valid message ID or link.'); | ||
return; | ||
} | ||
|
||
const broadcastMsg = Object.values(broadcastMsgs).find((m) => m.messageId === msgId); | ||
if (!broadcastMsg) { | ||
await message.channel.send('Please provide a valid message ID or link.'); | ||
return; | ||
} | ||
|
||
const fetchedMsg = await ( | ||
message.client.channels.cache.get(broadcastMsg.channelId) as GuildTextBasedChannel | ||
)?.messages | ||
.fetch(broadcastMsg.messageId) | ||
.catch(() => null); | ||
|
||
await sendHubReport(originalMsg.hubId, message.client, { | ||
userId: originalMsg.authorId, | ||
serverId: originalMsg.guildId, | ||
reason: message.reference?.messageId ? args[0] : args.slice(1).join(' '), | ||
reportedBy: message.author, | ||
evidence: { messageId: broadcastMsg.messageId, content: fetchedMsg?.content }, | ||
}); | ||
} | ||
private async getOriginalMessage(messageId: string) { | ||
return (await getOriginalMessage(messageId)) ?? (await findOriginalMessage(messageId)) ?? null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,73 @@ | ||
import { emojis } from '#main/config/Constants.js'; | ||
import Logger from '#main/utils/Logger.js'; | ||
import { isDev } from '#main/utils/Utils.js'; | ||
import { Message, PermissionsBitField } from 'discord.js'; | ||
|
||
export interface CommandData { | ||
name: string; | ||
description: string; | ||
category: 'Moderation' | 'Network'; // add more categories as needed | ||
category: 'Moderation' | 'Network' | 'Utility'; // add more categories as needed | ||
usage: string; | ||
examples: string[]; | ||
aliases: string[]; | ||
dbPermission?: boolean; | ||
totalArgs: number; | ||
cooldown?: number; | ||
ownerOnly?: boolean; | ||
requiredBotPermissions?: PermissionsBitField[]; | ||
requiredUserPermissions?: PermissionsBitField[]; | ||
requiredBotPermissions?: PermissionsBitField; | ||
requiredUserPermissions?: PermissionsBitField; | ||
} | ||
|
||
export default abstract class BasePrefixCommand { | ||
public abstract readonly data: CommandData; | ||
public abstract execute(message: Message, args: string[]): Promise<void>; | ||
protected abstract run(message: Message, args: string[]): Promise<void>; | ||
public async execute(message: Message, args: string[]): Promise<void> { | ||
try { | ||
// Check if command is owner-only | ||
if (this.data.ownerOnly && !isDev(message.author.id)) { | ||
await message.reply(`${emojis.botdev} This command can only be used by the bot owner.`); | ||
return; | ||
} | ||
|
||
// Check user permissions | ||
const { requiredBotPermissions, requiredUserPermissions } = this.data; | ||
|
||
const missingPerms = | ||
requiredUserPermissions && | ||
message.member?.permissions.missing(requiredUserPermissions, true); | ||
if (missingPerms?.length) { | ||
await message.reply(`${emojis.neutral} You're missing the following permissions: ${missingPerms.join(', ')}`); | ||
return; | ||
} | ||
|
||
const botMissingPerms = | ||
requiredBotPermissions && | ||
message.guild?.members.me?.permissions.missing(requiredBotPermissions, true); | ||
if (botMissingPerms?.length) { | ||
await message.reply(`${emojis.no} I'm missing the following permissions: ${botMissingPerms.join(', ')}`); | ||
return; | ||
} | ||
|
||
if (this.data.dbPermission && !message.inGuild()) { | ||
await message.reply(`${emojis.no} This command can only be used in a server.`); | ||
return; | ||
} | ||
|
||
if (this.data.totalArgs > args.length) { | ||
const examplesStr = | ||
this.data.examples.length > 0 ? `\n**Examples**: ${this.data.examples.join('\n')}` : ''; | ||
await message.reply( | ||
`${emojis.neutral} One or more args missing.\n**Usage**: ${this.data.usage}\n${examplesStr}`, | ||
); | ||
return; | ||
} | ||
|
||
// Run command | ||
await this.run(message, args); | ||
} | ||
catch (error) { | ||
Logger.error(error); | ||
await message.reply('There was an error executing this command!'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { emojis } from '#main/config/Constants.js'; | ||
import { RegisterInteractionHandler } from '#main/decorators/Interaction.js'; | ||
import { CustomID } from '#main/utils/CustomID.js'; | ||
import { InfoEmbed } from '#main/utils/EmbedUtils.js'; | ||
import { fetchHub, isStaffOrHubMod } from '#main/utils/hub/utils.js'; | ||
import modActionsPanel from '#main/utils/moderation/modActions/modActionsPanel.js'; | ||
import { findOriginalMessage, getOriginalMessage } from '#main/utils/network/messageUtils.js'; | ||
import { ButtonInteraction } from 'discord.js'; | ||
|
||
export default class ModActionsButton { | ||
@RegisterInteractionHandler('showModPanel') | ||
async handler(interaction: ButtonInteraction): Promise<void> { | ||
await interaction.deferUpdate(); | ||
|
||
const customId = CustomID.parseCustomId(interaction.customId); | ||
const [messageId] = customId.args; | ||
|
||
const originalMessage = | ||
(await getOriginalMessage(messageId)) ?? (await findOriginalMessage(messageId)); | ||
const hub = originalMessage ? await fetchHub(originalMessage?.hubId) : null; | ||
|
||
if (!originalMessage || !hub || !isStaffOrHubMod(interaction.user.id, hub)) { | ||
await interaction.editReply({ components: [] }); | ||
await interaction.followUp({ | ||
embeds: [new InfoEmbed({ description: `${emojis.slash} Message was deleted.` })], | ||
ephemeral: true, | ||
}); | ||
return; | ||
} | ||
|
||
if (!isStaffOrHubMod(interaction.user.id, hub)) return; | ||
|
||
const panel = await modActionsPanel.buildMessage(interaction, originalMessage); | ||
await interaction.followUp({ | ||
embeds: [panel.embed], | ||
components: panel.buttons, | ||
ephemeral: true, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.