Compare commits

..

No commits in common. "main" and "v3.2.0" have entirely different histories.
main ... v3.2.0

47 changed files with 5154 additions and 9105 deletions

View file

@ -7,7 +7,7 @@
# any secret values. # any secret values.
BOT_TOKEN= BOT_TOKEN=
BOT_VER=3.2.1 BOT_VER=3.2 DEV
BOT_AUTHOR=Vylpes BOT_AUTHOR=Vylpes
BOT_OWNERID=147392775707426816 BOT_OWNERID=147392775707426816
BOT_CLIENTID=682942374040961060 BOT_CLIENTID=682942374040961060
@ -15,8 +15,6 @@ BOT_CLIENTID=682942374040961060
ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
CACHE_INTERVAL=1800000 # 30 minutes
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_PORT=3101 DB_PORT=3101
DB_NAME=vylbot DB_NAME=vylbot

View file

@ -7,7 +7,7 @@ steps:
- name: deploy - name: deploy
image: appleboy/drone-ssh image: appleboy/drone-ssh
settings: settings:
host: 192.168.1.115 host: 192.168.68.120
username: vylpes username: vylpes
password: password:
from_secret: ssh_password from_secret: ssh_password
@ -28,7 +28,7 @@ steps:
- name: stage - name: stage
image: appleboy/drone-ssh image: appleboy/drone-ssh
settings: settings:
host: 192.168.1.115 host: 192.168.68.120
username: vylpes username: vylpes
password: password:
from_secret: ssh_password from_secret: ssh_password

View file

@ -1,67 +0,0 @@
name: Deploy To Production
on:
push:
branches:
- main
jobs:
build:
environment: prod
runs-on: node
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: 18.x
- run: npm ci
- run: npm run build
- run: npm test
- name: "Copy files over to location"
run: cp -r . ${{ secrets.PROD_REPO_PATH }}
deploy:
environment: prod
needs: build
runs-on: node
steps:
- uses: https://github.com/appleboy/ssh-action@v1.0.0
env:
DB_NAME: ${{ secrets.PROD_DB_NAME }}
DB_AUTH_USER: ${{ secrets.PROD_DB_AUTH_USER }}
DB_AUTH_PASS: ${{ secrets.PROD_DB_AUTH_PASS }}
DB_HOST: ${{ secrets.PROD_DB_HOST }}
DB_PORT: ${{ secrets.PROD_DB_PORT }}
DB_ROOT_HOST: ${{ secrets.PROD_DB_ROOT_HOST }}
DB_SYNC: ${{ secrets.PROD_DB_SYNC }}
DB_LOGGING: ${{ secrets.PROD_DB_LOGGING }}
DB_DATA_LOCATION: ${{ secrets.PROD_DB_DATA_LOCATION }}
SERVER_PATH: ${{ secrets.PROD_SSH_SERVER_PATH }}
BOT_TOKEN: ${{ secrets.PROD_BOT_TOKEN }}
BOT_VER: ${{ vars.PROD_BOT_VER }}
BOT_AUTHOR: ${{ vars.PROD_BOT_AUTHOR }}
BOT_OWNERID: ${{ vars.PROD_BOT_OWNERID }}
BOT_CLIENTID: ${{ vars.PROD_BOT_CLIENTID }}
ABOUT_FUNDING: ${{ vars.PROD_ABOUT_FUNDING }}
ABOUT_REPO: ${{ vars.PROD_ABOUT_REPO }}
CACHE_INTERVAL: ${{ vars.PROD_CACHE_INTERVAL }}
with:
host: ${{ secrets.PROD_SSH_HOST }}
username: ${{ secrets.PROD_SSH_USER }}
key: ${{ secrets.PROD_SSH_KEY }}
port: ${{ secrets.PROD_SSH_PORT }}
envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
script: |
source .sshrc \
&& cd /home/vylpes/apps/vylbot/vylbot_prod \
&& docker compose down \
&& (pm2 stop vylbot_prod || true) \
&& (pm2 delete vylbot_prod || true) \
&& docker compose up -d \
&& sleep 10 \
&& npm run db:up \
&& pm2 start --name vylbot_prod dist/vylbot.js

View file

