Compare commits

..

No commits in common. "32776a23117d9e20c5839b22238286b844f38fd7" and "63c3b14b1c974f7d95c8c6e6b63a573f43e6cc2f" have entirely different histories.

13 changed files with 378 additions and 432 deletions

View File

@ -10,11 +10,8 @@ POSTGRES_USER=USERNAME
POSTGRES_PASSWORD=PASSWORD
POSTGRES_DB=DB
# Redis (if running everything within docker compose, use "redis" for the host and leave the rest empty)
REDIS_HOST= # URL to redis database
REDIS_USER= # redis database user
REDIS_PASSWORD= # redis database password
REDIS_PORT= # redis database port
# Redis
REDIS_URL= # URL to redis database (if running everything within docker compose, use "redis")
# Database URL (designed for Postgres, but designed on Prisma)
DATABASE_URL= # "postgresql://USERNAME:PASSWORD@postgres:5432/DB?schema=ara&sslmode=prefer"

View File

@ -1,5 +0,0 @@
[phases.build]
cmds = ["pnpm prisma generate", "..."]
[start]
cmd = 'pnpm run start:migrate'

View File

@ -33,31 +33,31 @@
"node": ">=20",
"pnpm": ">=9"
},
"packageManager": "pnpm@9.6.0",
"dependencies": {
"@prisma/client": "^5.22.0",
"@sapphire/discord.js-utilities": "^7.3.2",
"@sapphire/framework": "^5.3.2",
"@prisma/client": "^5.18.0",
"@sapphire/discord.js-utilities": "^7.3.0",
"@sapphire/framework": "^5.2.1",
"@sapphire/plugin-logger": "^4.0.2",
"@sapphire/plugin-scheduled-tasks": "^10.0.2",
"@sapphire/plugin-scheduled-tasks": "^10.0.1",
"@sapphire/plugin-subcommands": "^6.0.3",
"@sapphire/stopwatch": "^1.5.4",
"@sapphire/time-utilities": "^1.7.14",
"@sapphire/stopwatch": "^1.5.2",
"@sapphire/time-utilities": "^1.7.12",
"@sapphire/ts-config": "^5.0.1",
"@sapphire/utilities": "^3.18.1",
"bullmq": "^5.34.10",
"discord.js": "^14.17.3",
"ioredis": "^5.4.2",
"@sapphire/utilities": "^3.17.0",
"bullmq": "^5.12.10",
"discord.js": "^14.15.3",
"ioredis": "^5.4.1",
"ts-node": "^10.9.2",
"typescript": "~5.4.5"
},
"devDependencies": {
"@types/node": "^20.17.13",
"@types/node": "^20.16.1",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint": "8.56.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "3.2.4",
"prisma": "^5.22.0"
},
"packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228"
"prisma": "^5.18.0"
}
}

