mirror of
https://github.com/veganhacktivists/arabot.git
synced 2025-12-02 10:50:02 +01:00
Compare commits
51 Commits
topbal
...
feat/log-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1b9fdcd4e | ||
|
|
b3afe3f162 | ||
|
|
5bbc5057fc | ||
|
|
7943a2d1b8 | ||
|
|
3a4f8dba78 | ||
|
|
f4eac3cbe7 | ||
|
|
fe655ea0dc | ||
|
|
a95b1fde6e | ||
|
|
aad5066ba9 | ||
|
|
8302e11436 | ||
|
|
8c48473ef3 | ||
|
|
d90c985cec | ||
|
|
b6b50ea450 | ||
|
|
d00fddd51a | ||
|
|
e5f2c9436e | ||
|
|
0bb10b55ed | ||
|
|
d9c4f54299 | ||
|
|
77bbe97c6a | ||
|
|
a498cde933 | ||
|
|
750b10062f | ||
|
|
e348b09f80 | ||
|
|
4dc37ab31c | ||
|
|
396d69db06 | ||
|
|
94036984d3 | ||
|
|
0068fb5bdd | ||
|
|
1f3610a89d | ||
|
|
02298f2089 | ||
|
|
bb6ac8aef0 | ||
|
|
3f82f87317 | ||
|
|
fc2574e8e1 | ||
|
|
619aeb533b | ||
|
|
255ca62c33 | ||
|
|
ef0cf08bf8 | ||
|
|
113ebbbaee | ||
|
|
4a03675256 | ||
|
|
7fa844c24f | ||
|
|
5a42926c13 | ||
|
|
54f1c23c69 | ||
|
|
b3e1d11e72 | ||
|
|
d42332f290 | ||
|
|
534453fcc0 | ||
|
|
6fbb547ca7 | ||
|
|
a1beb4d347 | ||
|
|
48b30bfcb9 | ||
|
|
165a34ba0c | ||
|
|
c9a987a2a9 | ||
|
|
7aebbbc2fd | ||
|
|
779f8de43f | ||
|
|
0e77867010 | ||
|
|
c58360d563 | ||
|
|
3bf351e472 |
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -68,4 +68,4 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
2
.github/workflows/eslint.yml
vendored
2
.github/workflows/eslint.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload analysis results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: eslint-results.sarif
|
||||
wait-for-processing: true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
image: postgres:16
|
||||
container_name: postgres
|
||||
restart: always
|
||||
env_file:
|
||||
|
||||
948
package-lock.json
generated
948
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
@@ -29,30 +29,30 @@
|
||||
},
|
||||
"homepage": "https://github.com/veganhacktivists/arabot#readme",
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.5.2",
|
||||
"@sapphire/discord.js-utilities": "^7.0.2",
|
||||
"@sapphire/framework": "^4.7.2",
|
||||
"@sapphire/plugin-logger": "^3.0.6",
|
||||
"@sapphire/plugin-scheduled-tasks": "^8.0.0",
|
||||
"@sapphire/plugin-subcommands": "^5.0.0",
|
||||
"@sapphire/stopwatch": "^1.5.0",
|
||||
"@sapphire/time-utilities": "^1.7.10",
|
||||
"@prisma/client": "^5.7.1",
|
||||
"@sapphire/discord.js-utilities": "^7.1.5",
|
||||
"@sapphire/framework": "^5.0.5",
|
||||
"@sapphire/plugin-logger": "^4.0.1",
|
||||
"@sapphire/plugin-scheduled-tasks": "^10.0.0",
|
||||
"@sapphire/plugin-subcommands": "^6.0.2",
|
||||
"@sapphire/stopwatch": "^1.5.1",
|
||||
"@sapphire/time-utilities": "^1.7.11",
|
||||
"@sapphire/ts-config": "^5.0.0",
|
||||
"@sapphire/utilities": "^3.13.0",
|
||||
"@types/node": "^20.8.9",
|
||||
"bullmq": "^4.12.7",
|
||||
"discord.js": "^14.13.0",
|
||||
"redis": "^4.6.10",
|
||||
"@sapphire/utilities": "^3.15.1",
|
||||
"@types/node": "^20.10.6",
|
||||
"bullmq": "^5.1.1",
|
||||
"discord.js": "^14.14.1",
|
||||
"redis": "^4.6.12",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.2.2"
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||
"@typescript-eslint/parser": "^6.9.0",
|
||||
"eslint": "8.54.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"prettier": "3.1.0",
|
||||
"prisma": "^5.5.2"
|
||||
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
||||
"@typescript-eslint/parser": "^6.17.0",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"prettier": "3.1.1",
|
||||
"prisma": "^5.7.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `active` on the `Warning` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Warning" DROP COLUMN "active";
|
||||
@@ -256,7 +256,6 @@ model Warning {
|
||||
mod User @relation("warnMod", fields: [modId], references: [id])
|
||||
modId String
|
||||
time DateTime @default(now())
|
||||
active Boolean @default(true)
|
||||
note String
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ChannelType } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class AccessCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'access',
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { Message } from 'discord.js';
|
||||
import { ChannelType, TextChannel } from 'discord.js';
|
||||
|
||||
export class AnonymousCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'anonymous',
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Args, Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import type { Message } from 'discord.js';
|
||||
|
||||
export class ClearCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'clear',
|
||||
|
||||
@@ -31,7 +31,10 @@ import {
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class PrivateCommand extends Subcommand {
|
||||
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
|
||||
public constructor(
|
||||
context: Subcommand.LoaderContext,
|
||||
options: Subcommand.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'private',
|
||||
|
||||
@@ -24,7 +24,7 @@ import { getBalance } from '#utils/database/economy';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
|
||||
export class BalanceCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'balance',
|
||||
|
||||
@@ -26,7 +26,7 @@ import { EmbedBuilder } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class DailyCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'daily',
|
||||
|
||||
@@ -25,7 +25,7 @@ import { EmbedBuilder, TextChannel } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class BalanceCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'pay',
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { N1984 } from '#utils/gifs';
|
||||
import { addFunLog, countTotal } from '#utils/database/fun';
|
||||
|
||||
export class N1984Command extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: '1984',
|
||||
description: 'this is literally 1984',
|
||||
preconditions: ['ModOnly'],
|
||||
preconditions: ['CoordinatorOnly', 'ModOnly'],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,10 +45,26 @@ export class N1984Command extends Command {
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the user
|
||||
const { user } = interaction;
|
||||
const { member } = interaction;
|
||||
|
||||
await addFunLog(user.id, '1984');
|
||||
const count = await countTotal(user.id, '1984');
|
||||
// Type checks
|
||||
if (!(member instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await addFunLog(member.id, '1984');
|
||||
const count = await countTotal(member.id, '1984');
|
||||
|
||||
let embedFooter: string;
|
||||
if (count === 1) {
|
||||
embedFooter = `${member.displayName} 1984'd the server for the first time!`;
|
||||
} else {
|
||||
embedFooter = `${member.displayName} 1984'd the server ${count} times!`;
|
||||
}
|
||||
|
||||
// Creates the embed for the 1984 reaction
|
||||
// Add a 1 in 1000 chance of Dantas literally making ARA 1984
|
||||
@@ -58,9 +74,9 @@ export class N1984Command extends Command {
|
||||
: N1984[Math.floor(Math.random() * N1984.length)];
|
||||
const n1984Embed = new EmbedBuilder()
|
||||
.setColor('#ffffff')
|
||||
.setTitle(`${user.username} is happy!`)
|
||||
.setTitle(`${member.displayName} is happy!`)
|
||||
.setImage(random1984)
|
||||
.setFooter({ text: `${user.username}'s 1984 count: ${count}` });
|
||||
.setFooter({ text: embedFooter });
|
||||
|
||||
// Send the embed
|
||||
await interaction.reply({ embeds: [n1984Embed], fetchReply: true });
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Cringe } from '#utils/gifs';
|
||||
import { addFunLog, countTotal } from '#utils/database/fun';
|
||||
|
||||
export class CringeCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'cringe',
|
||||
@@ -44,19 +44,34 @@ export class CringeCommand extends Command {
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the user
|
||||
// TODO exception handling
|
||||
const { user } = interaction;
|
||||
const { member } = interaction;
|
||||
|
||||
await addFunLog(user.id, 'cringe');
|
||||
const count = await countTotal(user.id, 'cringe');
|
||||
// Type check
|
||||
if (!(member instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await addFunLog(member.id, 'cringe');
|
||||
const count = await countTotal(member.id, 'cringe');
|
||||
|
||||
let embedFooter: string;
|
||||
if (count === 1) {
|
||||
embedFooter = `${member.displayName} cringed for the first time!`;
|
||||
} else {
|
||||
embedFooter = `${member.displayName} cringed ${count} times!`;
|
||||
}
|
||||
|
||||
// Creates the embed for the cringe reaction
|
||||
const randomCringe = Cringe[Math.floor(Math.random() * Cringe.length)];
|
||||
const cringeEmbed = new EmbedBuilder()
|
||||
.setColor('#001148')
|
||||
.setTitle(`${user.username} feels immense cringe...`)
|
||||
.setTitle(`${member.displayName} feels immense cringe...`)
|
||||
.setImage(randomCringe)
|
||||
.setFooter({ text: `${user.username}'s cringe count: ${count}` });
|
||||
.setFooter({ text: embedFooter });
|
||||
|
||||
// Send the embed
|
||||
await interaction.reply({ embeds: [cringeEmbed], fetchReply: true });
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Happy } from '#utils/gifs';
|
||||
|
||||
export class HappyCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'happy',
|
||||
@@ -44,15 +44,22 @@ export class HappyCommand extends Command {
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the user
|
||||
// TODO exception handling
|
||||
const member = interaction.member!.user;
|
||||
const memberGuildMember = interaction.guild!.members.cache.get(member.id)!;
|
||||
const { member } = interaction;
|
||||
|
||||
// Type checks
|
||||
if (!(member instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Creates the embed for the happy reaction
|
||||
const randomHappy = Happy[Math.floor(Math.random() * Happy.length)];
|
||||
const happyEmbed = new EmbedBuilder()
|
||||
.setColor('#40ff00')
|
||||
.setTitle(`${memberGuildMember.displayName} is happy!`)
|
||||
.setTitle(`${member.displayName} is happy!`)
|
||||
.setImage(randomHappy);
|
||||
|
||||
// Send the embed
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Hugs } from '#utils/gifs';
|
||||
import { addFunLog, countTotal } from '#utils/database/fun';
|
||||
|
||||
export class HugCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'hug',
|
||||
@@ -54,20 +54,43 @@ export class HugCommand extends Command {
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the users
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const hugger = interaction.user;
|
||||
const hugger = interaction.member;
|
||||
|
||||
// Type Checks
|
||||
|
||||
if (!(hugger instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await addFunLog(hugger.id, 'hug', user.id);
|
||||
const count = await countTotal(hugger.id, 'hug', user.id);
|
||||
|
||||
let embedFooter: string;
|
||||
if (hugger.id === user.id) {
|
||||
if (count === 1) {
|
||||
embedFooter = `You hugged yourself for the first time!`;
|
||||
} else {
|
||||
embedFooter = `You hugged yourself ${count} times!`;
|
||||
}
|
||||
} else {
|
||||
if (count === 1) {
|
||||
embedFooter = `${hugger.displayName} hugged you for the first time!`;
|
||||
} else {
|
||||
embedFooter = `${hugger.displayName} hugged you ${count} times!`;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the embed for the hug
|
||||
const randomHug = Hugs[Math.floor(Math.random() * Hugs.length)];
|
||||
const hugEmbed = new EmbedBuilder()
|
||||
.setColor('#0099ff')
|
||||
.setTitle(`Hug from ${hugger.username}`)
|
||||
.setTitle(`Hug from ${hugger.displayName}`)
|
||||
.setImage(randomHug)
|
||||
.setFooter({
|
||||
text: `Amount of hugs given from ${hugger.username} to you: ${count}`,
|
||||
});
|
||||
.setFooter({ text: embedFooter });
|
||||
|
||||
// Send the hug
|
||||
await interaction.reply({
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Kill } from '#utils/gifs';
|
||||
import { addFunLog, countTotal } from '#utils/database/fun';
|
||||
|
||||
export class KillCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'kill',
|
||||
@@ -54,7 +54,16 @@ export class KillCommand extends Command {
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the users
|
||||
const user = interaction.options.getUser('user', true)!;
|
||||
const sender = interaction.user;
|
||||
const sender = interaction.member;
|
||||
|
||||
// Type checks
|
||||
if (!(sender instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.id === sender.id) {
|
||||
await interaction.reply('You changed your mind');
|
||||
@@ -64,15 +73,20 @@ export class KillCommand extends Command {
|
||||
await addFunLog(sender.id, 'kill', user.id);
|
||||
const count = await countTotal(sender.id, 'kill', user.id);
|
||||
|
||||
let embedFooter: string;
|
||||
if (count === 1) {
|
||||
embedFooter = `${sender.displayName} killed you for the first time!`;
|
||||
} else {
|
||||
embedFooter = `${sender.displayName} killed you ${count} times!`;
|
||||
}
|
||||
|
||||
// Creates the embed for the kill
|
||||
const randomKill = Kill[Math.floor(Math.random() * Kill.length)];
|
||||
const killEmbed = new EmbedBuilder()
|
||||
.setColor('#ff0000')
|
||||
.setTitle(`Kill from ${sender.username}`)
|
||||
.setTitle(`Kill from ${sender.displayName}`)
|
||||
.setImage(randomKill)
|
||||
.setFooter({
|
||||
text: `Amount of kills from ${sender.username} to you: ${count}`,
|
||||
});
|
||||
.setFooter({ text: embedFooter });
|
||||
|
||||
// Send the kill
|
||||
await interaction.reply({
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Poke } from '#utils/gifs';
|
||||
import { addFunLog, countTotal } from '#utils/database/fun';
|
||||
|
||||
export class PokeCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'poke',
|
||||
@@ -54,20 +54,42 @@ export class PokeCommand extends Command {
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the users
|
||||
const user = interaction.options.getUser('user', true)!;
|
||||
const sender = interaction.user;
|
||||
const sender = interaction.member;
|
||||
|
||||
// Type checks
|
||||
if (!(sender instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await addFunLog(sender.id, 'poke', user.id);
|
||||
const count = await countTotal(sender.id, 'poke', user.id);
|
||||
|
||||
let embedFooter: string;
|
||||
if (sender.id === user.id) {
|
||||
if (count === 1) {
|
||||
embedFooter = `You poked yourself for the first time!`;
|
||||
} else {
|
||||
embedFooter = `You poked yourself ${count} times!`;
|
||||
}
|
||||
} else {
|
||||
if (count === 1) {
|
||||
embedFooter = `${sender.displayName} poked you for the first time!`;
|
||||
} else {
|
||||
embedFooter = `${sender.displayName} poked you ${count} times!`;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the embed for the poke
|
||||
const randomPoke = Poke[Math.floor(Math.random() * Poke.length)];
|
||||
const pokeEmbed = new EmbedBuilder()
|
||||
.setColor('#0099ff')
|
||||
.setTitle(`Poke from ${sender.username}`)
|
||||
.setTitle(`Poke from ${sender.displayName}`)
|
||||
.setImage(randomPoke)
|
||||
.setFooter({
|
||||
text: `Amount of pokes from ${sender.username} to you: ${count}`,
|
||||
});
|
||||
.setFooter({ text: embedFooter });
|
||||
|
||||
// Send the poke
|
||||
await interaction.reply({
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Sad } from '#utils/gifs';
|
||||
|
||||
export class SadCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'sad',
|
||||
@@ -44,15 +44,22 @@ export class SadCommand extends Command {
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the user
|
||||
// TODO exception handling
|
||||
const member = interaction.member!.user;
|
||||
const memberGuildMember = interaction.guild!.members.cache.get(member.id)!;
|
||||
const { member } = interaction;
|
||||
|
||||
// Type checks
|
||||
if (!(member instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Creates the embed for the sad reaction
|
||||
const randomSad = Sad[Math.floor(Math.random() * Sad.length)];
|
||||
const sadEmbed = new EmbedBuilder()
|
||||
.setColor('#001148')
|
||||
.setTitle(`${memberGuildMember.displayName} is sad...`)
|
||||
.setTitle(`${member.displayName} is sad...`)
|
||||
.setImage(randomSad);
|
||||
|
||||
// Send the embed
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
*/
|
||||
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import { EmbedBuilder, GuildMember } from 'discord.js';
|
||||
import { Shrug } from '#utils/gifs';
|
||||
|
||||
export class ShrugCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'shrug',
|
||||
@@ -44,15 +44,22 @@ export class ShrugCommand extends Command {
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the user
|
||||
// TODO exception handling
|
||||
const member = interaction.member!.user;
|
||||
const memberGuildMember = interaction.guild!.members.cache.get(member.id)!;
|
||||
const { member } = interaction;
|
||||
|
||||
// Type checks
|
||||
if (!(member instanceof GuildMember)) {
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'Failed to fetch your user on the bot!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Creates the embed for the shrug reaction
|
||||
const randomShrug = Shrug[Math.floor(Math.random() * Shrug.length)];
|
||||
const shrugEmbed = new EmbedBuilder()
|
||||
.setColor('#001980')
|
||||
.setTitle(`${memberGuildMember.displayName} shrugs`)
|
||||
.setTitle(`${member.displayName} shrugs`)
|
||||
.setImage(randomShrug);
|
||||
|
||||
// Send the embed
|
||||
|
||||
@@ -26,7 +26,7 @@ import { addEmptyUser, updateUser } from '#utils/database/dbExistingUser';
|
||||
import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
|
||||
|
||||
export class BanCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'ban',
|
||||
|
||||
@@ -26,7 +26,7 @@ import { addTempBan, checkTempBan } from '#utils/database/tempBan';
|
||||
import { addEmptyUser, updateUser } from '#utils/database/dbExistingUser';
|
||||
|
||||
export class TempBanCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'tempban',
|
||||
@@ -258,11 +258,13 @@ export class TempBanCommand extends Command {
|
||||
await addTempBan(userId, modId, time.fromNow, reason);
|
||||
|
||||
// Create scheduled task to unban
|
||||
this.container.tasks.create(
|
||||
'tempBan',
|
||||
await this.container.tasks.create(
|
||||
{
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
name: 'tempBan',
|
||||
payload: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
time.offset,
|
||||
);
|
||||
|
||||
@@ -33,7 +33,7 @@ import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
|
||||
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
|
||||
|
||||
export class UnbanCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'unban',
|
||||
|
||||
@@ -31,7 +31,10 @@ import type { TextChannel, Snowflake } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class DiversityCommand extends Subcommand {
|
||||
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
|
||||
public constructor(
|
||||
context: Subcommand.LoaderContext,
|
||||
options: Subcommand.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'diversity',
|
||||
|
||||
@@ -25,7 +25,7 @@ import type { Message } from 'discord.js';
|
||||
import { ChannelType } from 'discord.js';
|
||||
|
||||
export class MoveAllCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'moveall',
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Args, Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import type { GuildMember, Message } from 'discord.js';
|
||||
|
||||
export class RenameUserCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'rename',
|
||||
|
||||
@@ -277,7 +277,7 @@ export async function restrictRun(
|
||||
}
|
||||
|
||||
export class RestrictCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'restrict',
|
||||
|
||||
@@ -25,11 +25,11 @@ import { getRestrictions } from '#utils/database/restriction';
|
||||
import { checkStaff } from '#utils/checker';
|
||||
|
||||
export class RestrictLogsCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'restrictlogs',
|
||||
description: 'Unrestricts a user',
|
||||
description: 'Shows restriction history for a user',
|
||||
preconditions: ['ModOnly'],
|
||||
});
|
||||
}
|
||||
@@ -75,10 +75,9 @@ export class RestrictLogsCommand extends Command {
|
||||
userId = user.id;
|
||||
}
|
||||
|
||||
let staffChannel = false;
|
||||
if (channel.type === ChannelType.GuildText) {
|
||||
const staffChannel = checkStaff(channel);
|
||||
if (staffChannel) {
|
||||
channel = channel as TextChannel;
|
||||
staffChannel = checkStaff(channel);
|
||||
|
||||
if (userId === null) {
|
||||
let topic: string[];
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { User, Message } from 'discord.js';
|
||||
import { restrictRun } from './restrict';
|
||||
|
||||
export class RestrictToleranceCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'restricttolerance',
|
||||
|
||||
@@ -24,7 +24,10 @@ import { CategoryChannel, ChannelType } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class RestrictToolsCommand extends Subcommand {
|
||||
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
|
||||
public constructor(
|
||||
context: Subcommand.LoaderContext,
|
||||
options: Subcommand.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'restricttools',
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
} from '#utils/database/restriction';
|
||||
|
||||
export class UnRestrictCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'unrestrict',
|
||||
|
||||
@@ -24,7 +24,7 @@ import { Duration, DurationFormatter } from '@sapphire/time-utilities';
|
||||
import { isNumber } from '#utils/maths';
|
||||
|
||||
export class SlowmodeCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'slowmode',
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { GuildMember, Message } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class SoftMuteCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'softmute',
|
||||
|
||||
@@ -20,14 +20,13 @@
|
||||
import { RegisterBehavior, Args } from '@sapphire/framework';
|
||||
import { Subcommand } from '@sapphire/plugin-subcommands';
|
||||
import {
|
||||
ChannelType,
|
||||
EmbedBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonInteraction,
|
||||
ButtonStyle,
|
||||
} from 'discord.js';
|
||||
import type { Message, GuildMember, TextChannel } from 'discord.js';
|
||||
import type { Message, GuildMember } from 'discord.js';
|
||||
import { isMessageInstance } from '@sapphire/discord.js-utilities';
|
||||
import { addExistingUser } from '#utils/database/dbExistingUser';
|
||||
import {
|
||||
@@ -39,11 +38,15 @@ import {
|
||||
} from '#utils/database/sus';
|
||||
import { checkStaff } from '#utils/checker';
|
||||
import IDs from '#utils/ids';
|
||||
import { createSusLogEmbed } from '#utils/embeds';
|
||||
|
||||
// TODO add a check when they join the server to give the user the sus role again
|
||||
|
||||
export class SusCommand extends Subcommand {
|
||||
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
|
||||
public constructor(
|
||||
context: Subcommand.LoaderContext,
|
||||
options: Subcommand.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'sus',
|
||||
@@ -201,14 +204,7 @@ export class SusCommand extends Subcommand {
|
||||
return;
|
||||
}
|
||||
|
||||
let staffChannel = false;
|
||||
let { channel } = interaction;
|
||||
if (channel !== null) {
|
||||
if (channel.type === ChannelType.GuildText) {
|
||||
channel = channel as TextChannel;
|
||||
staffChannel = checkStaff(channel);
|
||||
}
|
||||
}
|
||||
const staffChannel = checkStaff(interaction.channel);
|
||||
|
||||
// Gets the sus notes from the database
|
||||
const notes = await findNotes(user.id, true);
|
||||
@@ -224,34 +220,7 @@ export class SusCommand extends Subcommand {
|
||||
}
|
||||
|
||||
// Creates the embed to display the sus note
|
||||
const noteEmbed = new EmbedBuilder()
|
||||
.setColor('#0099ff')
|
||||
.setTitle(`${notes.length} sus notes for ${user.username}`)
|
||||
.setThumbnail(user.displayAvatarURL());
|
||||
|
||||
// Add up to 10 of the latest sus notes to the embed
|
||||
for (
|
||||
let i = notes.length > 10 ? notes.length - 10 : 0;
|
||||
i < notes.length;
|
||||
i += 1
|
||||
) {
|
||||
// Get mod name
|
||||
let mod = notes[i].modId;
|
||||
const modMember = guild.members.cache.get(mod);
|
||||
if (modMember !== undefined) {
|
||||
mod = modMember.displayName;
|
||||
}
|
||||
|
||||
// Add sus note to embed
|
||||
noteEmbed.addFields({
|
||||
name: `Sus ID: ${
|
||||
notes[i].id
|
||||
} | Moderator: ${mod} | Date: <t:${Math.floor(
|
||||
notes[i].time.getTime() / 1000,
|
||||
)}>`,
|
||||
value: notes[i].note,
|
||||
});
|
||||
}
|
||||
const noteEmbed = createSusLogEmbed(notes, user, guild);
|
||||
|
||||
// Sends the notes to the user
|
||||
await interaction.reply({
|
||||
@@ -554,11 +523,6 @@ export class SusCommand extends Subcommand {
|
||||
await user.roles.add(IDs.roles.restrictions.sus);
|
||||
}
|
||||
|
||||
// Checks if the user is xlevra to send a very kind message
|
||||
if (mod.id === '259624904746467329') {
|
||||
await message.reply('Fuck you for making me add this feature 🤬');
|
||||
}
|
||||
|
||||
await message.react('✅');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { addMute, removeMute, checkActive } from '#utils/database/vcMute';
|
||||
import { addExistingUser } from '#utils/database/dbExistingUser';
|
||||
|
||||
export class VCMuteCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'vcmute',
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/*
|
||||
Animal Rights Advocates Discord Bot
|
||||
Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Args, Command } from '@sapphire/framework';
|
||||
import type { User, Message, Snowflake, Guild } from 'discord.js';
|
||||
import { addExistingUser, updateUser } from '#utils/database/dbExistingUser';
|
||||
import { addWarn } from '#utils/database/warnings';
|
||||
|
||||
/*
|
||||
This command is not intended to be functional for now, this is purely to log
|
||||
warnings onto a database, so if we were to switch purely to ARA Bot, it would
|
||||
mean we would have a lot of the warns already in the database.
|
||||
*/
|
||||
export class WarnCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'warn',
|
||||
description: 'Warns a user (only used for logging to a database for now)',
|
||||
preconditions: [['CoordinatorOnly', 'ModOnly']],
|
||||
});
|
||||
}
|
||||
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
// Get arguments
|
||||
let user: User;
|
||||
try {
|
||||
user = await args.pick('user');
|
||||
} catch {
|
||||
await message.react('❌');
|
||||
await message.reply('User was not provided!');
|
||||
return;
|
||||
}
|
||||
const reason = args.finished ? null : await args.rest('string');
|
||||
const mod = message.member;
|
||||
|
||||
if (reason === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Warn reason was not provided!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod === null) {
|
||||
await message.react('❌');
|
||||
await message.reply(
|
||||
'Moderator not found! Try again or contact a developer!',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { guild } = message;
|
||||
|
||||
if (guild === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Guild not found! Try again or contact a developer!');
|
||||
return;
|
||||
}
|
||||
|
||||
const warn = await this.warn(user.id, mod.id, reason, guild);
|
||||
|
||||
if (!warn.success) {
|
||||
await message.react('❌');
|
||||
}
|
||||
|
||||
// await message.react('✅');
|
||||
}
|
||||
|
||||
private async warn(
|
||||
userId: Snowflake,
|
||||
modId: Snowflake,
|
||||
reason: string,
|
||||
guild: Guild,
|
||||
) {
|
||||
const info = {
|
||||
message: '',
|
||||
success: false,
|
||||
};
|
||||
|
||||
// Gets mod's GuildMember
|
||||
const mod = guild.members.cache.get(modId);
|
||||
|
||||
// Checks if guildMember is null
|
||||
if (mod === undefined) {
|
||||
info.message = 'Error fetching mod!';
|
||||
return info;
|
||||
}
|
||||
|
||||
// Check if mod is in database
|
||||
await updateUser(mod);
|
||||
|
||||
// Gets guildMember
|
||||
let member = guild.members.cache.get(userId);
|
||||
|
||||
if (member === undefined) {
|
||||
member = await guild.members.fetch(userId).catch(() => undefined);
|
||||
}
|
||||
|
||||
if (member === undefined) {
|
||||
info.message = 'User is not on this server';
|
||||
return info;
|
||||
}
|
||||
|
||||
await addExistingUser(member);
|
||||
|
||||
await addWarn(userId, modId, reason);
|
||||
|
||||
info.message = `Warned ${member}`;
|
||||
info.success = true;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
183
src/commands/mod/warning/deleteWarning.ts
Normal file
183
src/commands/mod/warning/deleteWarning.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/*
|
||||
Animal Rights Advocates Discord Bot
|
||||
Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { EmbedBuilder, TextChannel } from 'discord.js';
|
||||
import type { Message, Guild, User } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
import { deleteWarning, fetchWarning } from '#utils/database/warnings';
|
||||
import { checkStaff } from '#utils/checker';
|
||||
|
||||
export class DeleteWarningCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'deletewarning',
|
||||
aliases: ['delwarn', 'removewarning'],
|
||||
description: 'Deletes a warning',
|
||||
preconditions: ['ModOnly'],
|
||||
});
|
||||
}
|
||||
|
||||
// Registers that this is a slash command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand(
|
||||
(builder) =>
|
||||
builder
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName('id')
|
||||
.setDescription('ID for the warning')
|
||||
.setRequired(true),
|
||||
),
|
||||
{
|
||||
behaviorWhenNotIdentical: RegisterBehavior.Overwrite,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the arguments
|
||||
const warningId = interaction.options.getInteger('id', true);
|
||||
const mod = interaction.user;
|
||||
const { guild } = interaction;
|
||||
|
||||
// Checks if all the variables are of the right type
|
||||
if (guild === null) {
|
||||
await interaction.reply({
|
||||
content: 'Error fetching guild!',
|
||||
ephemeral: true,
|
||||
fetchReply: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const staffChannel = checkStaff(interaction.channel);
|
||||
|
||||
await interaction.deferReply({ ephemeral: !staffChannel });
|
||||
|
||||
const info = await this.deleteWarning(warningId, mod, guild);
|
||||
|
||||
await interaction.editReply({
|
||||
content: info.message,
|
||||
embeds: info.embeds,
|
||||
});
|
||||
}
|
||||
|
||||
// Non Application Command method for removing a warning
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
// Get arguments
|
||||
let warningId: number;
|
||||
try {
|
||||
warningId = await args.pick('integer');
|
||||
} catch {
|
||||
await message.react('❌');
|
||||
await message.react('Correct warning ID not provided!');
|
||||
return;
|
||||
}
|
||||
|
||||
const mod = message.author;
|
||||
|
||||
const { guild } = message;
|
||||
|
||||
if (guild === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Guild not found! Try again or contact a developer!');
|
||||
return;
|
||||
}
|
||||
|
||||
const info = await this.deleteWarning(warningId, mod, guild);
|
||||
|
||||
await message.reply({ content: info.message, embeds: info.embeds });
|
||||
if (!info.success) {
|
||||
await message.react('❌');
|
||||
}
|
||||
}
|
||||
|
||||
private async deleteWarning(warningId: number, mod: User, guild: Guild) {
|
||||
const info = {
|
||||
message: '',
|
||||
embeds: [] as EmbedBuilder[],
|
||||
success: false,
|
||||
};
|
||||
|
||||
const warning = await fetchWarning(warningId);
|
||||
|
||||
if (warning === null) {
|
||||
info.message = `Warning ID \`${warningId}\` not found!`;
|
||||
return info;
|
||||
}
|
||||
|
||||
await deleteWarning(warningId);
|
||||
info.success = true;
|
||||
|
||||
const userId = warning.userId;
|
||||
let user = guild.client.users.cache.get(userId);
|
||||
|
||||
if (user === undefined) {
|
||||
user = await guild.client.users.fetch(userId);
|
||||
if (user === undefined) {
|
||||
info.message = `Deleted warning ID \`${warningId}\`, but the user could not be found!`;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
// Log the warnings deletion
|
||||
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
|
||||
| TextChannel
|
||||
| undefined;
|
||||
|
||||
if (logChannel === undefined) {
|
||||
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
|
||||
| TextChannel
|
||||
| undefined;
|
||||
if (logChannel === undefined) {
|
||||
this.container.logger.error(
|
||||
'Delete Warning Error: Could not fetch log channel',
|
||||
);
|
||||
info.message =
|
||||
`Deleted warning for ${user} (Warning ID: ${warningId} but ` +
|
||||
'could not find the log channel.';
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
const message = new EmbedBuilder()
|
||||
.setColor('#28A745')
|
||||
.setAuthor({
|
||||
name: `Removed warning for ${user.tag}`,
|
||||
iconURL: `${user.displayAvatarURL()}`,
|
||||
})
|
||||
.addFields(
|
||||
{ name: 'User', value: `${user}`, inline: true },
|
||||
{ name: 'Moderator', value: `${mod}`, inline: true },
|
||||
{ name: 'Warning ID', value: `${warningId}`, inline: true },
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({ text: `ID: ${userId}` });
|
||||
|
||||
await logChannel.send({ embeds: [message] });
|
||||
|
||||
info.message = `Deleted warning for ${user}`;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
226
src/commands/mod/warning/warn.ts
Normal file
226
src/commands/mod/warning/warn.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/*
|
||||
Animal Rights Advocates Discord Bot
|
||||
Copyright (C) 2023, 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
Args,
|
||||
Command,
|
||||
container,
|
||||
RegisterBehavior,
|
||||
} from '@sapphire/framework';
|
||||
import type { User, Message, Snowflake, Guild, TextChannel } from 'discord.js';
|
||||
import { updateUser } from '#utils/database/dbExistingUser';
|
||||
import { addWarn } from '#utils/database/warnings';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class WarnCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'warn',
|
||||
description: 'Warns a user',
|
||||
preconditions: [['CoordinatorOnly', 'ModOnly']],
|
||||
});
|
||||
}
|
||||
|
||||
// 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 to warn')
|
||||
.setRequired(true),
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('Reason for the warning')
|
||||
.setRequired(true),
|
||||
),
|
||||
{
|
||||
behaviorWhenNotIdentical: RegisterBehavior.Overwrite,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the arguments
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const reason = interaction.options.getString('reason', true);
|
||||
const mod = interaction.user;
|
||||
const { guild } = interaction;
|
||||
|
||||
// Checks if all the variables are of the right type
|
||||
if (guild === null) {
|
||||
await interaction.reply({
|
||||
content: 'Error fetching guild!',
|
||||
ephemeral: true,
|
||||
fetchReply: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
const info = await this.warn(user.id, mod.id, reason, guild);
|
||||
|
||||
await interaction.editReply({
|
||||
content: info.message,
|
||||
});
|
||||
}
|
||||
|
||||
// Non Application Command method for warning a user
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
// Get arguments
|
||||
let user: User;
|
||||
try {
|
||||
user = await args.pick('user');
|
||||
} catch {
|
||||
await message.react('❌');
|
||||
await message.reply('User was not provided!');
|
||||
return;
|
||||
}
|
||||
const reason = args.finished ? null : await args.rest('string');
|
||||
const mod = message.member;
|
||||
|
||||
if (reason === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Warn reason was not provided!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod === null) {
|
||||
await message.react('❌');
|
||||
await message.reply(
|
||||
'Moderator not found! Try again or contact a developer!',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { guild } = message;
|
||||
|
||||
if (guild === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Guild not found! Try again or contact a developer!');
|
||||
return;
|
||||
}
|
||||
|
||||
const warn = await this.warn(user.id, mod.id, reason, guild);
|
||||
|
||||
if (!warn.success) {
|
||||
await message.react('❌');
|
||||
return;
|
||||
}
|
||||
|
||||
await message.react('✅');
|
||||
}
|
||||
|
||||
private async warn(
|
||||
userId: Snowflake,
|
||||
modId: Snowflake,
|
||||
reason: string,
|
||||
guild: Guild,
|
||||
) {
|
||||
const info = {
|
||||
message: '',
|
||||
success: false,
|
||||
};
|
||||
|
||||
// Gets mod's GuildMember
|
||||
const mod = guild.members.cache.get(modId);
|
||||
|
||||
// Checks if guildMember is null
|
||||
if (mod === undefined) {
|
||||
info.message = 'Error fetching mod!';
|
||||
return info;
|
||||
}
|
||||
|
||||
// Check if mod is in database
|
||||
await updateUser(mod);
|
||||
|
||||
// Gets User for person being restricted
|
||||
let user = guild.client.users.cache.get(userId);
|
||||
|
||||
if (user === undefined) {
|
||||
user = await guild.client.users.fetch(userId);
|
||||
if (user === undefined) {
|
||||
info.message = 'Error fetching user';
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
await addWarn(userId, modId, reason);
|
||||
|
||||
info.message = `Warned ${user}`;
|
||||
info.success = true;
|
||||
|
||||
// DM the reason
|
||||
|
||||
const dmEmbed = new EmbedBuilder()
|
||||
.setColor('#FF6700')
|
||||
.setAuthor({
|
||||
name: "You've been warned!",
|
||||
iconURL: `${user.displayAvatarURL()}`,
|
||||
})
|
||||
.addFields({ name: 'Reason', value: reason })
|
||||
.setTimestamp();
|
||||
|
||||
await user.send({ embeds: [dmEmbed] }).catch(() => {});
|
||||
|
||||
// Log the ban
|
||||
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
|
||||
| TextChannel
|
||||
| undefined;
|
||||
|
||||
if (logChannel === undefined) {
|
||||
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
|
||||
| TextChannel
|
||||
| undefined;
|
||||
if (logChannel === undefined) {
|
||||
container.logger.error('Warn Error: Could not fetch log channel');
|
||||
info.message = `Warned ${user} but could not find the log channel. This has been logged to the database.`;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
const message = new EmbedBuilder()
|
||||
.setColor('#FF6700')
|
||||
.setAuthor({
|
||||
name: `Warned ${user.tag}`,
|
||||
iconURL: `${user.displayAvatarURL()}`,
|
||||
})
|
||||
.addFields(
|
||||
{ name: 'User', value: `${user}`, inline: true },
|
||||
{ name: 'Moderator', value: `${mod}`, inline: true },
|
||||
{ name: 'Reason', value: reason },
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({ text: `ID: ${userId}` });
|
||||
|
||||
await logChannel.send({ embeds: [message] });
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
161
src/commands/mod/warning/warnings.ts
Normal file
161
src/commands/mod/warning/warnings.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/*
|
||||
Animal Rights Advocates Discord Bot
|
||||
Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import { ChannelType, EmbedBuilder } from 'discord.js';
|
||||
import type { Message, Guild, User } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
import { fetchWarnings } from '#utils/database/warnings';
|
||||
import { checkStaff } from '#utils/checker';
|
||||
import { createWarningsEmbed } from '#utils/embeds';
|
||||
|
||||
export class WarningsCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'warnings',
|
||||
aliases: ['warninglog', 'warnlog'],
|
||||
description: 'Shows all the warnings for the user',
|
||||
preconditions: ['ModOnly'],
|
||||
});
|
||||
}
|
||||
|
||||
// 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 to check the warnings for')
|
||||
.setRequired(true),
|
||||
),
|
||||
{
|
||||
behaviorWhenNotIdentical: RegisterBehavior.Overwrite,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Command run
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
// Get the arguments
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const { guild } = interaction;
|
||||
|
||||
// Checks if all the variables are of the right type
|
||||
if (guild === null) {
|
||||
await interaction.reply({
|
||||
content: 'Error fetching guild!',
|
||||
ephemeral: true,
|
||||
fetchReply: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const staffChannel = checkStaff(interaction.channel);
|
||||
|
||||
await interaction.deferReply({ ephemeral: !staffChannel });
|
||||
|
||||
const info = await this.warnings(user, guild);
|
||||
|
||||
await interaction.editReply({
|
||||
content: info.message,
|
||||
embeds: info.embeds,
|
||||
});
|
||||
}
|
||||
|
||||
// Non Application Command method for fetching warnings
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
// Get arguments
|
||||
let user: User | undefined;
|
||||
try {
|
||||
user = await args.pick('user');
|
||||
} catch {
|
||||
user = undefined;
|
||||
}
|
||||
|
||||
const { guild } = message;
|
||||
|
||||
if (guild === null) {
|
||||
await message.react('❌');
|
||||
await message.reply('Guild not found! Try again or contact a developer!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (user === undefined) {
|
||||
const { channel } = message;
|
||||
|
||||
if (channel.type !== ChannelType.GuildText) {
|
||||
await message.react('❌');
|
||||
await message.reply('User was not provided!');
|
||||
return;
|
||||
}
|
||||
|
||||
let topic: string[];
|
||||
|
||||
if (channel.parentId === IDs.categories.modMail) {
|
||||
// Checks if the channel topic has the user's snowflake
|
||||
if (channel.topic !== null) {
|
||||
topic = channel.topic.split(' ');
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
const userId = topic[2];
|
||||
|
||||
user = guild.client.users.cache.get(userId);
|
||||
|
||||
if (user === undefined) {
|
||||
user = await guild.client.users.fetch(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (user === undefined) {
|
||||
await message.react('❌');
|
||||
await message.reply('User was not provided!');
|
||||
return;
|
||||
}
|
||||
|
||||
const info = await this.warnings(user, guild);
|
||||
|
||||
await message.reply({ content: info.message, embeds: info.embeds });
|
||||
}
|
||||
|
||||
private async warnings(user: User, guild: Guild) {
|
||||
const info = {
|
||||
message: '',
|
||||
embeds: [] as EmbedBuilder[],
|
||||
};
|
||||
|
||||
const warnings = await fetchWarnings(user.id);
|
||||
|
||||
if (warnings.length === 0) {
|
||||
info.message = `${user} user has no warnings.`;
|
||||
return info;
|
||||
}
|
||||
|
||||
// Creates an embed to display the warnings
|
||||
const embed = createWarningsEmbed(warnings, user, guild);
|
||||
|
||||
info.embeds.push(embed);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,10 @@ import IDs from '#utils/ids';
|
||||
import { EmbedBuilder } from 'discord.js';
|
||||
|
||||
export class OutreachCommand extends Subcommand {
|
||||
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
|
||||
public constructor(
|
||||
context: Subcommand.LoaderContext,
|
||||
options: Subcommand.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'outreach',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class BookClubCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'bookclub',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class DebateHostCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'debatehost',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class GameNightHostCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'gamenight',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class GuestCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'guest',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class MentorCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'mentor',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class ModCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'mod',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class RestrictedAccessCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'restrictedaccess',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class StageHostCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'stagehost',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class TrialModCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'trialmod',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class TrialVerifierCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'trialverifier',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class VerifierCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'verifier',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class ActivistCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'activist',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class ARAVeganCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'aravegan',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class ConvincedCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'convinced',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class PlusCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'plus',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class TrustedCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'trusted',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class VeganCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'vegan',
|
||||
|
||||
@@ -23,7 +23,7 @@ import IDs from '#utils/ids';
|
||||
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
|
||||
|
||||
export class VegCuriousCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'vegcurious',
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
import type { Message } from 'discord.js';
|
||||
|
||||
export class ApplyCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'apply',
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { Message } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class RenameUserCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'count',
|
||||
|
||||
@@ -19,7 +19,7 @@ import { EmbedBuilder } from 'discord.js';
|
||||
import type { Message } from 'discord.js';
|
||||
|
||||
export class HelpCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'help',
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import { Command, RegisterBehavior } from '@sapphire/framework';
|
||||
|
||||
export class InfoCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'info',
|
||||
|
||||
@@ -22,7 +22,7 @@ import { Command } from '@sapphire/framework';
|
||||
import type { Message } from 'discord.js';
|
||||
|
||||
export class PingCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'ping',
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
import { manualVerification } from '#utils/database/verification';
|
||||
|
||||
export class VerifyCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'verify',
|
||||
|
||||
@@ -22,7 +22,7 @@ import IDs from '#utils/ids';
|
||||
import { checkVerificationFinish } from '#utils/database/verification';
|
||||
|
||||
export class VerifyTimeoutRemoveCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'verifytimeoutremove',
|
||||
|
||||
@@ -23,7 +23,7 @@ import { EmbedBuilder } from 'discord.js';
|
||||
import { getRank, xpToNextLevel } from '#utils/database/xp';
|
||||
|
||||
export class RankCommand extends Command {
|
||||
public constructor(context: Command.Context, options: Command.Options) {
|
||||
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'rank',
|
||||
|
||||
@@ -21,12 +21,14 @@ import {
|
||||
InteractionHandler,
|
||||
InteractionHandlerTypes,
|
||||
} from '@sapphire/framework';
|
||||
import type { PieceContext } from '@sapphire/framework';
|
||||
import type { ButtonInteraction, GuildMember } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class NonVeganAccessButtonHandler extends InteractionHandler {
|
||||
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
|
||||
public constructor(
|
||||
ctx: InteractionHandler.LoaderContext,
|
||||
options: InteractionHandler.Options,
|
||||
) {
|
||||
super(ctx, {
|
||||
...options,
|
||||
interactionHandlerType: InteractionHandlerTypes.Button,
|
||||
|
||||
@@ -21,12 +21,14 @@ import {
|
||||
InteractionHandler,
|
||||
InteractionHandlerTypes,
|
||||
} from '@sapphire/framework';
|
||||
import type { PieceContext } from '@sapphire/framework';
|
||||
import type { ButtonInteraction, GuildMember, TextChannel } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class WelcomeButtonHandler extends InteractionHandler {
|
||||
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
|
||||
public constructor(
|
||||
ctx: InteractionHandler.LoaderContext,
|
||||
options: InteractionHandler.Options,
|
||||
) {
|
||||
super(ctx, {
|
||||
...options,
|
||||
interactionHandlerType: InteractionHandlerTypes.Button,
|
||||
|
||||
@@ -25,7 +25,10 @@ import IDs from '#utils/ids';
|
||||
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
|
||||
|
||||
export class BanListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'guildBanAdd',
|
||||
|
||||
@@ -23,7 +23,10 @@ import { checkBan, getBanReason } from '#utils/database/ban';
|
||||
import { checkTempBan } from '#utils/database/tempBan';
|
||||
|
||||
export class BanJoinListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'guildMemberAdd',
|
||||
|
||||
@@ -25,7 +25,10 @@ import IDs from '#utils/ids';
|
||||
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
|
||||
|
||||
export class UnbanListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'guildBanRemove',
|
||||
|
||||
@@ -21,7 +21,10 @@ import { Listener } from '@sapphire/framework';
|
||||
import type { Message } from 'discord.js';
|
||||
|
||||
export class BotAppreciationListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCreate',
|
||||
|
||||
@@ -24,7 +24,10 @@ import type {
|
||||
import { Listener } from '@sapphire/framework';
|
||||
|
||||
export class OldCommandDeniedListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCommandDenied',
|
||||
|
||||
@@ -25,7 +25,10 @@ import { getLastCount, addCount } from '#utils/database/counting';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class XpListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCreate',
|
||||
|
||||
@@ -27,7 +27,10 @@ import {
|
||||
} from '#utils/database/dbExistingUser';
|
||||
|
||||
export class DbLeaveServerListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'guildMemberRemove',
|
||||
|
||||
@@ -24,7 +24,10 @@ import type {
|
||||
import { Listener } from '@sapphire/framework';
|
||||
|
||||
export class CommandDeniedListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'chatInputCommandDenied',
|
||||
|
||||
38
src/listeners/error.ts
Normal file
38
src/listeners/error.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/*
|
||||
Animal Rights Advocates Discord Bot
|
||||
Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Listener, ListenerErrorPayload } from '@sapphire/framework';
|
||||
|
||||
export class ErrorListener extends Listener {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'listenerError',
|
||||
});
|
||||
}
|
||||
|
||||
public run(error: Error, payload: ListenerErrorPayload) {
|
||||
this.container.logger.debug(
|
||||
`TEST ERROR: ${error.stack}\n\nPAYLOAD: ${payload.piece.name}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,10 @@ import { Listener } from '@sapphire/framework';
|
||||
import { setupTypes } from '#utils/database/outreach';
|
||||
|
||||
export class EventTypesReadyListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
once: true,
|
||||
|
||||
@@ -18,15 +18,24 @@
|
||||
*/
|
||||
|
||||
import { Listener } from '@sapphire/framework';
|
||||
import { ChannelType, EmbedBuilder } from 'discord.js';
|
||||
import type { GuildChannel } from 'discord.js';
|
||||
import { ChannelType } from 'discord.js';
|
||||
import type { GuildChannel, EmbedBuilder } from 'discord.js';
|
||||
import { setTimeout } from 'timers/promises';
|
||||
import IDs from '#utils/ids';
|
||||
import { checkActive, getRestrictions } from '#utils/database/restriction';
|
||||
import { findNotes } from '#utils/database/sus';
|
||||
import {
|
||||
createRestrictLogEmbed,
|
||||
createSusLogEmbed,
|
||||
createWarningsEmbed,
|
||||
} from '#utils/embeds';
|
||||
import { fetchWarnings } from '#utils/database/warnings';
|
||||
|
||||
export class ModMailCreateListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'channelCreate',
|
||||
@@ -51,6 +60,16 @@ export class ModMailCreateListener extends Listener {
|
||||
// Get the user's ID
|
||||
const userId = topic[2];
|
||||
|
||||
// Gets user who created ModMail
|
||||
let user = guild.client.users.cache.get(userId);
|
||||
|
||||
if (user === undefined) {
|
||||
user = await guild.client.users.fetch(userId);
|
||||
if (user === undefined) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the user is currently restricted on the database
|
||||
if (!(await checkActive(userId))) return;
|
||||
|
||||
@@ -60,81 +79,21 @@ export class ModMailCreateListener extends Listener {
|
||||
|
||||
// Creation of embeds
|
||||
// Restriction Logs
|
||||
const restrictEmbed = new EmbedBuilder()
|
||||
.setColor('#FF6700')
|
||||
.setTitle(`${restrictions.length} restrictions`)
|
||||
.setFooter({ text: `ID: ${userId}` });
|
||||
const embeds: EmbedBuilder[] = [];
|
||||
embeds.push(createRestrictLogEmbed(restrictions, user, guild));
|
||||
|
||||
// Add up to 10 of the latest restrictions to the embed
|
||||
for (
|
||||
let i = restrictions.length > 10 ? restrictions.length - 10 : 0;
|
||||
i < restrictions.length;
|
||||
i += 1
|
||||
) {
|
||||
// Get mod names
|
||||
let restMod = restrictions[i].modId;
|
||||
const restModMember = guild.members.cache.get(restMod);
|
||||
if (restModMember !== undefined) {
|
||||
restMod = restModMember.displayName;
|
||||
}
|
||||
let endRestMod = restrictions[i].endModId;
|
||||
if (endRestMod !== null) {
|
||||
const endRestModMember = guild.members.cache.get(endRestMod);
|
||||
if (endRestModMember !== undefined) {
|
||||
endRestMod = endRestModMember.displayName;
|
||||
}
|
||||
}
|
||||
// Warnings
|
||||
const warnings = await fetchWarnings(userId);
|
||||
|
||||
let restTitle = `Restriction: ${i + 1} | Restricted by: ${restMod} | `;
|
||||
|
||||
if (endRestMod !== null) {
|
||||
restTitle += `Unrestricted by: ${endRestMod} | `;
|
||||
} else {
|
||||
restTitle += 'Currently Restricted | ';
|
||||
}
|
||||
|
||||
restTitle += `Date: <t:${Math.floor(
|
||||
restrictions[i].startTime.getTime() / 1000,
|
||||
)}>`;
|
||||
|
||||
restrictEmbed.addFields({
|
||||
name: restTitle,
|
||||
value: restrictions[i].reason,
|
||||
});
|
||||
}
|
||||
embeds.push(createWarningsEmbed(warnings, user, guild));
|
||||
|
||||
// Sus Notes
|
||||
const notes = await findNotes(userId, true);
|
||||
|
||||
const susEmbed = new EmbedBuilder()
|
||||
.setColor('#0099ff')
|
||||
.setTitle(`${notes.length} sus notes`);
|
||||
|
||||
// Add up to 10 of the latest sus notes to the embed
|
||||
for (
|
||||
let i = notes.length > 10 ? notes.length - 10 : 0;
|
||||
i < notes.length;
|
||||
i += 1
|
||||
) {
|
||||
// Get mod name
|
||||
const modGuildMember = guild.members.cache.get(notes[i].modId);
|
||||
let mod = notes[i].modId;
|
||||
if (modGuildMember !== undefined) {
|
||||
mod = modGuildMember.displayName;
|
||||
}
|
||||
// Add sus note to embed
|
||||
susEmbed.addFields({
|
||||
name: `Sus ID: ${
|
||||
notes[i].id
|
||||
} | Moderator: ${mod} | Date: <t:${Math.floor(
|
||||
notes[i].time.getTime() / 1000,
|
||||
)}>`,
|
||||
value: notes[i].note,
|
||||
});
|
||||
}
|
||||
embeds.push(createSusLogEmbed(notes, user, guild));
|
||||
|
||||
// Set a timeout for 1 second and then send the 2 embeds
|
||||
await setTimeout(1000);
|
||||
await channel.send({ embeds: [restrictEmbed, susEmbed] });
|
||||
await channel.send({ embeds: embeds });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ import type { Client, TextChannel } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class NonVeganAccessReady extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
once: true,
|
||||
|
||||
@@ -24,7 +24,10 @@ import { Listener } from '@sapphire/framework';
|
||||
import type { Client } from 'discord.js';
|
||||
|
||||
export class ReadyListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
once: true,
|
||||
|
||||
@@ -33,7 +33,10 @@ import { blockedRoles, blockedRolesAfterRestricted } from '#utils/blockedRoles';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class RolesJoinServerListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'guildMemberAdd',
|
||||
|
||||
@@ -23,7 +23,10 @@ import type { Message } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class Suggestions extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCreate',
|
||||
|
||||
@@ -22,7 +22,10 @@ import type { VoiceState } from 'discord.js';
|
||||
import { checkActive, removeMute } from '#utils/database/vcMute';
|
||||
|
||||
export class VCMuteListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'voiceStateUpdate',
|
||||
|
||||
@@ -56,7 +56,10 @@ import { rolesToString } from '#utils/formatter';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class VerificationJoinVCListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'voiceStateUpdate',
|
||||
@@ -151,14 +154,16 @@ export class VerificationJoinVCListener extends Listener {
|
||||
]);
|
||||
|
||||
// Start 15-minute timer if verifier does not join
|
||||
this.container.tasks.create(
|
||||
'verifyTimeout',
|
||||
await this.container.tasks.create(
|
||||
{
|
||||
channelId: channel.id,
|
||||
userId: member.id,
|
||||
name: 'verifyTimeout',
|
||||
payload: {
|
||||
channelId: channel.id,
|
||||
userId: member.id,
|
||||
},
|
||||
},
|
||||
900_000,
|
||||
); // 15 minutes
|
||||
900_000, // 15 minutes
|
||||
);
|
||||
}
|
||||
|
||||
// Check how many voice channels there are
|
||||
@@ -506,11 +511,13 @@ export class VerificationJoinVCListener extends Listener {
|
||||
await giveVerificationRoles(user, info.roles);
|
||||
// Add timeout if they do not have activist role
|
||||
if (!info.roles.activist) {
|
||||
this.container.tasks.create(
|
||||
'verifyUnblock',
|
||||
await this.container.tasks.create(
|
||||
{
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
name: 'verifyUnblock',
|
||||
payload: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
info.roles.vegan || info.roles.convinced ? 604800000 : 1814400000,
|
||||
);
|
||||
|
||||
@@ -37,7 +37,10 @@ import { fibonacci } from '#utils/maths';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class VerificationLeaveVCListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'voiceStateUpdate',
|
||||
@@ -103,11 +106,13 @@ export class VerificationLeaveVCListener extends Listener {
|
||||
// Creates the length of the time for the ban
|
||||
const banLength = fibonacci(incompleteCount) * 3600_000;
|
||||
|
||||
this.container.tasks.create(
|
||||
'verifyUnblock',
|
||||
await this.container.tasks.create(
|
||||
{
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
name: 'verifyUnblock',
|
||||
payload: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
banLength,
|
||||
);
|
||||
|
||||
@@ -22,7 +22,10 @@ import type { Message } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class VerificationMessageCounter extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCreate',
|
||||
|
||||
@@ -29,7 +29,10 @@ import { createVerificationVoice } from '#utils/verification';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class VerificationReady extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
once: true,
|
||||
|
||||
@@ -24,7 +24,10 @@ import type { Client, TextChannel } from 'discord.js';
|
||||
import IDs from '#utils/ids';
|
||||
|
||||
export class VerificationReady extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
once: true,
|
||||
|
||||
@@ -23,7 +23,10 @@ import { addXp, checkCanAddXp } from '#utils/database/xp';
|
||||
import { randint } from '#utils/maths';
|
||||
|
||||
export class XpListener extends Listener {
|
||||
public constructor(context: Listener.Context, options: Listener.Options) {
|
||||
public constructor(
|
||||
context: Listener.LoaderContext,
|
||||
options: Listener.Options,
|
||||
) {
|
||||
super(context, {
|
||||
...options,
|
||||
event: 'messageCreate',
|
||||
|
||||
@@ -24,7 +24,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class DiversityMonMessageTask extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, {
|
||||
|
||||
@@ -24,7 +24,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class DiversityWedMessageTask extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, {
|
||||
|
||||
@@ -24,7 +24,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class RestrictedMessageTask extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, {
|
||||
|
||||
@@ -24,7 +24,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class StandupTask extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, {
|
||||
|
||||
@@ -24,7 +24,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class VerifyReminder extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, {
|
||||
|
||||
@@ -25,7 +25,7 @@ import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
|
||||
|
||||
export class TempBan extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, options);
|
||||
@@ -102,6 +102,6 @@ export class TempBan extends ScheduledTask {
|
||||
|
||||
declare module '@sapphire/plugin-scheduled-tasks' {
|
||||
interface ScheduledTasks {
|
||||
tempBan: never;
|
||||
tempBan: { userId: string; guildId: string };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
|
||||
|
||||
export class VerifyTimeout extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, options);
|
||||
@@ -56,6 +56,6 @@ export class VerifyTimeout extends ScheduledTask {
|
||||
|
||||
declare module '@sapphire/plugin-scheduled-tasks' {
|
||||
interface ScheduledTasks {
|
||||
verifyTimeout: never;
|
||||
verifyTimeout: { channelId: string; userId: string };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import IDs from '#utils/ids';
|
||||
|
||||
export class VerifyUnblock extends ScheduledTask {
|
||||
public constructor(
|
||||
context: ScheduledTask.Context,
|
||||
context: ScheduledTask.LoaderContext,
|
||||
options: ScheduledTask.Options,
|
||||
) {
|
||||
super(context, options);
|
||||
@@ -56,6 +56,6 @@ export class VerifyUnblock extends ScheduledTask {
|
||||
|
||||
declare module '@sapphire/plugin-scheduled-tasks' {
|
||||
interface ScheduledTasks {
|
||||
verifyUnblock: never;
|
||||
verifyUnblock: { userId: string; guildId: string };
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user