@ -1,67 +0,0 @@
name: Deploy To Stage
on:
push:
branches:
- develop
jobs:
build:
environment: prod
runs-on: node
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: 18.x
- run: npm ci
- run: npm run build
- run: npm test
- name: "Copy files over to location"
run: cp -r . ${{ secrets.STAGE_REPO_PATH }}
deploy:
environment: prod
needs: build
runs-on: node
steps:
- uses: https://github.com/appleboy/ssh-action@v1.0.0
env:
DB_NAME: ${{ secrets.STAGE_DB_NAME }}
DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }}
DB_AUTH_PASS: ${{ secrets.STAGE_DB_AUTH_PASS }}
DB_HOST: ${{ secrets.STAGE_DB_HOST }}
DB_PORT: ${{ secrets.STAGE_DB_PORT }}
DB_ROOT_HOST: ${{ secrets.STAGE_DB_ROOT_HOST }}
DB_SYNC: ${{ secrets.STAGE_DB_SYNC }}
DB_LOGGING: ${{ secrets.STAGE_DB_LOGGING }}
DB_DATA_LOCATION: ${{ secrets.STAGE_DB_DATA_LOCATION }}
SERVER_PATH: ${{ secrets.STAGE_SSH_SERVER_PATH }}
BOT_TOKEN: ${{ secrets.STAGE_BOT_TOKEN }}
BOT_VER: ${{ vars.STAGE_BOT_VER }}
BOT_AUTHOR: ${{ vars.STAGE_BOT_AUTHOR }}
BOT_OWNERID: ${{ vars.STAGE_BOT_OWNERID }}
BOT_CLIENTID: ${{ vars.STAGE_BOT_CLIENTID }}
ABOUT_FUNDING: ${{ vars.STAGE_ABOUT_FUNDING }}
ABOUT_REPO: ${{ vars.STAGE_ABOUT_REPO }}
CACHE_INTERVAL: ${{ vars.STAGE_CACHE_INTERVAL }}
with:
host: ${{ secrets.STAGE_SSH_HOST }}
username: ${{ secrets.STAGE_SSH_USER }}
key: ${{ secrets.STAGE_SSH_KEY }}
port: ${{ secrets.STAGE_SSH_PORT }}
envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
script: |
source .sshrc \
&& cd /home/vylpes/apps/vylbot/vylbot_stage \
&& docker compose down \
&& (pm2 stop vylbot_stage || true) \
&& (pm2 delete vylbot_stage || true) \
&& docker compose up -d \
&& sleep 10 \
&& npm run db:up \
&& pm2 start --name vylbot_stage dist/vylbot.js

View file

