18 Commits

Author SHA1 Message Date
Joaquín Triñanes
9ebf8a6938 Allow redis to use password auth 2024-10-25 10:58:10 +02:00
Joaquín Triñanes
bc7f2ffcfd Add nixpacks config 2024-10-25 10:30:56 +02:00
Joaquín Triñanes
86f391e131 Enable corepack 2024-10-25 10:23:20 +02:00
Anthony Berg
63c3b14b1c feat(interaction): update info for welcome message 2024-09-03 17:48:28 +02:00
Anthony Berg
a5187ec567 feat(utils): update info for verification message 2024-09-02 22:36:43 +02:00
Anthony Berg
222c3cb81a feat(utils): add non-vegan vc text channel to IDs 2024-09-02 22:36:29 +02:00
Anthony Berg
8f8580398e refactor(arabot): ran prettier 2024-09-02 22:24:24 +02:00
Anthony Berg
fe88e9f87b feat(arabot): add information that you can use apply command for verification 2024-09-02 22:24:12 +02:00
Anthony Berg
4ad35f5b57 fix(arabot): add type safety to deleting text channels 2024-08-26 23:11:30 +02:00
Anthony Berg
1c9f6612a3 build: update deps 2024-08-26 22:43:31 +02:00
Anthony Berg
88dd678bdc feat(arabot): make rules on trusted shorter and clearer 2024-08-11 02:03:30 +01:00
Anthony Berg
9c51be9ab6 feat(arabot): make the information message for trusted more blunt 2024-08-11 01:54:15 +01:00
Anthony Berg
128b15f18f feat(arabot): nerf autotruster to level 7 2024-08-11 01:48:03 +01:00
Anthony Berg
dba9aa970e refactor(arabot): run prettier 2024-08-07 01:39:21 +02:00
Anthony Berg
0ac0ff7f5c feat(arabot): add automatic trusted role at level 5 2024-08-07 01:39:02 +02:00
Anthony Berg
ae0afa02db feat(db): add checking previous warns/restrictions 2024-08-07 01:38:38 +02:00
Anthony Berg
3009a0f923 feat(arabot): add emitter when user levels up 2024-08-07 01:38:16 +02:00
Anthony Berg
a09b007831 refactor(db): move db functions to separate folders to aid distinguishing functions 2024-08-07 00:48:40 +02:00
56 changed files with 380 additions and 145 deletions

View File

@@ -3,15 +3,18 @@ DISCORD_TOKEN= # Bot token from: https://discord.com/developers/
# Configuration
DEFAULT_PREFIX= # Prefix used to run commands in Discord
DEVELOPMENT= # (true/false) Enables developer mode
DEVELOPMENT= # (true/false) Enables developer mode
# Docker
POSTGRES_USER=USERNAME
POSTGRES_PASSWORD=PASSWORD
POSTGRES_DB=DB
# Redis
REDIS_URL= # URL to redis database (if running everything within docker compose, use "redis")
# 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
# Database URL (designed for Postgres, but designed on Prisma)
DATABASE_URL= # "postgresql://USERNAME:PASSWORD@postgres:5432/DB?schema=ara&sslmode=prefer"

5
nixpacks.toml Normal file
View File

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

View File

@@ -33,9 +33,8 @@
"node": ">=20",
"pnpm": ">=9"
},
"packageManager": "pnpm@9.6.0",
"dependencies": {
"@prisma/client": "^5.17.0",
"@prisma/client": "^5.18.0",
"@sapphire/discord.js-utilities": "^7.3.0",
"@sapphire/framework": "^5.2.1",
"@sapphire/plugin-logger": "^4.0.2",
@@ -45,19 +44,20 @@
"@sapphire/time-utilities": "^1.7.12",
"@sapphire/ts-config": "^5.0.1",
"@sapphire/utilities": "^3.17.0",
"bullmq": "^5.12.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.14.14",
"@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.17.0"
}
"prisma": "^5.18.0"
},
"packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228"
}

170
pnpm-lock.yaml generated
View File

