diff options
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/info/links.ts (renamed from src/commands/info/invite.ts) | 25 | ||||
-rw-r--r-- | src/commands/info/pronouns.ts | 14 | ||||
-rw-r--r-- | src/commands/info/snowflakeInfo.ts | 11 | ||||
-rw-r--r-- | src/commands/info/userInfo.ts | 19 | ||||
-rw-r--r-- | src/commands/moderation/ban.ts | 1 | ||||
-rw-r--r-- | src/commands/utilities/activity.ts | 57 | ||||
-rw-r--r-- | src/commands/utilities/steal.ts | 59 | ||||
-rw-r--r-- | src/commands/utilities/whoHasRole.ts | 3 |
8 files changed, 149 insertions, 40 deletions
diff --git a/src/commands/info/invite.ts b/src/commands/info/links.ts index 615e767..29152d9 100644 --- a/src/commands/info/invite.ts +++ b/src/commands/info/links.ts @@ -1,15 +1,16 @@ import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { MessageActionRow, MessageButton } from 'discord.js'; +import packageDotJSON from '../../../package.json'; -export default class InviteCommand extends BushCommand { +export default class LinksCommand extends BushCommand { public constructor() { - super('invite', { - aliases: ['invite'], + super('links', { + aliases: ['links', 'invite', 'support'], category: 'info', description: { - content: 'Sends the bot invite link.', - usage: 'invite', - examples: ['invite'] + content: 'Sends bot links', + usage: 'links', + examples: ['links'] }, ratelimit: 4, cooldown: 4000, @@ -27,8 +28,18 @@ export default class InviteCommand extends BushCommand { url: `https://discord.com/api/oauth2/authorize?client_id=${ client.user!.id }&permissions=2147483647&scope=bot%20applications.commands` + }), + new MessageButton({ + style: 'LINK', + label: 'Support Server', + url: client.config.supportGuild.invite + }), + new MessageButton({ + style: 'LINK', + label: 'GitHub', + url: packageDotJSON.repository }) ); - return await message.util.reply({ content: 'You can invite me here:', components: [ButtonRow] }); + return await message.util.reply({ content: '\u200B', components: [ButtonRow] }); } } diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts index c7eac7f..96040c0 100644 --- a/src/commands/info/pronouns.ts +++ b/src/commands/info/pronouns.ts @@ -40,7 +40,7 @@ export default class PronounsCommand extends BushCommand { args: [ { id: 'user', - type: 'user', + customType: util.arg.union('user', 'bigint'), prompt: { start: 'Who would you like to view the pronouns of?', retry: '{error} Choose a valid user to view the pronouns of.', @@ -60,8 +60,16 @@ export default class PronounsCommand extends BushCommand { slash: true }); } - override async exec(message: BushMessage | BushSlashMessage, args: { user?: User }): Promise<unknown> { - const user = args.user ?? message.author; + override async exec(message: BushMessage | BushSlashMessage, args: { user?: User | string }): Promise<unknown> { + const user = + args?.user === undefined || args?.user === null + ? message.author + : typeof args.user === 'object' + ? args.user + : await client.users.fetch(`${args.user}`).catch(() => undefined); + + if (user === undefined) return message.util.reply(`${util.emojis.error} Invalid user.`); + const author = user.id === message.author.id; try { const apiRes: { pronouns: pronounsType } = await got diff --git a/src/commands/info/snowflakeInfo.ts b/src/commands/info/snowflakeInfo.ts index c4d71da..02c8d39 100644 --- a/src/commands/info/snowflakeInfo.ts +++ b/src/commands/info/snowflakeInfo.ts @@ -88,7 +88,7 @@ export default class SnowflakeInfoCommand extends BushCommand { } // Guild - else if (client.guilds.cache.has(snowflake)) { + if (client.guilds.cache.has(snowflake)) { const guild: Guild = client.guilds.cache.get(snowflake)!; const guildInfo = [ `**Name:** ${guild.name}`, @@ -101,8 +101,9 @@ export default class SnowflakeInfoCommand extends BushCommand { } // User - else if (client.users.cache.has(snowflake)) { - const user: User = client.users.cache.get(snowflake)!; + const fetchedUser = await client.users.fetch(`${snowflake}`).catch(() => undefined); + if (client.users.cache.has(snowflake) || fetchedUser) { + const user: User = (client.users.cache.get(snowflake) ?? fetchedUser)!; const userInfo = [`**Name:** <@${user.id}> (${user.tag})`]; if (user.avatar) snowflakeEmbed.setThumbnail(user.avatarURL({ size: 2048, dynamic: true })!); snowflakeEmbed.addField('» User Info', userInfo.join('\n')); @@ -110,7 +111,7 @@ export default class SnowflakeInfoCommand extends BushCommand { } // Emoji - else if (client.emojis.cache.has(snowflake)) { + if (client.emojis.cache.has(snowflake)) { const emoji: Emoji = client.emojis.cache.get(snowflake)!; const emojiInfo = [`**Name:** ${emoji.name}`, `**Animated:** ${emoji.animated}`]; if (emoji.url) snowflakeEmbed.setThumbnail(emoji.url); @@ -119,7 +120,7 @@ export default class SnowflakeInfoCommand extends BushCommand { } // Role - else if (message.guild && message.guild.roles.cache.has(snowflake)) { + if (message.guild && message.guild.roles.cache.has(snowflake)) { const role: Role = message.guild.roles.cache.get(snowflake)!; const roleInfo = [ `**Name:** <@&${role.id}> (${role.name})`, diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts index 9ec5552..7b8d7d8 100644 --- a/src/commands/info/userInfo.ts +++ b/src/commands/info/userInfo.ts @@ -1,7 +1,6 @@ import { BushCommand, BushMessage, BushSlashMessage, BushUser } from '@lib'; import { MessageEmbed } from 'discord.js'; -// TODO: Re-Implement Status Emojis // TODO: Add bot information export default class UserInfoCommand extends BushCommand { public constructor() { @@ -141,6 +140,24 @@ export default class UserInfoCommand extends BushCommand { presenceInfo.push(`**Activit${activitiesNames.length - 1 ? 'ies' : 'y'}:** ${util.oxford(activitiesNames, 'and', '')}`); if (customStatus && customStatus.length) presenceInfo.push(`**Custom Status:** ${customStatus}`); userEmbed.addField('» Presence', presenceInfo.join('\n')); + + enum statusEmojis { + online = '787550449435803658', + idle = '787550520956551218', + dnd = '787550487633330176', + offline = '787550565382750239', + invisible = '787550565382750239' + } + userEmbed.setFooter(user.tag, client.emojis.cache.get(statusEmojis[member?.presence.status])?.url ?? undefined); + } + + // roles + if (member?.roles.cache.size && member?.roles.cache.size - 1) { + const roles = member?.roles.cache + .filter((role) => role.name !== '@everyone') + .sort((role1, role2) => role2.position - role1.position) + .map((role) => `${role}`); + userEmbed.addField(`» Role${roles.length - 1 ? 's' : ''} [${roles.length}]`, roles.join(', ')); } // Important Perms diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index e32bf18..8a98998 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -90,6 +90,7 @@ export default class BanCommand extends BushCommand { force }: { user: User; reason?: { duration: number; contentWithoutTime: string }; days?: number; force: boolean } ): Promise<unknown> { + if (!message.guild) return message.util.reply(`${util.emojis.error} This command cannot be used in dms.`); const member = message.guild!.members.cache.get(user.id) as BushGuildMember; const useForce = force && message.author.isOwner(); const canModerateResponse = util.moderationPermissionCheck(message.member!, member, 'ban', true, useForce); diff --git a/src/commands/utilities/activity.ts b/src/commands/utilities/activity.ts index 8bdfc21..c0ab2a2 100644 --- a/src/commands/utilities/activity.ts +++ b/src/commands/utilities/activity.ts @@ -1,4 +1,4 @@ -import { Message, VoiceChannel } from 'discord.js'; +import { DiscordAPIError, Message, VoiceChannel } from 'discord.js'; import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; const activityMap = { @@ -19,7 +19,7 @@ function map(phase: string) { } // eslint-disable-next-line @typescript-eslint/no-unused-vars -const activityTypeCaster = (_message: Message, phrase: string) => { +const activityTypeCaster = (_message: Message | BushMessage | BushSlashMessage, phrase: string) => { if (!phrase) return null; const mappedPhrase = map(phrase); if (mappedPhrase) return mappedPhrase; @@ -51,7 +51,12 @@ export default class YouTubeCommand extends BushCommand { { id: 'activity', match: 'rest', - customType: activityTypeCaster + customType: activityTypeCaster, + prompt: { + start: 'What activity would you like to play?', + retry: + '{error} You must choose one of the following options: `yt`, `youtube`, `chess`, `park`, `poker`, `fish`, `fishing`, `fishington`, or `betrayal`.' + } } ], slash: true, @@ -85,29 +90,35 @@ export default class YouTubeCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { channel: VoiceChannel; activity: string } ): Promise<unknown> { - if (!args.channel?.id || args.channel?.type != 'GUILD_VOICE') + const channel = typeof args.channel === 'string' ? message.guild?.channels.cache.get(args.channel) : args.channel; + if (!channel || channel.type !== 'GUILD_VOICE') return await message.util.reply(`${util.emojis.error} Choose a valid voice channel`); - let target_application_id: string; - if (message.util.isSlash) target_application_id = args.activity; - else target_application_id = target_application_id = args.activity; + const target_application_id = message.util.isSlash ? args.activity : activityTypeCaster(message, args.activity); - // @ts-ignore: jank typings - // prettier-ignore - const invite = await this.client.api.channels(args.channel.id) - .invites.post({ - data: { - validate: null, - max_age: 604800, - max_uses: 0, - target_type: 2, - target_application_id, - temporary: false - } - }) - .catch(() => false); - if (!invite || !invite.code) - return await message.util.reply(`${this.client.util.emojis.error} An error occurred while generating your invite.`); + let response: string; + const invite = await (client as any).api + .channels(channel.id) + .invites.post({ + data: { + validate: null, + max_age: 604800, + max_uses: 0, + target_type: 2, + target_application_id, + temporary: false + } + }) + .catch((e: Error | DiscordAPIError) => { + if ((e as DiscordAPIError).code === 50013) { + response = `${util.emojis.error} I am missing permissions to make an invite in that channel.`; + return; + } else response = `${util.emojis.error} An error occurred while generating your invite: ${e?.message ?? e}`; + }); + if (response! || !invite || !invite.code) + return await message.util.reply( + response! ?? `${util.emojis.error} An unknown error occurred while generating your invite.` + ); else return await message.util.send(`https://discord.gg/${invite.code}`); } } diff --git a/src/commands/utilities/steal.ts b/src/commands/utilities/steal.ts new file mode 100644 index 0000000..92abcb2 --- /dev/null +++ b/src/commands/utilities/steal.ts @@ -0,0 +1,59 @@ +import { BushCommand, BushMessage } from '@lib'; +import { Emoji } from 'discord.js'; + +export default class StealCommand extends BushCommand { + public constructor() { + super('steal', { + aliases: ['steal', 'copyemoji'], + category: 'utilities', + description: { + content: 'Steal an emoji from another server and add it to your own.', + usage: 'steal <emoji/url> [--name name]', + examples: ['steal <:omegaclown:782630946435366942> --name ironm00n'] + }, + args: [ + { + id: 'emoji', + customType: util.arg.union('emoji', 'url'), + prompt: { + start: 'What emoji would you like to steal?', + retry: '{error} Pick a valid emoji.', + optional: true + } + }, + { id: 'name', match: 'option', flag: '--name', default: 'stolen_emoji' } + ], + slash: false, + channel: 'guild', + clientPermissions: ['SEND_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'], + userPermissions: ['SEND_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'] + }); + } + public override async exec(message: BushMessage, args: { emoji?: URL | Emoji; name: string }): Promise<unknown> { + if ((!args || !args.emoji) && !message.attachments.size) + return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`); + const image = + message.attachments.size && message.attachments.first()!.contentType?.includes('image/') + ? message.attachments.first()!.url + : args?.emoji instanceof Emoji + ? `https://cdn.discordapp.com/emojis/${args.emoji.id}` + : args?.emoji instanceof URL + ? args.emoji.href + : undefined; + + if (!image) return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`); + + const creationSuccess = await message + .guild!.emojis.create(image, args.name, { + reason: `Stolen by ${message.author.tag} (${message.author.id})` + }) + .catch((e: Error) => e); + + if (!(creationSuccess instanceof Error)) + return await message.util.reply(`${util.emojis.success} You successfully stole ${creationSuccess}.`); + else + return await message.util.reply( + `${util.emojis.error} The was an error stealing that emoji \`${creationSuccess.message}\`.` + ); + } +} diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts index a6c4665..e507036 100644 --- a/src/commands/utilities/whoHasRole.ts +++ b/src/commands/utilities/whoHasRole.ts @@ -33,7 +33,8 @@ export default class WhoHasRoleCommand extends BushCommand { ], channel: 'guild', clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + userPermissions: ['SEND_MESSAGES'], + typing: true }); } public override async exec(message: BushMessage | BushSlashMessage, args: { role: Role }): Promise<unknown> { |