@ -1,24 +0,0 @@
name: Test
on:
push:
branches:
- feature/*
- hotfix/*
- renovate/*
jobs:
build:
environment: stage
runs-on: node
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: 18.x
- run: npm ci
- run: npm run build
- run: npm test

24
.prod.env Normal file
View file

@ -0,0 +1,24 @@
# Security Warning! Do not commit this file to any VCS!
# This is a local file to speed up development process,
# so you don't have to change your environment variables.
#
# This is not applied to `.env.template`!
# Template files must be committed to the VCS, but must not contain
# any secret values.
BOT_TOKEN=
BOT_VER=3.2
BOT_AUTHOR=Vylpes
BOT_OWNERID=147392775707426816
BOT_CLIENTID=680083120896081954
ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
DB_HOST=127.0.0.1
DB_PORT=3121
DB_NAME=vylbot
DB_AUTH_USER=prod
DB_AUTH_PASS=prod
DB_SYNC=false
DB_LOGGING=false

24
.stage.env Normal file
View file

@ -0,0 +1,24 @@
# Security Warning! Do not commit this file to any VCS!
# This is a local file to speed up development process,
# so you don't have to change your environment variables.
#
# This is not applied to `.env.template`!
# Template files must be committed to the VCS, but must not contain
# any secret values.
BOT_TOKEN=
BOT_VER=3.2 BETA
BOT_AUTHOR=Vylpes
BOT_OWNERID=147392775707426816
BOT_CLIENTID=1016767908740857949
ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
DB_HOST=127.0.0.1
DB_PORT=3111
DB_NAME=vylbot
DB_AUTH_USER=stage
DB_AUTH_PASS=stage
DB_SYNC=false
DB_LOGGING=false

View file

@ -1,2 +0,0 @@
ALTER TABLE server
ADD LastCached datetime NOT NULL DEFAULT '2024-03-01 18:10:04';

31
docker-compose.prod.yml Normal file
View file

@ -0,0 +1,31 @@
version: "3.9"
volumes:
prod_database_data:
services:
# discord:
# build: .
database:
image: mysql/mysql-server
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
- MYSQL_DATABASE=vylbot
- MYSQL_USER=prod
- MYSQL_PASSWORD=prod
- MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_HOST=0.0.0.0
ports:
- "3121:3306"
volumes:
- prod_database_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- "3122:80"
environment:
- PMA_ARBITRARY=1

31
docker-compose.stage.yml Normal file
View file

@ -0,0 +1,31 @@
version: "3.9"
volumes:
stage_database_data:
services:
# discord:
# build: .
database:
image: mysql/mysql-server
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
- MYSQL_DATABASE=vylbot
- MYSQL_USER=stage
- MYSQL_PASSWORD=stage
- MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_HOST=0.0.0.0
ports:
- "3111:3306"
volumes:
- stage_database_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- "3112:80"
environment:
- PMA_ARBITRARY=1

View file

@ -1,17 +1,31 @@
version: "3.9" version: "3.9"
volumes:
dev_database_data:
services: services:
# discord:
# build: .
database: database:
image: mysql/mysql-server image: mysql/mysql-server
command: --default-authentication-plugin=mysql_native_password command: --default-authentication-plugin=mysql_native_password
restart: always restart: always
environment: environment:
- MYSQL_DATABASE=$DB_NAME - MYSQL_DATABASE=vylbot
- MYSQL_USER=$DB_AUTH_USER - MYSQL_USER=dev
- MYSQL_PASSWORD=$DB_AUTH_PASS - MYSQL_PASSWORD=dev
- MYSQL_ROOT_PASSWORD=$DB_AUTH_PASS - MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_HOST=$DB_ROOT_HOST - MYSQL_ROOT_HOST=0.0.0.0
ports: ports:
- "$DB_PORT:3306" - "3101:3306"
volumes: volumes:
- $DB_DATA_LOCATION:/var/lib/mysql - dev_database_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- "3102:80"
environment:
- PMA_ARBITRARY=1

8815
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{ {
"name": "vylbot-app", "name": "vylbot-app",
"version": "3.2.2", "version": "3.2.0",
"description": "A discord bot made for Vylpes' Den", "description": "A discord bot made for Vylpes' Den",
"main": "./dist/vylbot", "main": "./dist/vylbot",
"typings": "./dist", "typings": "./dist",
@ -11,7 +11,6 @@
"test": "echo true", "test": "echo true",
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
"db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js", "db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js",
"db:create": "typeorm migration:create ./src/database/migrations",
"release": "np --no-publish" "release": "np --no-publish"
}, },
"repository": { "repository": {
@ -37,17 +36,16 @@
"jest-mock-extended": "^3.0.0", "jest-mock-extended": "^3.0.0",
"minimatch": "9.0.3", "minimatch": "9.0.3",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"random-bunny": "^2.1.6", "random-bunny": "^2.0.5",
"ts-jest": "^29.0.0", "ts-jest": "^29.0.0",
"typeorm": "0.3.20" "typeorm": "0.3.17"
}, },
"resolutions": { "resolutions": {
"**/semver": "^7.5.2", "**/semver": "^7.5.2"
"**/undici": "^6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.0.0", "@types/node": "^20.0.0",
"np": "^10.0.0", "np": "^9.0.0",
"typescript": "^5.0.0" "typescript": "^5.0.0"
} }
} }

View file