@@ -9,8 +9,8 @@ importers:
.:
dependencies:
'@prisma/client':
specifier: ^5.17.0
version: 5.17.0(prisma@5.17.0)
specifier: ^5.18.0
version: 5.18.0(prisma@5.18.0)
'@sapphire/discord.js-utilities':
specifier: ^7.3.0
version: 7.3.0
@@ -39,8 +39,8 @@ importers:
specifier: ^3.17.0
version: 3.17.0
bullmq:
specifier: ^5.12.0
version: 5.12.0
specifier: ^5.12.10
version: 5.12.10
discord.js:
specifier: ^14.15.3
version: 14.15.3
@@ -49,14 +49,14 @@ importers:
version: 5.4.1
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@20.14.14)(typescript@5.4.5)
version: 10.9.2(@types/node@20.16.1)(typescript@5.4.5)
typescript:
specifier: ~5.4.5
version: 5.4.5
devDependencies:
'@types/node':
specifier: ^20.14.14
version: 20.14.14
specifier: ^20.16.1
version: 20.16.1
'@typescript-eslint/eslint-plugin':
specifier: ^6.21.0
version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint@8.56.0)(typescript@5.4.5)
@@ -73,8 +73,8 @@ importers:
specifier: 3.2.4
version: 3.2.4
prisma:
specifier: ^5.17.0
version: 5.17.0
specifier: ^5.18.0
version: 5.18.0
packages:
@@ -196,8 +196,8 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@prisma/client@5.17.0':
resolution: {integrity: sha512-N2tnyKayT0Zf7mHjwEyE8iG7FwTmXDHFZ1GnNhQp0pJUObsuel4ZZ1XwfuAYkq5mRIiC/Kot0kt0tGCfLJ70Jw==}
'@prisma/client@5.18.0':
resolution: {integrity: sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==}
engines: {node: '>=16.13'}
peerDependencies:
prisma: '*'
@@ -205,20 +205,20 @@ packages:
prisma:
optional: true
'@prisma/debug@5.17.0':
resolution: {integrity: sha512-l7+AteR3P8FXiYyo496zkuoiJ5r9jLQEdUuxIxNCN1ud8rdbH3GTxm+f+dCyaSv9l9WY+29L9czaVRXz9mULfg==}
'@prisma/debug@5.18.0':
resolution: {integrity: sha512-f+ZvpTLidSo3LMJxQPVgAxdAjzv5OpzAo/eF8qZqbwvgi2F5cTOI9XCpdRzJYA0iGfajjwjOKKrVq64vkxEfUw==}
'@prisma/engines-version@5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053':
resolution: {integrity: sha512-tUuxZZysZDcrk5oaNOdrBnnkoTtmNQPkzINFDjz7eG6vcs9AVDmA/F6K5Plsb2aQc/l5M2EnFqn3htng9FA4hg==}
'@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169':
resolution: {integrity: sha512-a/+LpJj8vYU3nmtkg+N3X51ddbt35yYrRe8wqHTJtYQt7l1f8kjIBcCs6sHJvodW/EK5XGvboOiwm47fmNrbgg==}
'@prisma/engines@5.17.0':
resolution: {integrity: sha512-+r+Nf+JP210Jur+/X8SIPLtz+uW9YA4QO5IXA+KcSOBe/shT47bCcRMTYCbOESw3FFYFTwe7vU6KTWHKPiwvtg==}
'@prisma/engines@5.18.0':
resolution: {integrity: sha512-ofmpGLeJ2q2P0wa/XaEgTnX/IsLnvSp/gZts0zjgLNdBhfuj2lowOOPmDcfKljLQUXMvAek3lw5T01kHmCG8rg==}
'@prisma/fetch-engine@5.17.0':
resolution: {integrity: sha512-ESxiOaHuC488ilLPnrv/tM2KrPhQB5TRris/IeIV4ZvUuKeaicCl4Xj/JCQeG9IlxqOgf1cCg5h5vAzlewN91Q==}
'@prisma/fetch-engine@5.18.0':
resolution: {integrity: sha512-I/3u0x2n31rGaAuBRx2YK4eB7R/1zCuayo2DGwSpGyrJWsZesrV7QVw7ND0/Suxeo/vLkJ5OwuBqHoCxvTHpOg==}
'@prisma/get-platform@5.17.0':
resolution: {integrity: sha512-UlDgbRozCP1rfJ5Tlkf3Cnftb6srGrEQ4Nm3og+1Se2gWmCZ0hmPIi+tQikGDUVLlvOWx3Gyi9LzgRP+HTXV9w==}
'@prisma/get-platform@5.18.0':
resolution: {integrity: sha512-Tk+m7+uhqcKDgnMnFN0lRiH7Ewea0OEsZZs9pqXa7i3+7svS3FSCqDBCaM9x5fmhhkufiG0BtunJVDka+46DlA==}
'@sapphire/async-queue@1.5.3':
resolution: {integrity: sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==}
@@ -319,8 +319,8 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node@20.14.14':
resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==}
'@types/node@20.16.1':
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
'@types/semver@7.5.8':
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
@@ -389,8 +389,8 @@ packages:
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
'@vladfrangu/async_event_emitter@2.4.5':
resolution: {integrity: sha512-J7T3gUr3Wz0l7Ni1f9upgBZ7+J22/Q1B7dl0X6fG+fTsD+H+31DIosMHj4Um1dWQwqbcQ3oQf+YS2foYkDc9cQ==}
'@vladfrangu/async_event_emitter@2.4.6':
resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==}
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
acorn-jsx@5.3.2:
@@ -444,8 +444,8 @@ packages:
bullmq@5.1.3:
resolution: {integrity: sha512-safpGwiwKHsNPW01Wk8FPxdWbPS2mA0HZKqIhdQB10J4wWRSDWPeQE2p+YYnAmqEsk0FwJdZnzVcwCfn7w5cVA==}
bullmq@5.12.0:
resolution: {integrity: sha512-kOtSQx9ymylslsLNFD0xOMJM9mHqnq3x6KD7+DYkHByWe0HFRdblpYKhZyL4uR3rwaKZwzOrJVl3RwRaDjZxSg==}
bullmq@5.12.10:
resolution: {integrity: sha512-lXH8Caj+FvYHiBS0QBEpQOq57RcVuEPziBC5cBlWguCVNfn1UMSri22bRrynDKuof8o9XB43ctmYASUpoa0DeQ==}
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
@@ -514,8 +514,8 @@ packages:
discord-api-types@0.37.83:
resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==}
discord-api-types@0.37.93:
resolution: {integrity: sha512-M5jn0x3bcXk8EI2c6F6V6LeOWq10B/cJf+YJSyqNmg7z4bdXK+Z7g9zGJwHS0h9Bfgs0nun2LQISFOzwck7G9A==}
discord-api-types@0.37.98:
resolution: {integrity: sha512-xsH4UwmnCQl4KjAf01/p9ck9s+/vDqzHbUxPOBzo8fcVUa/hQG6qInD7Cr44KAuCM+xCxGJFSAUx450pBrX0+g==}
discord.js@14.15.3:
resolution: {integrity: sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==}
@@ -638,8 +638,8 @@ packages:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
ignore@5.3.1:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
import-fresh@3.3.0:
@@ -733,8 +733,8 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
micromatch@4.0.7:
resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
minimatch@3.1.2:
@@ -816,8 +816,8 @@ packages:
engines: {node: '>=14'}
hasBin: true
prisma@5.17.0:
resolution: {integrity: sha512-m4UWkN5lBE6yevqeOxEvmepnL5cNPEjzMw2IqDB59AcEV6w7D8vGljDLd1gPFH+W6gUxw9x7/RmN5dCS/WTPxA==}
prisma@5.18.0:
resolution: {integrity: sha512-+TrSIxZsh64OPOmaSgVPH7ALL9dfU0jceYaMJXsNrTkFHO7/3RANi5K2ZiPB1De9+KDxCWn7jvRq8y8pvk+o9g==}
engines: {node: '>=16.13'}
hasBin: true
@@ -917,8 +917,8 @@ packages:
tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
tslib@2.6.3:
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
tslib@2.7.0:
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
@@ -933,8 +933,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
undici@6.13.0:
resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==}
@@ -996,7 +996,7 @@ snapshots:
discord-api-types: 0.37.83
fast-deep-equal: 3.1.3
ts-mixer: 6.0.4
tslib: 2.6.3
tslib: 2.7.0
'@discordjs/collection@1.5.3': {}
@@ -1012,7 +1012,7 @@ snapshots:
'@discordjs/util': 1.1.0
'@sapphire/async-queue': 1.5.3
'@sapphire/snowflake': 3.5.3
'@vladfrangu/async_event_emitter': 2.4.5
'@vladfrangu/async_event_emitter': 2.4.6
discord-api-types: 0.37.83
magic-bytes.js: 1.10.0
tslib: 2.6.2
@@ -1027,7 +1027,7 @@ snapshots:
'@discordjs/util': 1.1.0
'@sapphire/async-queue': 1.5.3
'@types/ws': 8.5.12
'@vladfrangu/async_event_emitter': 2.4.5
'@vladfrangu/async_event_emitter': 2.4.6
discord-api-types: 0.37.83
tslib: 2.6.2
ws: 8.18.0
@@ -1048,7 +1048,7 @@ snapshots:
debug: 4.3.6
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
ignore: 5.3.2
import-fresh: 3.3.0
js-yaml: 4.1.0
minimatch: 3.1.2
@@ -1111,30 +1111,30 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@prisma/client@5.17.0(prisma@5.17.0)':
'@prisma/client@5.18.0(prisma@5.18.0)':
optionalDependencies:
prisma: 5.17.0
prisma: 5.18.0
'@prisma/debug@5.17.0': {}
'@prisma/debug@5.18.0': {}
'@prisma/engines-version@5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053': {}
'@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169': {}
'@prisma/engines@5.17.0':
'@prisma/engines@5.18.0':
dependencies:
'@prisma/debug': 5.17.0
'@prisma/engines-version': 5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053
'@prisma/fetch-engine': 5.17.0
'@prisma/get-platform': 5.17.0
'@prisma/debug': 5.18.0
'@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169
'@prisma/fetch-engine': 5.18.0
'@prisma/get-platform': 5.18.0
'@prisma/fetch-engine@5.17.0':
'@prisma/fetch-engine@5.18.0':
dependencies:
'@prisma/debug': 5.17.0
'@prisma/engines-version': 5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053
'@prisma/get-platform': 5.17.0
'@prisma/debug': 5.18.0
'@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169
'@prisma/get-platform': 5.18.0
'@prisma/get-platform@5.17.0':
'@prisma/get-platform@5.18.0':
dependencies:
'@prisma/debug': 5.17.0
'@prisma/debug': 5.18.0
'@sapphire/async-queue@1.5.3': {}
@@ -1144,14 +1144,14 @@ snapshots:
'@sapphire/discord-utilities@3.3.0':
dependencies:
discord-api-types: 0.37.93
discord-api-types: 0.37.98
'@sapphire/discord.js-utilities@7.3.0':
dependencies:
'@sapphire/discord-utilities': 3.3.0
'@sapphire/duration': 1.1.2
'@sapphire/utilities': 3.17.0
tslib: 2.6.3
tslib: 2.7.0
'@sapphire/duration@1.1.2': {}
@@ -1175,7 +1175,7 @@ snapshots:
dependencies:
'@discordjs/collection': 1.5.3
'@sapphire/utilities': 3.17.0
tslib: 2.6.3
tslib: 2.7.0
'@sapphire/plugin-logger@4.0.2':
dependencies:
@@ -1187,14 +1187,14 @@ snapshots:
'@sapphire/stopwatch': 1.5.2
'@sapphire/utilities': 3.17.0
bullmq: 5.1.3
tslib: 2.6.3
tslib: 2.7.0
transitivePeerDependencies:
- supports-color
'@sapphire/plugin-subcommands@6.0.3':
dependencies:
'@sapphire/utilities': 3.17.0
tslib: 2.6.3
tslib: 2.7.0
'@sapphire/ratelimits@2.4.9': {}
@@ -1209,7 +1209,7 @@ snapshots:
'@sapphire/stopwatch@1.5.2':
dependencies:
tslib: 2.6.3
tslib: 2.7.0
'@sapphire/time-utilities@1.7.12':
dependencies:
@@ -1224,7 +1224,7 @@ snapshots:
'@sapphire/ts-config@5.0.1':
dependencies:
tslib: 2.6.3
tslib: 2.7.0
typescript: 5.4.5
'@sapphire/utilities@3.17.0': {}
@@ -1239,15 +1239,15 @@ snapshots:
'@types/json-schema@7.0.15': {}
'@types/node@20.14.14':
'@types/node@20.16.1':
dependencies:
undici-types: 5.26.5
undici-types: 6.19.8
'@types/semver@7.5.8': {}
'@types/ws@8.5.12':
dependencies:
'@types/node': 20.14.14
'@types/node': 20.16.1
'@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint@8.56.0)(typescript@5.4.5)':
dependencies:
@@ -1260,7 +1260,7 @@ snapshots:
debug: 4.3.6
eslint: 8.56.0
graphemer: 1.4.0
ignore: 5.3.1
ignore: 5.3.2
natural-compare: 1.4.0
semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.4.5)
@@ -1337,7 +1337,7 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
'@vladfrangu/async_event_emitter@2.4.5': {}
'@vladfrangu/async_event_emitter@2.4.6': {}
acorn-jsx@5.3.2(acorn@8.12.1):
dependencies:
@@ -1392,19 +1392,19 @@ snapshots:
msgpackr: 1.11.0
node-abort-controller: 3.1.1
semver: 7.6.3
tslib: 2.6.3
tslib: 2.7.0
uuid: 9.0.1
transitivePeerDependencies:
- supports-color
bullmq@5.12.0:
bullmq@5.12.10:
dependencies:
cron-parser: 4.9.0
ioredis: 5.4.1
msgpackr: 1.11.0
node-abort-controller: 3.1.1
semver: 7.6.3
tslib: 2.6.3
tslib: 2.7.0
uuid: 9.0.1
transitivePeerDependencies:
- supports-color
@@ -1459,7 +1459,7 @@ snapshots:
discord-api-types@0.37.83: {}
discord-api-types@0.37.93: {}
discord-api-types@0.37.98: {}
discord.js@14.15.3:
dependencies:
@@ -1523,7 +1523,7 @@ snapshots:
glob-parent: 6.0.2
globals: 13.24.0
graphemer: 1.4.0
ignore: 5.3.1
ignore: 5.3.2
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
@@ -1565,7 +1565,7 @@ snapshots:
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.7
micromatch: 4.0.8
fast-json-stable-stringify@2.1.0: {}
@@ -1632,7 +1632,7 @@ snapshots:
array-union: 2.1.0
dir-glob: 3.0.1
fast-glob: 3.3.2
ignore: 5.3.1
ignore: 5.3.2
merge2: 1.4.1
slash: 3.0.0
@@ -1640,7 +1640,7 @@ snapshots:
has-flag@4.0.0: {}
ignore@5.3.1: {}
ignore@5.3.2: {}
import-fresh@3.3.0:
dependencies:
@@ -1723,7 +1723,7 @@ snapshots:
merge2@1.4.1: {}
micromatch@4.0.7:
micromatch@4.0.8:
dependencies:
braces: 3.0.3
picomatch: 2.3.1
@@ -1806,9 +1806,9 @@ snapshots:
prettier@3.2.4: {}
prisma@5.17.0:
prisma@5.18.0:
dependencies:
'@prisma/engines': 5.17.0
'@prisma/engines': 5.18.0
punycode@2.3.1: {}
@@ -1866,14 +1866,14 @@ snapshots:
ts-mixer@6.0.4: {}
ts-node@10.9.2(@types/node@20.14.14)(typescript@5.4.5):
ts-node@10.9.2(@types/node@20.16.1)(typescript@5.4.5):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 20.14.14
'@types/node': 20.16.1
acorn: 8.12.1
acorn-walk: 8.3.3
arg: 4.1.3
@@ -1886,7 +1886,7 @@ snapshots:
tslib@2.6.2: {}
tslib@2.6.3: {}
tslib@2.7.0: {}
type-check@0.4.0:
dependencies:
@@ -1896,7 +1896,7 @@ snapshots:
typescript@5.4.5: {}
undici-types@5.26.5: {}
undici-types@6.19.8: {}
undici@6.13.0: {}

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import type { User, Guild, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { getBalance } from '#utils/database/economy';
import { getBalance } from '#utils/database/fun/economy';
import { EmbedBuilder } from 'discord.js';
export class BalanceCommand extends Command {

View File

@@ -21,7 +21,7 @@ import { Command, RegisterBehavior } from '@sapphire/framework';
import { Time } from '@sapphire/time-utilities';
import type { User, Guild, GuildMember, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { daily, getLastDaily } from '#utils/database/economy';
import { daily, getLastDaily } from '#utils/database/fun/economy';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';

View File

@@ -20,7 +20,7 @@
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import type { User, Guild, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { getBalance, transfer } from '#utils/database/economy';
import { getBalance, transfer } from '#utils/database/fun/economy';
import { EmbedBuilder, TextChannel } from 'discord.js';
import IDs from '#utils/ids';

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { N1984 } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
export class N1984Command extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Cringe } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
export class CringeCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Hugs } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
export class HugCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Kill } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
export class KillCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -20,7 +20,7 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Poke } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
export class PokeCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -21,9 +21,12 @@ import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import type { User, Message, Snowflake, TextChannel, Guild } from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
import { addBan, checkBan } from '#utils/database/ban';
import { addBan, checkBan } from '#utils/database/moderation/ban';
import { addEmptyUser, updateUser } from '#utils/database/dbExistingUser';
import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
import {
checkTempBan,
removeTempBan,
} from '#utils/database/moderation/tempBan';
export class BanCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -22,7 +22,7 @@ import { Duration, DurationFormatter } from '@sapphire/time-utilities';
import type { User, Snowflake, TextChannel, Guild } from 'discord.js';
import { EmbedBuilder, Message } from 'discord.js';
import IDs from '#utils/ids';
import { addTempBan, checkTempBan } from '#utils/database/tempBan';
import { addTempBan, checkTempBan } from '#utils/database/moderation/tempBan';
import { addEmptyUser, updateUser } from '#utils/database/dbExistingUser';
export class TempBanCommand extends Command {

View File

@@ -28,8 +28,11 @@ import type {
} from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
import { removeBan, checkBan, addBan } from '#utils/database/ban';
import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
import { removeBan, checkBan, addBan } from '#utils/database/moderation/ban';
import {
checkTempBan,
removeTempBan,
} from '#utils/database/moderation/tempBan';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
export class UnbanCommand extends Command {

View File

@@ -36,7 +36,7 @@ import {
updateUser,
fetchRoles,
} from '#utils/database/dbExistingUser';
import { restrict, checkActive } from '#utils/database/restriction';
import { restrict, checkActive } from '#utils/database/moderation/restriction';
import { randint } from '#utils/maths';
import { blockedRolesAfterRestricted } from '#utils/blockedRoles';

View File

@@ -21,7 +21,7 @@ import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { ChannelType, EmbedBuilder } from 'discord.js';
import type { Message, TextChannel, Guild, Snowflake } from 'discord.js';
import IDs from '#utils/ids';
import { getRestrictions } from '#utils/database/restriction';
import { getRestrictions } from '#utils/database/moderation/restriction';
import { checkStaff } from '#utils/checker';
export class RestrictLogsCommand extends Command {

View File

@@ -26,7 +26,7 @@ import {
unRestrict,
checkActive,
unRestrictLegacy,
} from '#utils/database/restriction';
} from '#utils/database/moderation/restriction';
export class UnRestrictCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -39,7 +39,7 @@ import {
getNote,
deactivateNote,
deactivateAllNotes,
} from '#utils/database/sus';
} from '#utils/database/moderation/sus';
import { checkStaff } from '#utils/checker';
import IDs from '#utils/ids';
import { createSusLogEmbed } from '#utils/embeds';

View File

@@ -19,7 +19,11 @@
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import type { GuildMember, Message } from 'discord.js';
import { addMute, removeMute, checkActive } from '#utils/database/vcMute';
import {
addMute,
removeMute,
checkActive,
} from '#utils/database/moderation/vcMute';
import { addExistingUser } from '#utils/database/dbExistingUser';
export class VCMuteCommand extends Command {

View File

@@ -21,7 +21,10 @@ 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 {
deleteWarning,
fetchWarning,
} from '#utils/database/moderation/warnings';
import { checkStaff } from '#utils/checker';
export class DeleteWarningCommand extends Command {

View File

@@ -25,7 +25,7 @@ import {
} 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 { addWarn } from '#utils/database/moderation/warnings';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';

View File

@@ -21,7 +21,7 @@ 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 { fetchWarnings } from '#utils/database/moderation/warnings';
import { checkStaff } from '#utils/checker';
import { createWarningsEmbed } from '#utils/embeds';

View File

@@ -146,8 +146,8 @@ export class TrustedCommand extends Command {
.send(
`You have been given the ${trusted.name} role by ${mod}!` +
'\n\nThis role allows you to post attachments to the server and stream in VCs.' +
"\nMake sure that you follow the rules, and don't post anything NSFW, anything objectifying animals and follow Discord's ToS." +
`\nNot following these rules can result in the removal of the ${trusted.name} role.`,
'\nMake sure that you follow the rules, especially by **not** posting anything **NSFW**, and **no animal products or consumption of animal products**.' +
`\n\nNot following these rules will result in the **immediate removal** of the ${trusted.name} role.`,
)
.catch(() => {});
info.success = true;

View File

@@ -18,6 +18,7 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import IDs from '#utils/ids';
export class InfoCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@@ -94,7 +95,9 @@ export class InfoCommand extends Command {
message =
"If you want to have the vegan or activist role, you'll need to do a voice verification. " +
"To do this, hop into the 'Verification' voice channel." +
"\n\nIf there aren't any verifiers available, you'll be disconnected, and you can rejoin later.";
"\n\nIf there aren't any verifiers available, you'll be disconnected, and you can rejoin later." +
`\n\nAlternatively if you would like text verification, you can use \`/apply\` in <#${IDs.channels.nonVegan.vcText}> ` +
'to be able fill out a Vegan Verification form through the Appy Bot.';
break;
case 'modMail':
message =

View File

@@ -20,7 +20,7 @@
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import type { User, Guild, Message } from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import { getRank, xpToNextLevel } from '#utils/database/xp';
import { getRank, xpToNextLevel } from '#utils/database/fun/xp';
export class RankCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {

View File

@@ -27,6 +27,10 @@ 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,
@@ -49,7 +53,10 @@ const client = new SapphireClient({
tasks: {
bull: {
connection: {
host: process.env.REDIS_URL,
host: process.env.REDIS_HOST,
username: process.env.REDIS_USER,
password: process.env.REDIS_PASSWORD,
port: REDIS_PORT,
},
},
},
@@ -62,9 +69,12 @@ const main = async () => {
client.logger.info('Logging in');
// Create databases
container.database = await new PrismaClient();
container.database = new PrismaClient();
container.redis = new Redis({
host: process.env.REDIS_URL,
host: process.env.REDIS_HOST,
username: process.env.REDIS_USER,
password: process.env.REDIS_PASSWORD,
port: REDIS_PORT,
db: 1,
});

View File

@@ -69,7 +69,8 @@ export class WelcomeButtonHandler extends InteractionHandler {
await general.send(
`${member} Welcome to ARA! :D Please check <#${IDs.channels.information.roles}> ` +
`and remember to follow the <#${IDs.channels.information.conduct}> and to respect ongoing discussions and debates.` +
"\n\nIf you are vegan, you can join the 'Verification' voice channel to be verified and gain access to more channels.",
`\n\nIf you are vegan, you can join the 'Verification' voice channel, or use \`/apply\` with the Appy bot in <#${IDs.channels.nonVegan.vcText}>, ` +
'to be verified and gain access to more channels.',
);
return;
}

View File

@@ -20,7 +20,7 @@
import { Listener } from '@sapphire/framework';
import type { GuildBan } from 'discord.js';
import { AuditLogEvent, EmbedBuilder, TextChannel } from 'discord.js';
import { addBan, checkBan } from '#utils/database/ban';
import { addBan, checkBan } from '#utils/database/moderation/ban';
import IDs from '#utils/ids';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';

View File

@@ -19,8 +19,8 @@
import { Listener } from '@sapphire/framework';
import type { GuildMember } from 'discord.js';
import { checkBan, getBanReason } from '#utils/database/ban';
import { checkTempBan } from '#utils/database/tempBan';
import { checkBan, getBanReason } from '#utils/database/moderation/ban';
import { checkTempBan } from '#utils/database/moderation/tempBan';
export class BanJoinListener extends Listener {
public constructor(

View File

@@ -20,7 +20,7 @@
import { Listener } from '@sapphire/framework';
import type { GuildBan } from 'discord.js';
import { AuditLogEvent, EmbedBuilder, TextChannel } from 'discord.js';
import { addBan, checkBan, removeBan } from '#utils/database/ban';
import { addBan, checkBan, removeBan } from '#utils/database/moderation/ban';
import IDs from '#utils/ids';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';

View File

@@ -21,7 +21,7 @@
import { Listener } from '@sapphire/framework';
import type { Message } from 'discord.js';
import { getLastCount, addCount } from '#utils/database/counting';
import { getLastCount, addCount } from '#utils/database/fun/counting';
import IDs from '#utils/ids';
export class XpListener extends Listener {

View File

@@ -22,14 +22,17 @@ 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 {
checkActive,
getRestrictions,
} from '#utils/database/moderation/restriction';
import { findNotes } from '#utils/database/moderation/sus';
import {
createRestrictLogEmbed,
createSusLogEmbed,
createWarningsEmbed,
} from '#utils/embeds';
import { fetchWarnings } from '#utils/database/warnings';
import { fetchWarnings } from '#utils/database/moderation/warnings';
export class ModMailCreateListener extends Listener {
public constructor(

View File

@@ -28,7 +28,10 @@ import type {
import { ChannelType } from 'discord.js';
import { fetchRoles, getLeaveRoles } from '#utils/database/dbExistingUser';
import { blockTime } from '#utils/database/verification';
import { checkActive, getSection } from '#utils/database/restriction';
import {
checkActive,
getSection,
} from '#utils/database/moderation/restriction';
import { blockedRoles, blockedRolesAfterRestricted } from '#utils/blockedRoles';
import IDs from '#utils/ids';

View File

@@ -19,7 +19,7 @@
import { Listener } from '@sapphire/framework';
import type { VoiceState } from 'discord.js';
import { checkActive, removeMute } from '#utils/database/vcMute';
import { checkActive, removeMute } from '#utils/database/moderation/vcMute';
export class VCMuteListener extends Listener {
public constructor(

View File

@@ -50,7 +50,7 @@ import {
startVerification,
finishVerification,
} from '#utils/database/verification';
import { findNotes } from '#utils/database/sus';
import { findNotes } from '#utils/database/moderation/sus';
import { addExistingUser } from '#utils/database/dbExistingUser';
import { rolesToString } from '#utils/formatter';
import IDs from '#utils/ids';

View File

@@ -148,7 +148,10 @@ export class VerificationLeaveVCListener extends Listener {
listTextChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (textChannel.topic!.includes(userSnowflake!)) {
if (
textChannel.topic !== null &&
textChannel.topic.includes(userSnowflake!)
) {
textChannel.delete();
}
});

View File

@@ -80,7 +80,10 @@ export class VerificationReady extends Listener {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
emptyVC.forEach((snowflake) => {
if (textChannel.topic!.includes(snowflake)) {
if (
textChannel.topic !== null &&
textChannel.topic.includes(snowflake)
) {
textChannel.delete();
}
});

View File

@@ -0,0 +1,88 @@
// 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 } from '@sapphire/framework';
import { GuildMember } from 'discord.js';
import IDs from '#utils/ids';
import { noModHistory, userPreviouslyHadRole } from '#utils/database/memberMod';
/**
* Gives the trusted role to users who have levelled up to level 5
* and has not gotten any other warnings/restrictions prior.
*/
export class TrustedListener extends Listener {
public constructor(
context: Listener.LoaderContext,
options: Listener.Options,
) {
super(context, {
...options,
event: 'xpLevelUp',
});
}
public async run(member: GuildMember, level: number) {
// Checks if the member has gotten level 7
// Has been nefred. Should take around 1.5 hours to get the trusted role now
if (level !== 7) {
return;
}
// Checks if the user has been previously moderated
const noModerationHistory = await noModHistory(member.id);
if (!noModerationHistory) {
return;
}
const { guild } = member;
const trusted = guild.roles.cache.get(IDs.roles.trusted);
if (trusted === undefined) {
this.container.logger.error(
'TrustedXP Listener: the Trusted role could not be found in the guild.',
);
return;
}
// Checks if the member has previously had the trusted role given/removed
const previouslyHadRole = await userPreviouslyHadRole(
member.id,
trusted.id,
);
if (previouslyHadRole) {
return;
}
// Checks if the user already has the trusted role
if (member.roles.cache.has(trusted.id)) {
return;
}
// Gives the trusted role to the member
await member.roles.add(trusted);
// Send a DM to inform the member that they have been given the trusted role
await member.user.send(
`Hi, you have been given the ${trusted.name} as you have been interacting in ARA for a long enough time!` +
'\n\nThis role allows you to post attachments to the server and stream in VCs.' +
'\nMake sure that you follow the rules, especially by **not** posting anything **NSFW**, and **no animal products or consumption of animal products**.' +
`\n\nNot following these rules will result in the **immediate removal** of the ${trusted.name} role.`,
);
}
}

View File

@@ -19,7 +19,7 @@
import { Listener } from '@sapphire/framework';
import type { Message } from 'discord.js';
import { addXp, checkCanAddXp } from '#utils/database/xp';
import { addXp, checkCanAddXp } from '#utils/database/fun/xp';
import { randint } from '#utils/maths';
export class XpListener extends Listener {
@@ -46,6 +46,12 @@ export class XpListener extends Listener {
const xp = randint(15, 25);
await addXp(user.id, xp);
const level = await addXp(user.id, xp);
// Emits that a user has leveled up
if (level !== null) {
this.container.logger.info('User is levelling up!');
this.container.client.emit('xpLevelUp', message.member, level);
}
}
}

View File

@@ -52,7 +52,9 @@ export class VerifyReminder extends ScheduledTask {
await channel.send(
"If you want to have the vegan or activist role, you'll need to do a voice verification. " +
"To do this, hop into the 'Verification' voice channel." +
"\n\nIf there aren't any verifiers available, you'll be disconnected, and you can rejoin later.",
"\n\nIf there aren't any verifiers available, you'll be disconnected, and you can rejoin later." +
`\nAlternatively if you would like text verification, you can use \`/apply\` in <#${IDs.channels.nonVegan.vcText}> ` +
'to be able fill out a Vegan Verification form through the Appy Bot.',
);
// Reset the total message counter to 0

View File

@@ -20,8 +20,11 @@
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import IDs from '#utils/ids';
import { EmbedBuilder } from 'discord.js';
import { checkBan } from '#utils/database/ban';
import { checkTempBan, removeTempBan } from '#utils/database/tempBan';
import { checkBan } from '#utils/database/moderation/ban';
import {
checkTempBan,
removeTempBan,
} from '#utils/database/moderation/tempBan';
export class TempBan extends ScheduledTask {
public constructor(

View File

@@ -36,7 +36,7 @@ export async function addXp(userId: Snowflake, xp: number) {
}
}
await container.database.xp.upsert({
const info = await container.database.xp.upsert({
where: {
userId,
},
@@ -63,6 +63,12 @@ export async function addXp(userId: Snowflake, xp: number) {
xpForNextLevel: xp,
},
});
if (level === 1) {
return info.level;
} else {
return null;
}
}
export async function checkCanAddXp(userId: Snowflake) {

View File

@@ -0,0 +1,55 @@
// 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 { Snowflake } from 'discord.js';
import { countWarnings } from '#utils/database/moderation/warnings';
import { countRestrictions } from '#utils/database/moderation/restriction';
import { container } from '@sapphire/framework';
/**
* Checks if the user has
* @param userId Discord Snowflake of the user to check
* @return Boolean true if no prior moderation action
*/
export async function noModHistory(userId: Snowflake) {
const warnCount = await countWarnings(userId);
const restrictCount = await countRestrictions(userId);
return warnCount === 0 && restrictCount === 0;
}
/**
* Checks if the user has previously had a role given or taken away by a moderator.
* @param userId Discord Snowflake of the user to check
* @param roleId Snowflake of the role being checked for the user
* @return Boolean true if the user has had a moderator give/remove the specified role
*/
export async function userPreviouslyHadRole(
userId: Snowflake,
roleId: Snowflake,
) {
const count = await container.database.roleLog.count({
where: {
userId,
roleId,
},
});
return count !== 0;
}

View File

@@ -114,6 +114,19 @@ export async function getSection(userId: Snowflake) {
return restriction.section;
}
/**
* Returns the amount of restrictions a user has.
* @param userId Discord Snowflake of the user to check
* @return number The amount of restrictions the user has
*/
export async function countRestrictions(userId: Snowflake) {
return container.database.restrict.count({
where: {
userId,
},
});
}
// This is only for restrictions created with the old bot
export async function unRestrictLegacy(
userId: Snowflake,

View File

@@ -61,3 +61,16 @@ export async function deleteWarning(warningId: number) {
},
});
}
/**
* Returns the amount of warnings a user has.
* @param userId Discord Snowflake of the user to check
* @return number The amount of warnings the user has
*/
export async function countWarnings(userId: Snowflake) {
return container.database.warning.count({
where: {
userId,
},
});
}

View File

@@ -100,6 +100,7 @@ const devIDs = {
},
nonVegan: {
general: '999431677325615189',
vcText: '999431677535338567',
},
vegan: {
general: '999431677535338575',

View File

@@ -18,9 +18,9 @@
*/
import type { Guild, User } from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import type { SusNotes } from '#utils/database/sus';
import { RestrictionLogs } from '#utils/database/restriction';
import { Warnings } from '#utils/database/warnings';
import type { SusNotes } from '#utils/database/moderation/sus';
import { RestrictionLogs } from '#utils/database/moderation/restriction';
import { Warnings } from '#utils/database/moderation/warnings';
export function createSusLogEmbed(notes: SusNotes, user: User, guild: Guild) {
const embed = new EmbedBuilder()

View File

@@ -102,6 +102,7 @@ let IDs = {
},
nonVegan: {
general: '798967615636504657',
vcText: '808191982169096232',
},
vegan: {
general: '787738272616808509',