Compare commits
No commits in common. "main" and "v3.1.0" have entirely different histories.
|
@ -7,16 +7,15 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=3.2.1
|
BOT_VER=3.1
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
|
BOT_DATE=08 May 2023
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=682942374040961060
|
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
|
14
.drone.yml
14
.drone.yml
|
@ -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.121
|
||||||
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.121
|
||||||
username: vylpes
|
username: vylpes
|
||||||
password:
|
password:
|
||||||
from_secret: ssh_password
|
from_secret: ssh_password
|
||||||
|
@ -54,11 +54,11 @@ steps:
|
||||||
- yarn install --frozen-lockfile
|
- yarn install --frozen-lockfile
|
||||||
- yarn build
|
- yarn build
|
||||||
|
|
||||||
# - name: test
|
- name: test
|
||||||
# image: node
|
image: node
|
||||||
# commands:
|
commands:
|
||||||
# - yarn install --frozen-lockfile
|
- yarn install --frozen-lockfile
|
||||||
# - yarn test
|
- yarn test
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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,6 +24,6 @@ Please describe the tests that you ran to verify the changes. Provide instructio
|
||||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
- [ ] I have made corresponding changes to the documentation
|
- [ ] I have made corresponding changes to the documentation
|
||||||
- [ ] My changes generate no new warnings
|
- [ ] My changes generate no new warnings
|
||||||
- [ ] I have added tests that provide my fix is effective or that my feature works
|
- [ ] I have added tests that provde my fix is effective or that my feature works
|
||||||
- [ ] New and existing unit tests pass locally with my changes
|
- [ ] New and existing unit tests pass locally with my changes
|
||||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
- [ ] Any dependent changes have been merged and published in downstream modules
|
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
16
.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
name: Epic
|
||||||
|
about: Agile Epic
|
||||||
|
title: ''
|
||||||
|
labels: epic
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Description here*
|
||||||
|
|
||||||
|
## Stories
|
||||||
|
*Stories linked to this epic*
|
||||||
|
|
||||||
|
## Bugs
|
||||||
|
*Bugs linked to this epic*
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
24
.github/ISSUE_TEMPLATE/user-story.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/user-story.md
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
name: User Story
|
||||||
|
about: Agile User Story
|
||||||
|
title: ''
|
||||||
|
labels: needs criteria, story
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Epic Link: N/A
|
||||||
|
Story Points: N/A
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Description here*
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
*Add your ACs here*
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
*Any extra information*
|
||||||
|
|
||||||
|
## Subtasks
|
||||||
|
*Add technical subtasks here*
|
30
.github/pull_request_template.md
vendored
Normal file
30
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||||
|
|
||||||
|
Fixes # (issue)
|
||||||
|
|
||||||
|
## Type of change
|
||||||
|
|
||||||
|
Please delete options that are not relevant.
|
||||||
|
|
||||||
|
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||||
|
- [ ] New feature (non-breaking change which adds functionality)
|
||||||
|
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
|
- [ ] This change requires a documentation update
|
||||||
|
|
||||||
|
# How Has This Been Tested?
|
||||||
|
|
||||||
|
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||||
|
|
||||||
|
|
||||||
|
# Checklist:
|
||||||
|
|
||||||
|
- [ ] My code follows the style guidelines of this project
|
||||||
|
- [ ] I have performed a self-review of my own code
|
||||||
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
|
- [ ] I have made corresponding changes to the documentation
|
||||||
|
- [ ] My changes generate no new warnings
|
||||||
|
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||||
|
- [ ] New and existing unit tests pass locally with my changes
|
||||||
|
- [ ] Any dependent changes have been merged and published in downstream modules
|
0
.gitlab/.gitkeep
Normal file
0
.gitlab/.gitkeep
Normal file
0
.gitlab/merge_request_templates/.gitkeep
Normal file
0
.gitlab/merge_request_templates/.gitkeep
Normal file
29
.gitlab/merge_request_templates/default.md
Normal file
29
.gitlab/merge_request_templates/default.md
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||||
|
|
||||||
|
Fixes # (issue)
|
||||||
|
|
||||||
|
## Type of change
|
||||||
|
|
||||||
|
Please delete options that are not relevant.
|
||||||
|
|
||||||
|
- Bug fix (non-breaking change which fixes an issue)
|
||||||
|
- New feature (non-breaking change which adds functionality)
|
||||||
|
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
|
- This change requires a documentation update
|
||||||
|
|
||||||
|
# How Has This Been Tested?
|
||||||
|
|
||||||
|
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||||
|
|
||||||
|
# Checklist
|
||||||
|
|
||||||
|
- [ ] My code follows the style guidelines of this project
|
||||||
|
- [ ] I have performed a self-review of my own code
|
||||||
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
|
- [ ] I have made corresponding changes to the documentation
|
||||||
|
- [ ] My changes generate no new warnings
|
||||||
|
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||||
|
- [ ] New and existing unit tests pass locally with my changes
|
||||||
|
- [ ] Any dependant changes have been merged and published in downstream modules
|
24
.prod.env
Normal file
24
.prod.env
Normal 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.1
|
||||||
|
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
24
.stage.env
Normal 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.1
|
||||||
|
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
|
|
@ -26,11 +26,11 @@ event.message.delete.channel: Sets the channel the bot will log message delete e
|
||||||
event.message.update.enabled: Enables/Disables the message delete log event (Default: "false")
|
event.message.update.enabled: Enables/Disables the message delete log event (Default: "false")
|
||||||
event.message.update.channel: Sets the channel the bot will log message delete events to (Default: "message-logs")
|
event.message.update.channel: Sets the channel the bot will log message delete events to (Default: "message-logs")
|
||||||
|
|
||||||
event.member.add.enabled: Enables/Disables the member join log event (Default: "false")
|
event.member.add.enabled: Enables/Disables the message delete log event (Default: "false")
|
||||||
event.member.add.channel: Sets the channel the bot will log member join events to (Default: "member-logs")
|
event.member.add.channel: Sets the channel the bot will log message delete events to (Default: "member-logs")
|
||||||
|
|
||||||
event.member.remove.enabled: Enables/Disables the member leave log event (Default: "false")
|
event.member.remove.enabled: Enables/Disables the message delete log event (Default: "false")
|
||||||
event.member.remove.channel: Sets the channel the bot will log member leave events to (Default: "member-logs")
|
event.member.remove.channel: Sets the channel the bot will log message delete events to (Default: "member-logs")
|
||||||
|
|
||||||
event.member.update.enabled: Enables/Disables the member update log event (Default: "false")
|
event.member.update.enabled: Enables/Disables the message delete log event (Default: "false")
|
||||||
event.member.update.channel: Sets the channel the bot will log member update events to (Default: "member-logs")
|
event.member.update.channel: Sets the channel the bot will log message delete events to (Default: "member-logs")
|
|
@ -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
31
docker-compose.prod.yml
Normal 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
31
docker-compose.stage.yml
Normal 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
|
|
@ -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
8815
package-lock.json
generated
File diff suppressed because it is too large
Load diff
21
package.json
21
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vylbot-app",
|
"name": "vylbot-app",
|
||||||
"version": "3.2.2",
|
"version": "3.1.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",
|
||||||
|
@ -8,11 +8,9 @@
|
||||||
"clean": "rm -rf node_modules/ dist/",
|
"clean": "rm -rf node_modules/ dist/",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"start": "node ./dist/vylbot",
|
"start": "node ./dist/vylbot",
|
||||||
"test": "echo true",
|
"test": "jest",
|
||||||
"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"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -27,7 +25,7 @@
|
||||||
"homepage": "https://github.com/Vylpes/vylbot-app",
|
"homepage": "https://github.com/Vylpes/vylbot-app",
|
||||||
"funding": "https://ko-fi.com/vylpes",
|
"funding": "https://ko-fi.com/vylpes",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/rest": "^2.0.0",
|
"@discordjs/rest": "^1.1.0",
|
||||||
"@types/jest": "^29.0.0",
|
"@types/jest": "^29.0.0",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^9.0.0",
|
||||||
"discord.js": "^14.3.0",
|
"discord.js": "^14.3.0",
|
||||||
|
@ -35,19 +33,14 @@
|
||||||
"emoji-regex": "^10.0.0",
|
"emoji-regex": "^10.0.0",
|
||||||
"jest": "^29.0.0",
|
"jest": "^29.0.0",
|
||||||
"jest-mock-extended": "^3.0.0",
|
"jest-mock-extended": "^3.0.0",
|
||||||
"minimatch": "9.0.3",
|
"minimatch": "9.0.2",
|
||||||
"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": {
|
|
||||||
"**/semver": "^7.5.2",
|
|
||||||
"**/undici": "^6.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
"np": "^10.0.0",
|
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import { ButtonInteraction, CacheType } from "discord.js";
|
|
||||||
import { ButtonEvent } from "../type/buttonEvent";
|
|
||||||
import SettingsHelper from "../helpers/SettingsHelper";
|
|
||||||
|
|
||||||
export default class Verify extends ButtonEvent {
|
|
||||||
public override async execute(interaction: ButtonInteraction<CacheType>) {
|
|
||||||
if (!interaction.guildId || !interaction.guild) return;
|
|
||||||
|
|
||||||
const roleName = await SettingsHelper.GetSetting("verification.role", interaction.guildId);
|
|
||||||
|
|
||||||
if (!roleName) return;
|
|
||||||
|
|
||||||
const role = interaction.guild.roles.cache.find(x => x.name == roleName);
|
|
||||||
|
|
||||||
if (!role) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: `Unable to find the role, ${roleName}`,
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const member = interaction.guild.members.cache.find(x => x.id == interaction.user.id);
|
|
||||||
|
|
||||||
if (!member || !member.manageable) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: "Unable to give role to user",
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await member.roles.add(role);
|
|
||||||
|
|
||||||
await interaction.reply({
|
|
||||||
content: "Given role",
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Client, Partials } from "discord.js";
|
import { Client } from "discord.js";
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
import { createConnection } from "typeorm";
|
import { createConnection } from "typeorm";
|
||||||
import { EventType } from "../constants/EventType";
|
import { EventType } from "../constants/EventType";
|
||||||
|
@ -9,14 +9,10 @@ import { Command } from "../type/command";
|
||||||
import { Events } from "./events";
|
import { Events } from "./events";
|
||||||
import { Util } from "./util";
|
import { Util } from "./util";
|
||||||
import AppDataSource from "../database/dataSources/appDataSource";
|
import AppDataSource from "../database/dataSources/appDataSource";
|
||||||
import ButtonEventItem from "../contracts/ButtonEventItem";
|
|
||||||
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[];
|
||||||
private static _eventItems: IEventItem[];
|
private static _eventItems: IEventItem[];
|
||||||
private static _buttonEvents: ButtonEventItem[];
|
|
||||||
|
|
||||||
private _events: Events;
|
private _events: Events;
|
||||||
private _util: Util;
|
private _util: Util;
|
||||||
|
@ -29,17 +25,12 @@ export class CoreClient extends Client {
|
||||||
return this._eventItems;
|
return this._eventItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get buttonEvents(): ButtonEventItem[] {
|
constructor(intents: number[]) {
|
||||||
return this._buttonEvents;
|
super({ intents: intents });
|
||||||
}
|
|
||||||
|
|
||||||
constructor(intents: number[], partials: Partials[]) {
|
|
||||||
super({ intents: intents, partials: partials });
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
CoreClient._commandItems = [];
|
CoreClient._commandItems = [];
|
||||||
CoreClient._eventItems = [];
|
CoreClient._eventItems = [];
|
||||||
CoreClient._buttonEvents = [];
|
|
||||||
|
|
||||||
this._events = new Events();
|
this._events = new Events();
|
||||||
this._util = new Util();
|
this._util = new Util();
|
||||||
|
@ -60,10 +51,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);
|
||||||
}
|
}
|
||||||
|
@ -86,13 +73,4 @@ export class CoreClient extends Client {
|
||||||
|
|
||||||
CoreClient._eventItems.push(item);
|
CoreClient._eventItems.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterButtonEvent(buttonId: string, event: ButtonEvent) {
|
|
||||||
const item: ButtonEventItem = {
|
|
||||||
ButtonId: buttonId,
|
|
||||||
Event: event,
|
|
||||||
};
|
|
||||||
|
|
||||||
CoreClient._buttonEvents.push(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,40 @@
|
||||||
import { Interaction } from "discord.js";
|
import { Interaction } from "discord.js";
|
||||||
import ChatInputCommand from "./interactionCreate/chatInputCommand";
|
import ICommandItem from "../contracts/ICommandItem";
|
||||||
import Button from "./interactionCreate/button";
|
import SettingsHelper from "../helpers/SettingsHelper";
|
||||||
|
import { CoreClient } from "./client";
|
||||||
|
|
||||||
export class Events {
|
export class Events {
|
||||||
public async onInteractionCreate(interaction: Interaction) {
|
public async onInteractionCreate(interaction: Interaction) {
|
||||||
|
if (!interaction.isChatInputCommand()) return;
|
||||||
if (!interaction.guildId) return;
|
if (!interaction.guildId) return;
|
||||||
|
|
||||||
if (interaction.isChatInputCommand()) {
|
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId);
|
||||||
ChatInputCommand.onChatInput(interaction);
|
const disabledCommands = disabledCommandsString?.split(",");
|
||||||
|
|
||||||
|
const disabledCommandsMessage = await SettingsHelper.GetSetting("commands.disabled.message", interaction.guildId);
|
||||||
|
|
||||||
|
if (disabledCommands?.find(x => x == interaction.commandName)) {
|
||||||
|
await interaction.reply(disabledCommandsMessage || "This command is disabled.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interaction.isButton()) {
|
const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId);
|
||||||
Button.onButtonClicked(interaction);
|
const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId);
|
||||||
|
|
||||||
|
let itemToUse: ICommandItem;
|
||||||
|
|
||||||
|
if (!itemForServer) {
|
||||||
|
if (!item) {
|
||||||
|
await interaction.reply('Command not found');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemToUse = item;
|
||||||
|
} else {
|
||||||
|
itemToUse = itemForServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemToUse.Command.execute(interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit when bot is logged in and ready to use
|
// Emit when bot is logged in and ready to use
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { ButtonInteraction } from "discord.js";
|
|
||||||
import { CoreClient } from "../client";
|
|
||||||
|
|
||||||
export default class Button {
|
|
||||||
public static async onButtonClicked(interaction: ButtonInteraction) {
|
|
||||||
if (!interaction.isButton) return;
|
|
||||||
|
|
||||||
const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(" ")[0]);
|
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
await interaction.reply("Event not found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.Event.execute(interaction);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
import { Interaction } from "discord.js";
|
|
||||||
import { CoreClient } from "../client";
|
|
||||||
import ICommandItem from "../../contracts/ICommandItem";
|
|
||||||
|
|
||||||
export default class ChatInputCommand {
|
|
||||||
public static async onChatInput(interaction: Interaction) {
|
|
||||||
if (!interaction.isChatInputCommand()) return;
|
|
||||||
|
|
||||||
const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId);
|
|
||||||
const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId);
|
|
||||||
|
|
||||||
let itemToUse: ICommandItem;
|
|
||||||
|
|
||||||
if (!itemForServer) {
|
|
||||||
if (!item) {
|
|
||||||
await interaction.reply("Command not found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemToUse = item;
|
|
||||||
} else {
|
|
||||||
itemToUse = itemForServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemToUse.Command.execute(interaction);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 =>
|
||||||
|
|
|
@ -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');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -44,7 +44,6 @@ export default class Ban extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Banned")
|
.setTitle("Member Banned")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -116,15 +116,9 @@ export default class Config extends Command {
|
||||||
const setting = server.Settings.filter(x => x.Key == key.value)[0];
|
const setting = server.Settings.filter(x => x.Key == key.value)[0];
|
||||||
|
|
||||||
if (setting) {
|
if (setting) {
|
||||||
await interaction.reply(`\`${key.value}\`: \`${setting.Value}\``);
|
await interaction.reply(`\`${key}\`: \`${setting.Value}\``);
|
||||||
} else {
|
} else {
|
||||||
var defaultValue = DefaultValues.GetValue(key.value.toString());
|
await interaction.reply(`\`${key}\`: \`${DefaultValues.GetValue(key.value.toString())}\` <DEFAULT>`);
|
||||||
|
|
||||||
if (defaultValue) {
|
|
||||||
await interaction.reply(`\`${key.value}\`: \`${defaultValue}\` <DEFAULT>`);
|
|
||||||
} else {
|
|
||||||
await interaction.reply(`\`${key.value}\`: <NONE>`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -44,7 +44,6 @@ export default class Kick extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Kicked")
|
.setTitle("Member Kicked")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -42,7 +42,6 @@ export default class Mute extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Muted")
|
.setTitle("Member Muted")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
@ -54,14 +53,7 @@ export default class Mute extends Command {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const mutedRoleName = await SettingsHelper.GetSetting('role.muted', interaction.guildId);
|
const mutedRole = interaction.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED);
|
||||||
|
|
||||||
if (!mutedRoleName) {
|
|
||||||
await interaction.reply('Unable to find configuration. Please contact the bot author.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutedRole = interaction.guild.roles.cache.find(role => role.name == mutedRoleName);
|
|
||||||
|
|
||||||
if (!mutedRole) {
|
if (!mutedRole) {
|
||||||
await interaction.reply('Muted role not found.');
|
await interaction.reply('Muted role not found.');
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
import { CommandInteraction, SlashCommandBuilder } from "discord.js";
|
|
||||||
import { Command } from "../type/command";
|
|
||||||
import { EmbedBuilder } from "@discordjs/builders";
|
|
||||||
import EmbedColours from "../constants/EmbedColours";
|
|
||||||
|
|
||||||
export default class Poll extends Command {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.CommandBuilder = new SlashCommandBuilder()
|
|
||||||
.setName('poll')
|
|
||||||
.setDescription('Run a poll, automatically adding reaction emojis as options')
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('title')
|
|
||||||
.setDescription('Title of the poll')
|
|
||||||
.setRequired(true))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('option1')
|
|
||||||
.setDescription('Option 1')
|
|
||||||
.setRequired(true))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('option2')
|
|
||||||
.setDescription('Option 2')
|
|
||||||
.setRequired(true))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('option3')
|
|
||||||
.setDescription('Option 3'))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('option4')
|
|
||||||
.setDescription('Option 4'))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName('option5')
|
|
||||||
.setDescription('Option 5'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async execute(interaction: CommandInteraction) {
|
|
||||||
const title = interaction.options.get('title');
|
|
||||||
const option1 = interaction.options.get('option1');
|
|
||||||
const option2 = interaction.options.get('option2');
|
|
||||||
const option3 = interaction.options.get('option3');
|
|
||||||
const option4 = interaction.options.get('option4');
|
|
||||||
const option5 = interaction.options.get('option5');
|
|
||||||
|
|
||||||
if (!title || !option1 || !option2) return;
|
|
||||||
|
|
||||||
const description = [
|
|
||||||
option1.value as string,
|
|
||||||
option2.value as string,
|
|
||||||
option3?.value as string,
|
|
||||||
option4?.value as string,
|
|
||||||
option5?.value as string
|
|
||||||
]
|
|
||||||
.filter(x => x != null);
|
|
||||||
|
|
||||||
const arrayOfNumbers = [
|
|
||||||
':one:',
|
|
||||||
':two:',
|
|
||||||
':three:',
|
|
||||||
':four:',
|
|
||||||
':five:',
|
|
||||||
];
|
|
||||||
|
|
||||||
const reactionEmojis = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣"];
|
|
||||||
|
|
||||||
description.forEach((value, index) => {
|
|
||||||
description[index] = `${reactionEmojis[index]} ${description[index]}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
|
||||||
.setColor(EmbedColours.Ok)
|
|
||||||
.setTitle(title.value as string)
|
|
||||||
.setDescription(description.join('\n'))
|
|
||||||
.setFooter({
|
|
||||||
text: `Poll by ${interaction.user.username}`,
|
|
||||||
iconURL: interaction.user.avatarURL()!,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const message = await interaction.reply({ embeds: [ embed ]});
|
|
||||||
|
|
||||||
description.forEach(async (value, index) => {
|
|
||||||
await (await message.fetch()).react(reactionEmojis[index]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
||||||
import { existsSync, readFileSync } from "fs";
|
import { existsSync, readFileSync } from "fs";
|
||||||
import EmbedColours from "../constants/EmbedColours";
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import SettingsHelper from "../helpers/SettingsHelper";
|
|
||||||
|
|
||||||
interface IRules {
|
interface IRules {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -15,36 +14,13 @@ export default class Rules extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.CommandBuilder = new SlashCommandBuilder()
|
super.CommandBuilder = new SlashCommandBuilder()
|
||||||
.setName('rules')
|
.setName("rules")
|
||||||
.setDescription("Rules-related commands")
|
.setDescription("Send the rules embeds for this server")
|
||||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator)
|
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator);
|
||||||
.addSubcommand(x =>
|
|
||||||
x
|
|
||||||
.setName('embeds')
|
|
||||||
.setDescription('Send the rules embeds for this server'))
|
|
||||||
.addSubcommand(x =>
|
|
||||||
x
|
|
||||||
.setName('access')
|
|
||||||
.setDescription('Send the server verification embed button'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(interaction: CommandInteraction) {
|
public override async execute(interaction: CommandInteraction) {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
|
||||||
|
|
||||||
switch (interaction.options.getSubcommand()) {
|
|
||||||
case "embeds":
|
|
||||||
await this.SendEmbeds(interaction);
|
|
||||||
break;
|
|
||||||
case "access":
|
|
||||||
await this.SendAccessButton(interaction);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
await interaction.reply("Subcommand doesn't exist.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async SendEmbeds(interaction: CommandInteraction) {
|
|
||||||
if (!interaction.guildId) return;
|
if (!interaction.guildId) return;
|
||||||
|
|
||||||
if (!existsSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`)) {
|
if (!existsSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`)) {
|
||||||
|
@ -95,27 +71,4 @@ export default class Rules extends Command {
|
||||||
|
|
||||||
await interaction.reply({ embeds: [ successEmbed ], ephemeral: true });
|
await interaction.reply({ embeds: [ successEmbed ], ephemeral: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async SendAccessButton(interaction: CommandInteraction) {
|
|
||||||
if (!interaction.guildId) return;
|
|
||||||
|
|
||||||
const buttonLabel = await SettingsHelper.GetSetting("rules.access.label", interaction.guildId);
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
|
||||||
.addComponents([
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId('verify')
|
|
||||||
.setStyle(ButtonStyle.Primary)
|
|
||||||
.setLabel(buttonLabel || "Verify")
|
|
||||||
]);
|
|
||||||
|
|
||||||
await interaction.channel?.send({
|
|
||||||
components: [ row ]
|
|
||||||
});
|
|
||||||
|
|
||||||
await interaction.reply({
|
|
||||||
content: "Success",
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -64,7 +64,6 @@ export default class Timeout extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Timed Out")
|
.setTitle("Member Timed Out")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -40,7 +40,6 @@ export default class Unmute extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Unmuted")
|
.setTitle("Member Unmuted")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
@ -52,14 +51,7 @@ export default class Unmute extends Command {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const mutedRoleName = await SettingsHelper.GetSetting('role.muted', interaction.guildId);
|
const mutedRole = interaction.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED);
|
||||||
|
|
||||||
if (!mutedRoleName) {
|
|
||||||
await interaction.reply('Unable to find configuration. Please contact the bot author.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutedRole = interaction.guild.roles.cache.find(role => role.name == mutedRoleName);
|
|
||||||
|
|
||||||
if (!mutedRole) {
|
if (!mutedRole) {
|
||||||
await interaction.reply('Muted role not found.');
|
await interaction.reply('Muted role not found.');
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -41,7 +41,6 @@ export default class Warn extends Command {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Warned")
|
.setTitle("Member Warned")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
|
|
@ -31,7 +31,6 @@ export default class DefaultValues {
|
||||||
|
|
||||||
// Rules (Command)
|
// Rules (Command)
|
||||||
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
||||||
this.values.push({ Key: "rules.access.label", Value: "Verify" });
|
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
|
this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
|
||||||
|
@ -58,7 +57,7 @@ export default class DefaultValues {
|
||||||
this.values.push({ Key: "event.member.remove.channel", Value: "member-logs" });
|
this.values.push({ Key: "event.member.remove.channel", Value: "member-logs" });
|
||||||
|
|
||||||
this.values.push({ Key: "event.member.update.enabled", Value: "false" });
|
this.values.push({ Key: "event.member.update.enabled", Value: "false" });
|
||||||
this.values.push({ Key: "event.member.update.channel", Value: "member-logs" });
|
this.values.push({ Key: "event.member.remove.channel", Value: "member-logs" });
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { ButtonEvent } from "../type/buttonEvent";
|
|
||||||
|
|
||||||
interface ButtonEventItem {
|
|
||||||
ButtonId: string,
|
|
||||||
Event: ButtonEvent,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ButtonEventItem;
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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") {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -36,8 +33,8 @@ export default async function MessageDelete(message: Message) {
|
||||||
if (message.attachments.size > 0) {
|
if (message.attachments.size > 0) {
|
||||||
embed.addFields([
|
embed.addFields([
|
||||||
{
|
{
|
||||||
name: `Attachments (${message.attachments.size})`,
|
name: "Attachments",
|
||||||
value: `\`\`\`${message.attachments.map(x => x.name).join("\n")}\`\`\``
|
value: `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\``
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@ import Disable from "./commands/disable";
|
||||||
import Ignore from "./commands/ignore";
|
import Ignore from "./commands/ignore";
|
||||||
import Kick from "./commands/kick";
|
import Kick from "./commands/kick";
|
||||||
import Mute from "./commands/mute";
|
import Mute from "./commands/mute";
|
||||||
import Poll from "./commands/poll";
|
|
||||||
import Role from "./commands/Role/role";
|
import Role from "./commands/Role/role";
|
||||||
import ConfigRole from "./commands/Role/config";
|
import ConfigRole from "./commands/Role/config";
|
||||||
import Rules from "./commands/rules";
|
import Rules from "./commands/rules";
|
||||||
|
@ -37,9 +36,6 @@ import MessageDelete from "./events/MessageEvents/MessageDelete";
|
||||||
import MessageUpdate from "./events/MessageEvents/MessageUpdate";
|
import MessageUpdate from "./events/MessageEvents/MessageUpdate";
|
||||||
import MessageCreate from "./events/MessageEvents/MessageCreate";
|
import MessageCreate from "./events/MessageEvents/MessageCreate";
|
||||||
|
|
||||||
// Button Event Imports
|
|
||||||
import Verify from "./buttonEvents/verify";
|
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
CoreClient.RegisterCommand("about", new About());
|
CoreClient.RegisterCommand("about", new About());
|
||||||
|
@ -53,7 +49,6 @@ export default class Registry {
|
||||||
CoreClient.RegisterCommand("ignore", new Ignore());
|
CoreClient.RegisterCommand("ignore", new Ignore());
|
||||||
CoreClient.RegisterCommand("kick", new Kick());
|
CoreClient.RegisterCommand("kick", new Kick());
|
||||||
CoreClient.RegisterCommand("mute", new Mute());
|
CoreClient.RegisterCommand("mute", new Mute());
|
||||||
CoreClient.RegisterCommand("poll", new Poll());
|
|
||||||
CoreClient.RegisterCommand("rules", new Rules());
|
CoreClient.RegisterCommand("rules", new Rules());
|
||||||
CoreClient.RegisterCommand("setup", new Setup());
|
CoreClient.RegisterCommand("setup", new Setup());
|
||||||
CoreClient.RegisterCommand("timeout", new Timeout());
|
CoreClient.RegisterCommand("timeout", new Timeout());
|
||||||
|
@ -87,8 +82,4 @@ export default class Registry {
|
||||||
CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate);
|
CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate);
|
||||||
CoreClient.RegisterEvent(EventType.MessageCreate, MessageCreate);
|
CoreClient.RegisterEvent(EventType.MessageCreate, MessageCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterButtonEvents() {
|
|
||||||
CoreClient.RegisterButtonEvent("verify", new Verify());
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
import { ButtonInteraction } from "discord.js";
|
|
||||||
|
|
||||||
export abstract class ButtonEvent {
|
|
||||||
abstract execute(interaction: ButtonInteraction): Promise<void>;
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { CoreClient } from "./client/client";
|
import { CoreClient } from "./client/client";
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
import registry from "./registry";
|
import registry from "./registry";
|
||||||
import { IntentsBitField, Partials } from "discord.js";
|
import { IntentsBitField } from "discord.js";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
@ -30,13 +30,9 @@ const client = new CoreClient([
|
||||||
IntentsBitField.Flags.GuildMessages,
|
IntentsBitField.Flags.GuildMessages,
|
||||||
IntentsBitField.Flags.GuildMembers,
|
IntentsBitField.Flags.GuildMembers,
|
||||||
IntentsBitField.Flags.MessageContent,
|
IntentsBitField.Flags.MessageContent,
|
||||||
], [
|
|
||||||
Partials.GuildMember,
|
|
||||||
Partials.User,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
registry.RegisterCommands();
|
registry.RegisterCommands();
|
||||||
registry.RegisterEvents();
|
registry.RegisterEvents();
|
||||||
registry.RegisterButtonEvents();
|
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
|
|
Loading…
Reference in a new issue