diff --git a/src/commands/fun/hug.ts b/src/commands/fun/hug.ts
new file mode 100644
index 0000000..847013f
--- /dev/null
+++ b/src/commands/fun/hug.ts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ Animal Rights Advocates Discord Bot
+ Copyright (C) 2022 Anthony Berg
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+import { Command, RegisterBehavior } from '@sapphire/framework';
+import { MessageEmbed } from 'discord.js';
+import { Hugs } from '../../utils/gifs';
+
+export class HugCommand extends Command {
+ public constructor(context: Command.Context, options: Command.Options) {
+ super(context, {
+ ...options,
+ name: 'hug',
+ description: 'Hug a user',
+ });
+ }
+
+ // Registers that this is a slash command
+ public override registerApplicationCommands(registry: Command.Registry) {
+ registry.registerChatInputCommand(
+ (builder) => builder
+ .setName(this.name)
+ .setDescription(this.description)
+ .addUserOption((option) => option.setName('user')
+ .setDescription('User you want to hug')
+ .setRequired(true)),
+ {
+ behaviorWhenNotIdentical: RegisterBehavior.Overwrite,
+ },
+ );
+ }
+
+ // Command run
+ public async chatInputRun(interaction: Command.ChatInputInteraction) {
+ // Get the users
+ const user = interaction.options.getUser('user')!;
+ const hugger = interaction.member!.user;
+ const huggerGuildMember = interaction.guild!.members.cache.get(hugger.id)!;
+
+ // Creates the embed for the hug
+ const randomHug = Hugs[Math.floor(Math.random() * Hugs.length)];
+ const hugEmbed = new MessageEmbed()
+ .setColor('#0099ff')
+ .setTitle(`Hug from ${huggerGuildMember.displayName}`)
+ .setImage(randomHug);
+
+ // Send the hug
+ await interaction.reply({ content: `<@${user.id}>`, embeds: [hugEmbed], fetchReply: true });
+ }
+}
diff --git a/src/listeners/deniedPermission.ts b/src/listeners/deniedPermission.ts
new file mode 100644
index 0000000..e8952ef
--- /dev/null
+++ b/src/listeners/deniedPermission.ts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ Animal Rights Advocates Discord Bot
+ Copyright (C) 2022 Anthony Berg
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import type { UserError, ChatInputCommandDeniedPayload } from '@sapphire/framework';
+import { Listener } from '@sapphire/framework';
+
+export class CommandDeniedListener extends Listener {
+ public constructor(context: Listener.Context, options: Listener.Options) {
+ super(context, {
+ ...options,
+ once: false,
+ event: 'chatInputCommandDenied',
+ });
+ }
+
+ public run(error: UserError, { interaction }: ChatInputCommandDeniedPayload) {
+ return interaction.reply(error.message);
+ }
+}
diff --git a/src/preconditions/PatronOnly.ts b/src/preconditions/PatronOnly.ts
new file mode 100644
index 0000000..48cfbf7
--- /dev/null
+++ b/src/preconditions/PatronOnly.ts
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ Animal Rights Advocates Discord Bot
+ Copyright (C) 2022 Anthony Berg
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import { AllFlowsPrecondition } from '@sapphire/framework';
+import type { CommandInteraction, ContextMenuInteraction, Message } from 'discord.js';
+import { IDs } from '../utils/ids';
+
+export class PatreonOnlyPrecondition extends AllFlowsPrecondition {
+ public override async messageRun(message: Message) {
+ // for message command
+ return this.checkPatreon(message.author.id);
+ }
+
+ public override async chatInputRun(interaction: CommandInteraction) {
+ // for slash command
+ return this.checkPatreon(interaction.user.id);
+ }
+
+ public override async contextMenuRun(interaction: ContextMenuInteraction) {
+ // for context menu command
+ return this.checkPatreon(interaction.user.id);
+ }
+
+ private async checkPatreon(userId: string) {
+ return userId === IDs.roles.patron
+ ? this.ok()
+ : this.error({ message: 'Only patreon supporters can run this command!' });
+ }
+}
+
+declare module '@sapphire/framework' {
+ interface Preconditions {
+ VerifierOnly: never;
+ }
+}
diff --git a/src/utils/gifs.ts b/src/utils/gifs.ts
new file mode 100644
index 0000000..381251f
--- /dev/null
+++ b/src/utils/gifs.ts
@@ -0,0 +1,7 @@
+export const Hugs = [
+ 'https://c.tenor.com/FTf559jroJ0AAAAd/couple-cats-cat-love.gif',
+ 'https://c.tenor.com/j9ovpes78QsAAAAC/huge-hug-bromance.gif',
+ 'https://c.tenor.com/K2uYNMCeqe4AAAAC/bear-hug.gif',
+ 'https://c.tenor.com/Etrdmkw-GCAAAAAC/animals-fauna.gif',
+ 'https://c.tenor.com/bq2zhO_XTeAAAAAC/cat-pets.gif',
+];
diff --git a/src/utils/ids.ts b/src/utils/ids.ts
index 832c115..9ea9830 100644
--- a/src/utils/ids.ts
+++ b/src/utils/ids.ts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
/*
Animal Rights Advocates Discord Bot
Copyright (C) 2022 Anthony Berg
@@ -40,7 +41,11 @@ const IDs = {
staff: {
coordinator: '993636242019323904',
devCoordinator: '966031741099855973',
+ restricted: '851624392928264222',
+ moderator: '826157475815489598',
+ verifier: '871802735031373856',
},
+ patron: '765370219207852055',
},
channels: {
staff: {