@ -11,7 +11,6 @@ import { Util } from "./util";
import AppDataSource from "../database/dataSources/appDataSource"; import AppDataSource from "../database/dataSources/appDataSource";
import ButtonEventItem from "../contracts/ButtonEventItem"; import ButtonEventItem from "../contracts/ButtonEventItem";
import { ButtonEvent } from "../type/buttonEvent"; import { ButtonEvent } from "../type/buttonEvent";
import CacheHelper from "../helpers/CacheHelper";
export class CoreClient extends Client { export class CoreClient extends Client {
private static _commandItems: ICommandItem[]; private static _commandItems: ICommandItem[];
@ -60,10 +59,6 @@ export class CoreClient extends Client {
await super.login(process.env.BOT_TOKEN); await super.login(process.env.BOT_TOKEN);
this.guilds.cache.forEach(async (guild) => {
await CacheHelper.UpdateServerCache(guild);
});
this._util.loadEvents(this, CoreClient._eventItems); this._util.loadEvents(this, CoreClient._eventItems);
this._util.loadSlashCommands(this); this._util.loadSlashCommands(this);
} }

View file

@ -6,7 +6,7 @@ export default class AddRole extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('addlobby') .setName('addlobby')
.setDescription('Add lobby channel') .setDescription('Add lobby channel')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -7,7 +7,7 @@ export default class ListLobby extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('listlobby') .setName('listlobby')
.setDescription('Lists all channels set up as lobbies') .setDescription('Lists all channels set up as lobbies')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers); .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers);

View file

@ -6,7 +6,7 @@ export default class Lobby extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('lobby') .setName('lobby')
.setDescription('Attempt to organise a lobby'); .setDescription('Attempt to organise a lobby');
} }

View file

@ -7,7 +7,7 @@ export default class RemoveLobby extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('removelobby') .setName('removelobby')
.setDescription('Remove a lobby channel') .setDescription('Remove a lobby channel')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -7,7 +7,7 @@ export default class Entry extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('entry') .setName('entry')
.setDescription('Sends the entry embed') .setDescription('Sends the entry embed')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers); .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers);

View file

@ -7,7 +7,7 @@ export default class ConfigRole extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('configrole') .setName('configrole')
.setDescription('Toggle your roles') .setDescription('Toggle your roles')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageRoles) .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageRoles)

View file

@ -7,7 +7,7 @@ export default class Role extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('role') .setName('role')
.setDescription('Toggle your roles') .setDescription('Toggle your roles')
.addSubcommand(subcommand => .addSubcommand(subcommand =>

View file

@ -6,7 +6,7 @@ export default class About extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('about') .setName('about')
.setDescription('About VylBot'); .setDescription('About VylBot');
} }

View file

@ -9,7 +9,7 @@ export default class Audits extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("audits") .setName("audits")
.setDescription("View audits of a particular user in the server") .setDescription("View audits of a particular user in the server")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -9,7 +9,7 @@ export default class Ban extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("ban") .setName("ban")
.setDescription("Ban a member from the server with an optional reason") .setDescription("Ban a member from the server with an optional reason")
.setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers)

View file

@ -7,7 +7,7 @@ export default class Bunny extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("bunny") .setName("bunny")
.setDescription("Get a random picture of a rabbit."); .setDescription("Get a random picture of a rabbit.");
} }
@ -15,8 +15,6 @@ export default class Bunny extends Command {
public override async execute(interaction: CommandInteraction) { public override async execute(interaction: CommandInteraction) {
if (!interaction.isChatInputCommand()) return; if (!interaction.isChatInputCommand()) return;
await interaction.deferReply();
const subreddits = [ const subreddits = [
'rabbits', 'rabbits',
'bunnieswithhats', 'bunnieswithhats',
@ -39,9 +37,9 @@ export default class Bunny extends Command {
.setURL(`https://reddit.com${result.Result!.Permalink}`) .setURL(`https://reddit.com${result.Result!.Permalink}`)
.setFooter({ text: `r/${selectedSubreddit} · ${result.Result!.Ups} upvotes`}); .setFooter({ text: `r/${selectedSubreddit} · ${result.Result!.Ups} upvotes`});
await interaction.editReply({ embeds: [ embed ]}); await interaction.reply({ embeds: [ embed ]});
} else { } else {
await interaction.editReply("There was an error running this command."); await interaction.reply("There was an error running this command.");
} }
} }
} }

View file

@ -5,7 +5,7 @@ export default class Clear extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("clear") .setName("clear")
.setDescription("Clears the channel of messages") .setDescription("Clears the channel of messages")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages) .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)

View file