618
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import type { Message } from 'discord.js';
import { ChannelType, TextChannel } from 'discord.js';
export class AnonymousCommand extends Command {
@ -67,8 +67,8 @@ export class AnonymousCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -77,17 +77,8 @@ export class AnonymousCommand extends Command {
if (interaction.channel === null) {
await interaction.reply({
content: 'Error getting the channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
});
return;
}
if (!interaction.channel.isSendable()) {
await interaction.reply({
content: `I do not have sufficient permissions to send a message in ${interaction.channel}!`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -95,8 +86,8 @@ export class AnonymousCommand extends Command {
await interaction.channel.send(message);
await interaction.reply({
content: 'Sent the message',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -104,8 +95,8 @@ export class AnonymousCommand extends Command {
if (channel.type !== ChannelType.GuildText) {
await interaction.reply({
content: 'Could not send, unsupported text channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
}
@ -114,8 +105,8 @@ export class AnonymousCommand extends Command {
await interaction.reply({
content: 'Sent the message',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
}
@ -130,7 +121,7 @@ export class AnonymousCommand extends Command {
return;
}
if (channel.isSendable()) {
if (channel.isTextBased()) {
await channel.send(text);
} else {
await message.react('❌');

View File

@ -30,9 +30,9 @@ import {
TextChannel,
GuildMember,
Snowflake,
MessageFlagsBitField,
} from 'discord.js';
import type { Message } from 'discord.js';
import { isMessageInstance } from '@sapphire/discord.js-utilities';
import {
addSusNoteDB,
findNotes,
@ -407,21 +407,16 @@ export class SusCommand extends Subcommand {
const message = await interaction.reply({
embeds: [noteEmbed],
components: [buttons],
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
// Checks if the message is not an APIMessage
if (message.resource === null) {
if (!isMessageInstance(message)) {
await interaction.editReply('Failed to retrieve the message :(');
return;
}
if (!channel.isSendable()) {
await interaction.editReply('Cannot send messages in this channel!');
return;
}
// Listen for the button presses
const collector = channel.createMessageComponentCollector({
max: 1, // Maximum of 1 button press
@ -524,8 +519,8 @@ export class SusCommand extends Subcommand {
if (guild === null || channel === null) {
await interaction.reply({
content: 'Error fetching guild or channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -536,8 +531,8 @@ export class SusCommand extends Subcommand {
if (member === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -550,8 +545,8 @@ export class SusCommand extends Subcommand {
if (notes.length === 0) {
await interaction.reply({
content: `${user} had no notes!`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -601,21 +596,16 @@ export class SusCommand extends Subcommand {
const message = await interaction.reply({
embeds: [noteEmbed],
components: [buttons],
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
// Checks if the message is not an APIMessage
if (message.resource === null) {
if (!isMessageInstance(message)) {
await interaction.editReply('Failed to retrieve the message :(');
return;
}
if (!channel.isSendable()) {
await interaction.editReply('Cannot send messages in this channel!');
return;
}
// Listen for the button presses
const collector = channel.createMessageComponentCollector({
max: 1, // Maximum of 1 button press

View File

@ -17,8 +17,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { isMessageInstance } from '@sapphire/discord.js-utilities';
import { Command } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import type { Message } from 'discord.js';
export class PingCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -40,13 +41,12 @@ export class PingCommand extends Command {
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
const msg = await interaction.reply({
content: 'Ping?',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
if (msg.resource !== null && msg.resource.message !== null) {
const diff =
msg.resource.message.createdTimestamp - interaction.createdTimestamp;
if (isMessageInstance(msg)) {
const diff = msg.createdTimestamp - interaction.createdTimestamp;
const ping = Math.round(this.container.client.ws.ping);
return interaction.editReply(
`Pong 🏓! (Round trip took: ${diff}ms. Heartbeat: ${ping}ms.)`,
@ -57,11 +57,6 @@ export class PingCommand extends Command {
}
public async messageRun(message: Message) {
if (!message.channel.isSendable()) {
// TODO manage logging/errors properly
return;
}
const msg = await message.channel.send('Ping?');
const diff = msg.createdTimestamp - message.createdTimestamp;

View File

@ -27,10 +27,6 @@ import '@sapphire/plugin-logger/register';
import { PrismaClient } from '@prisma/client';
import { Redis } from 'ioredis';
const REDIS_PORT = process.env.REDIS_PORT
? parseInt(process.env.REDIS_PORT)
: undefined;
// Setting up the Sapphire client
const client = new SapphireClient({
defaultPrefix: process.env.DEFAULT_PREFIX,
@ -53,10 +49,7 @@ const client = new SapphireClient({
tasks: {
bull: {
connection: {
host: process.env.REDIS_HOST,
username: process.env.REDIS_USER,
password: process.env.REDIS_PASSWORD,
port: REDIS_PORT,
host: process.env.REDIS_URL,
},
},
},
@ -69,12 +62,9 @@ const main = async () => {
client.logger.info('Logging in');
// Create databases
container.database = new PrismaClient();
container.database = await new PrismaClient();
container.redis = new Redis({
host: process.env.REDIS_HOST,
username: process.env.REDIS_USER,
password: process.env.REDIS_PASSWORD,
port: REDIS_PORT,
host: process.env.REDIS_URL,
db: 1,
});

View File

@ -49,11 +49,6 @@ export class XpListener extends Listener {
// If no counts exist on the database, then create the first count from the bot
if (lastCount === null) {
if (this.container.client.id === null) {
if (!message.channel.isSendable()) {
// TODO manage logging/errors properly
return;
}
message.channel.send(
'An unexpected error occurred trying to set up the counting channel, please contact a developer!',
);
@ -68,11 +63,6 @@ export class XpListener extends Listener {
lastCount = await getLastCount();
if (lastCount === null) {
if (!message.channel.isSendable()) {
// TODO manage logging/errors properly
return;
}
message.channel.send(
'An unexpected error occurred, please contact a developer!',
);

View File

@ -22,7 +22,6 @@
import { Listener } from '@sapphire/framework';
import type { Client } from 'discord.js';
import IDs from '#utils/ids';
export class ReadyListener extends Listener {
public constructor(
@ -36,24 +35,8 @@ export class ReadyListener extends Listener {
});
}
public async run(client: Client) {
public run(client: Client) {
const { username, id } = client.user!;
this.container.logger.info(`Successfully logged in as ${username} (${id})`);
const botLogChannel = await client.channels.fetch(IDs.channels.logs.bot);
if (botLogChannel === null) {
this.container.logger.error(
'ReadyListener: Could not find the channel for bot logs.',
);
return;
} else if (!botLogChannel.isSendable()) {
this.container.logger.info(
'ReadyListener: No permission to send in bots logs channel.',
);
return;
}
botLogChannel.send('The bot has started up!');
}
}

View File

@ -83,11 +83,6 @@ export class Suggestions extends Listener {
return;
}
if (!mailbox.isSendable()) {
// TODO manage logging/errors properly
return;
}
const sent = await mailbox.send({
embeds: [suggestion],
content: message.author.toString(),

View File

@ -18,7 +18,6 @@
*/
const devIDs = {
guild: '999431674972618792',
roles: {
trusted: '999431675081666599',
booster: '',
@ -127,7 +126,6 @@ const devIDs = {
},
logs: {
restricted: '999431681217937513',
bot: '999431681217937516',
economy: '999431681599623198',
sus: '999431681599623199',
},

View File

@ -20,18 +20,17 @@
import devIDs from '#utils/devIDs';
let IDs = {
guild: '730907954345279591',
roles: {
trusted: '1329089675977035879',
trusted: '731563158011117590',
booster: '731213264540795012',
nonvegan: {
nonvegan: '1329093962153332848',
vegCurious: '1329107984227369020',
nonvegan: '774763753308815400',
vegCurious: '832656046572961803',
convinced: '797132019166871612',
},
vegan: {
vegan: '788114978020392982',
activist: '1329112833115295815',
activist: '730915638746546257',
nvAccess: '1076857105648209971',
plus: '798682625619132428',
araVegan: '995394977658044506',
@ -76,7 +75,7 @@ let IDs = {
stageHost: '854893757593419786',
patron: '765370219207852055',
patreon: '993848684640997406',
verifyBlock: '1329107805130461247',
verifyBlock: '1032765019269640203',
bookClub: '955516408249352212',
debateHost: '935508325615931443',
gameNightHost: '952779915701415966',
@ -129,7 +128,6 @@ let IDs = {
},
logs: {
restricted: '920993034462715925',
bot: '872126272015314966',
economy: '932050015034159174',
sus: '872884989950324826',
},