@ -7,7 +7,7 @@ export default class Code extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('code') .setName('code')
.setDescription('Manage the verification code of the server') .setDescription('Manage the verification code of the server')
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -10,7 +10,7 @@ export default class Config extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('config') .setName('config')
.setDescription('Configure the current server') .setDescription('Configure the current server')
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator) .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator)

View file

@ -6,7 +6,7 @@ export default class Disable extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('disable') .setName('disable')
.setDescription('Disables a command') .setDescription('Disables a command')
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator) .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator)

View file

@ -6,7 +6,7 @@ export default class Ignore extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('ignore') .setName('ignore')
.setDescription('Ignore events in this channel') .setDescription('Ignore events in this channel')
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator);

View file

@ -9,7 +9,7 @@ export default class Kick extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("kick") .setName("kick")
.setDescription("Kick a member from the server with an optional reason") .setDescription("Kick a member from the server with an optional reason")
.setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers)

View file

@ -9,7 +9,7 @@ export default class Mute extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("mute") .setName("mute")
.setDescription("(DEPRECATED) Mute a member in the server with an optional reason") .setDescription("(DEPRECATED) Mute a member in the server with an optional reason")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -7,7 +7,7 @@ export default class Poll extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('poll') .setName('poll')
.setDescription('Run a poll, automatically adding reaction emojis as options') .setDescription('Run a poll, automatically adding reaction emojis as options')
.addStringOption(option => .addStringOption(option =>

View file

@ -6,7 +6,7 @@ export default class Setup extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName('setup') .setName('setup')
.setDescription('Makes the server ready to be configured') .setDescription('Makes the server ready to be configured')
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator);

View file

@ -10,7 +10,7 @@ export default class Timeout extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("timeout") .setName("timeout")
.setDescription("Timeouts a user out, sending them a DM with the reason if possible") .setDescription("Timeouts a user out, sending them a DM with the reason if possible")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -7,7 +7,7 @@ export default class Unmute extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("unmute") .setName("unmute")
.setDescription("(DEPRECATED) Unmute a member in the server with an optional reason") .setDescription("(DEPRECATED) Unmute a member in the server with an optional reason")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -9,7 +9,7 @@ export default class Warn extends Command {
constructor() { constructor() {
super(); super();
this.CommandBuilder = new SlashCommandBuilder() super.CommandBuilder = new SlashCommandBuilder()
.setName("warn") .setName("warn")
.setDescription("Warns a member in the server with an optional reason") .setDescription("Warns a member in the server with an optional reason")
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)

View file

@ -1,4 +1,4 @@
import { Column, Entity, OneToMany } from "typeorm"; import { Entity, OneToMany } from "typeorm";
import BaseEntity from "../../contracts/BaseEntity"; import BaseEntity from "../../contracts/BaseEntity";
import Role from "./Role"; import Role from "./Role";
import Setting from "./Setting"; import Setting from "./Setting";
@ -9,22 +9,14 @@ export default class Server extends BaseEntity {
super(); super();
this.Id = serverId; this.Id = serverId;
this.LastCached = new Date();
} }
@Column({ default: "2024-03-01 18:10:04" })
LastCached: Date;
@OneToMany(() => Setting, x => x.Server) @OneToMany(() => Setting, x => x.Server)
Settings: Setting[]; Settings: Setting[];
@OneToMany(() => Role, x => x.Server) @OneToMany(() => Role, x => x.Server)
Roles: Role[]; Roles: Role[];
public UpdateLastCached(lastCached: Date) {
this.LastCached = lastCached;
}
public AddSettingToServer(setting: Setting) { public AddSettingToServer(setting: Setting) {
this.Settings.push(setting); this.Settings.push(setting);
} }

View file

@ -1,15 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm"
import MigrationHelper from "../../../helpers/MigrationHelper"
export class AddServerCacheDate1709316734401 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
MigrationHelper.Up('1709316734401-AddServerCacheDate', '3.2.1', [
"01-Server",
], queryRunner);
}
public async down(queryRunner: QueryRunner): Promise<void> {
}
}

View file

@ -1,13 +1,10 @@
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import CacheHelper from "../../helpers/CacheHelper";
export default async function GuildMemberAdd(member: GuildMember) { export default async function GuildMemberAdd(member: GuildMember) {
if (!member.guild) return; if (!member.guild) return;
await CacheHelper.UpdateServerCache(member.guild);
const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id);
if (!enabled || enabled.toLowerCase() != "true") return; if (!enabled || enabled.toLowerCase() != "true") return;

View file

@ -1,13 +1,10 @@
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import CacheHelper from "../../helpers/CacheHelper";
export default async function GuildMemberRemove(member: GuildMember) { export default async function GuildMemberRemove(member: GuildMember) {
if (!member.guild) return; if (!member.guild) return;
await CacheHelper.UpdateServerCache(member.guild);
const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id);
if (!enabled || enabled.toLowerCase() != "true") return; if (!enabled || enabled.toLowerCase() != "true") return;

View file

@ -1,13 +1,8 @@
import { GuildMember } from "discord.js"; import { GuildMember } from "discord.js";
import NicknameChanged from "./GuildMemberUpdate/NicknameChanged"; import NicknameChanged from "./GuildMemberUpdate/NicknameChanged";
import CacheHelper from "../../helpers/CacheHelper";
export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) { export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) {
const updatedFromCache = await CacheHelper.UpdateServerCache(newMember.guild); if (oldMember.nickname != newMember.nickname) { // Nickname change
if (updatedFromCache) return;
if (oldMember.nickname !== newMember.nickname) { // Nickname change
await NicknameChanged(oldMember, newMember); await NicknameChanged(oldMember, newMember);
} }
} }

View file

@ -1,14 +1,11 @@
import { Message } from "discord.js"; import { Message } from "discord.js";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import VerificationCheck from "./MessageCreate/VerificationCheck"; import VerificationCheck from "./MessageCreate/VerificationCheck";
import CacheHelper from "../../helpers/CacheHelper";
export default async function MessageCreate(message: Message) { export default async function MessageCreate(message: Message) {
if (!message.guild) return; if (!message.guild) return;
if (message.author.bot) return; if (message.author.bot) return;
await CacheHelper.UpdateServerCache(message.guild);
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {

View file

@ -2,14 +2,11 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import IgnoredChannel from "../../database/entities/IgnoredChannel"; import IgnoredChannel from "../../database/entities/IgnoredChannel";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import CacheHelper from "../../helpers/CacheHelper";
export default async function MessageDelete(message: Message) { export default async function MessageDelete(message: Message) {
if (!message.guild) return; if (!message.guild) return;
if (message.author.bot) return; if (message.author.bot) return;
await CacheHelper.UpdateServerCache(message.guild);
const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id);
if (!enabled || enabled.toLowerCase() != "true") return; if (!enabled || enabled.toLowerCase() != "true") return;

View file

@ -2,14 +2,10 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import IgnoredChannel from "../../database/entities/IgnoredChannel"; import IgnoredChannel from "../../database/entities/IgnoredChannel";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import CacheHelper from "../../helpers/CacheHelper";
export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { export default async function MessageUpdate(oldMessage: Message, newMessage: Message) {
if (!newMessage.guild) return; if (!newMessage.guild) return;
if (newMessage.author.bot) return; if (newMessage.author.bot) return;
await CacheHelper.UpdateServerCache(newMessage.guild);
if (oldMessage.content == newMessage.content) return; if (oldMessage.content == newMessage.content) return;
const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id);

View file

@ -1,33 +0,0 @@
import { Guild } from "discord.js";
import Server from "../database/entities/Server";
export default class CacheHelper {
public static async UpdateServerCache(guild: Guild): Promise<boolean> {
const cacheInterval = process.env.CACHE_INTERVAL;
if (!cacheInterval) return false;
let server = await Server.FetchOneById(Server, guild.id);
if (!server) {
server = new Server(guild.id);
await server.Save(Server, server);
await CacheHelper.UpdateCache(guild);
return true;
} else if (server.LastCached.getTime() + Number(cacheInterval) > Date.now()) {
await CacheHelper.UpdateCache(guild);
return true;
}
return false;
}
private static async UpdateCache(guild: Guild) {
console.log(`Updating cache for ${guild.name} (${guild.id})`);
await guild.members.fetch();
}
}

4988
yarn.lock Normal file

File diff suppressed because it is too large Load diff