Compare commits

...

25 Commits
1.0.0 ... main

Author SHA1 Message Date
b485b5d420 Merge pull request 'dev' (#26) from dev into main
Reviewed-on: #26
2023-09-16 15:39:32 +02:00
1c50e818b0 Merge pull request 'feature/uptime-kuma-heartbeat' (#25) from feature/uptime-kuma-heartbeat into dev
Reviewed-on: #25
2023-09-16 15:38:58 +02:00
8cb74a1291
Bump version 2023-09-16 15:35:30 +02:00
4bf782cddf
Add version scripts 2023-09-16 15:34:34 +02:00
c6a4577872
Implement push monitoring 2023-09-16 15:33:16 +02:00
3594c2ea8c Merge pull request 'hotfix/db-race' (#23) from hotfix/db-race into dev
Reviewed-on: #23
2023-09-16 11:20:08 +02:00
538d039c5c Merge branch 'dev' into hotfix/db-race 2023-09-16 11:19:12 +02:00
da1996f2ff Merge pull request 'Fix db race condition' (#20) from hotfix/db-race into main
Reviewed-on: #20
2023-09-16 11:14:33 +02:00
d5b75b12c8
Fix db race condition
- Fixed a bug where the bot would crash if the db connection took too long
- Updated packages to latest version
- Bumped version to 1.1.1
2023-09-16 11:12:43 +02:00
Lukas | AstroGD
a71dbecf8c
Merge pull request #19 from r-Overwatch2/main 2022-11-29 21:38:32 +01:00
Lukas | AstroGD
f528d107da
Merge pull request #18 from r-Overwatch2/release/1.1.0 2022-11-29 21:37:08 +01:00
9510116a37
Update lockfile 2022-11-29 21:36:18 +01:00
b8508a4a82
Adjust changelog 2022-11-29 21:34:02 +01:00
ccf2fd9361
Bump version number 2022-11-29 21:33:13 +01:00
cb4bddf983
Bump version number 2022-11-29 21:00:36 +01:00
b1b087e32c
Update reportEmbed wording 2022-11-29 21:00:09 +01:00
451b414fba
Bump version number 2022-11-29 20:55:03 +01:00
Lukas | AstroGD
b53c08a553
Merge pull request #17 from r-Overwatch2/feature/16-send-dm-to-user-that-used-blocked-word-in-channel
closes https://github.com/r-Overwatch2/eu.astrogd.white-leopard/issues/16
2022-11-29 19:40:29 +01:00
f34e06d31f
Format Readme 2022-11-29 19:38:18 +01:00
173438395e
Update env variable documentation 2022-11-29 19:30:25 +01:00
59429ea548
Removed unused import 2022-11-29 19:26:28 +01:00
dbb64baae3
Send message to user when their channel gets deleted 2022-11-29 19:22:11 +01:00
eccb379b51 Update user report embed 2022-11-29 19:21:00 +01:00
cb5516246f
Add user report Embed 2022-11-29 19:05:24 +01:00
Lukas | AstroGD
63c67f4992
Merge pull request #15 from r-Overwatch2/main 2022-11-29 03:22:52 +01:00
14 changed files with 1098 additions and 420 deletions

3
.npmrc Normal file
View File

@ -0,0 +1,3 @@
@astrogd:registry=https://git.astrogd.cloud/api/packages/packages/npm/
@internal:registry=https://git.astrogd.cloud/api/packages/internal/npm/
//git.astrogd.cloud/api/packages/internal/npm/:_authToken=${NPM_TOKEN}

View File

@ -1,9 +1,30 @@
# Changelog
This file is used to list changes made to this software.
## V1.0.0 [2022-11-29]
_Current development version: **1.0.0**_
_Current development release: 1.1.1_
## V1.1.1 [2023-09-16]
### Updates
- Updated packages to latest versions
### Bugfixes
- Fixed a bug where the bot would crash on startup if the database connection establishment took too long
### Other
- Renamed db service in docker compose file from database to db
## V1.1.0 [2022-11-29]
### Features
- If a channel gets deleted and the responsible user has been detected, a message will be sent to that user informing him of the deletion
## V1.0.0 [2022-11-29]
### Features
- /info
- /logchannel
- /blocklist get

View File

@ -1,40 +1,53 @@
# eu.astrogd.white-leopard
A Discord bot that checks Discord channel names for banned words and prevents renaming of them
## Commands
### /logchanel [channel?] `Permission: MANAGE_GUILD`
Sets the channel where the bot will log if a channel meets the banned word criteria. If channel is omitted, the log channel will be disabled.
### /blocklist `Permission: MANAGE_GUILD`
#### /blocklist get
Returns the global and server specific banned word list and returns it (Same behaviour as /showblocklist)
#### /blocklist add [word]
Adds the word to the server specific blocklist
#### /blocklist remove [word]
Removes the word from the server specific blocklist
### /info `Permission: EVERYONE`
Returns general information about the bot and the servers stats
### /preservesettings `Permission: ADMINISTRATOR`
Changes the behaviour when the bot leaves the server.
Options are:
- Keep settings persistent even if the bot leaves
- Delete setting when the bot leaves the server [default]
### /showblocklist `Permission: MANAGE_CHANNELS`
Returns the global and server specific banned word list and returns it
### /showsettings `Permission: MANAGE_GUILD`
Returns the current settings for the server
## Environment variables
| Name | Description | Required | Example |
| :--------------- | :------------------------------------------------------------------------------ | :------: | :------------------ |
| TOKEN | Discord bot token to log into the API with | ▶️/🚀 | NzYzMDP3MzE1Mzky... |
| DB_HOST | Hostname of the database | ▶️ | 127.0.0.1:3546 |
| DB_HOST | Hostname of the database | ▶️ | 127.0.0.1 |
| DB_USERNAME | Username of the database | ▶️ | root |
| DB_PASSWORD | Password of the database | ▶️ | abc123 |
| DB_DATABASE | Database name | ▶️ | white-leopard |
@ -42,6 +55,7 @@ Returns the current settings for the server
| DEPLOY_TOKEN | Production Discord bot token to log into the API with | 🚀 | NzYzMDP3MzE1Mzky... |
| DEPLOY_CLIENT_ID | Production Client ID of the Discord appication associated with the deploy token | 🚀 | 763035392692274 |
### Icon explanation:
### Icon explanation
- ▶️ = Required in runtime
- 🚀 = Required during CI/CD

View File

@ -8,15 +8,16 @@ services:
tty: true
stdin_open: true
depends_on:
- database
- db
restart: unless-stopped
environment:
- TOKEN=$TOKEN
- DB_HOST=database
- DB_HOST=db
- DB_USERNAME=$DB_USERNAME
- DB_PASSWORD=$DB_PASSWORD
- DB_DATABASE=$DB_DATABASE
database:
- MONITOR_URL=$MONITOR_URL
db:
image: postgres:latest
restart: unless-stopped
ports:

1358
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,27 @@
{
"name": "eu.astrogd.white-leopard",
"version": "1.0.0",
"version": "1.2.0",
"description": "A Discord bot that checks channel names for blacklisted words and reverts the changes if necessary",
"main": "build/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc && shx cp package-lock.json build/package-lock.json",
"start:rebuild": "npm run build && node --enable-source-maps .",
"version:dev": "npm version prerelease --preid dev --no-commit-hooks --no-git-tag-version",
"version:patch": "npm version prepatch --preid dev --no-commit-hooks --no-git-tag-version",
"version:minor": "npm version preminor --preid dev --no-commit-hooks --no-git-tag-version",
"version:major": "npm version premajor --preid dev --no-commit-hooks --no-git-tag-version",
"version:release": "npm version patch --no-commit-hooks --no-git-tag-version",
"deploy-commands:dev": "ts-node ci/devDeploy.ts",
"deploy-commands:prod": "ts-node ci/deploy.ts",
"deploy:dev": "npm run build && npm run deploy-commands:dev && docker compose build && docker compose up -d",
"deploy:prod": "rimraf build && npm run build && npm run deploy-commands:prod && docker build -t astrogd/white-leopard:latest . && docker push astrogd/white-leopard:latest",
"start": "npm run build && npm run deploy-commands:dev && docker-compose up --no-start && docker compose start database && node --enable-source-maps .",
"migration:create": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:generate -d src/data/dataSource.ts -p src/data/migrations/data",
"migration:run": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:run -d src/data/dataSource.ts",
"migration:revert": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:revert -d src/data/dataSource.ts",
"migration:show": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:show -d src/data/dataSource.ts",
"migration:check": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:generate --check -d src/data/dataSource.ts src/data/migrations/data"
"start": "npm run build && npm run deploy-commands:dev && docker-compose up -d db && node --enable-source-maps .",
"migration:create": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:generate -d src/data/dataSource.migration.ts -p src/data/migrations/data",
"migration:run": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:run -d src/data/dataSource.migration.ts",
"migration:revert": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:revert -d src/data/dataSource.migration.ts",
"migration:show": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:show -d src/data/dataSource.migration.ts",
"migration:check": "node --require ts-node/register ./node_modules/typeorm/cli.js migration:generate --check -d src/data/dataSource.migration.ts src/data/migrations/data"
},
"repository": {
"type": "git",
@ -30,15 +35,16 @@
"homepage": "https://github.com/r-Overwatch2/eu.astrogd.white-leopard#readme",
"devDependencies": {
"@types/express": "^4.17.14",
"@types/fs-extra": "^9.0.13",
"@types/node": "^18.11.9",
"rimraf": "^3.0.2",
"@types/fs-extra": "^11.0.2",
"@types/node": "^18.17.17",
"rimraf": "^5.0.1",
"shx": "^0.3.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.3"
"typescript": "^5.2.2"
},
"dependencies": {
"discord.js": "^14.6.0",
"@astrogd/eu.astrogd.uptime-kuma-push-monitor": "^1.0.0-dev.3",
"discord.js": "^14.13.0",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"fs-extra": "^11.0.0",

View File

@ -1,13 +1,25 @@
import { runCleanup } from "../service";
import client from "./index";
import { initPromise } from "../data/dataSource";
import pushMonitor from "@astrogd/eu.astrogd.uptime-kuma-push-monitor";
const token = process.env["TOKEN"];
if (!token) throw new ReferenceError("TOKEN environment variable is missing");
client.login(token);
async function run() {
console.log("Establishing database connection");
await initPromise;
console.log("Connection established\nAuthenticating with Discord API");
client.login(token);
}
client.on("ready", () => {
client.on("ready", async () => {
console.log(`Connected to Discord API. Bot account is ${client.user?.tag} (${client.user?.id})`);
if (process.env["MONITOR_URL"]) pushMonitor.register(process.env["MONITOR_URL"], 120);
pushMonitor.enableShutdownNotifications();
pushMonitor.setPerformanceHandler(() => client.ws.ping);
runCleanup();
});
run();

View File

@ -0,0 +1,3 @@
import dataSource from "./dataSource";
export default dataSource;

View File

@ -28,6 +28,9 @@ const dataSource = new DataSource({
migrationsTransactionMode: "each"
});
dataSource.initialize();
const initPromise = dataSource.initialize();
export default dataSource;
export {
initPromise
}

View File

@ -3,7 +3,7 @@ import { AuditLogEvent, Events, GuildAuditLogsEntry, PermissionFlagsBits, User }
import { getGuildSetting } from "../tools/data";
import { Badword, database } from "../data";
import { IsNull } from "typeorm";
import getDefaultEmbed, { getFailedEmbed } from "../tools/defaultEmbeds";
import getDefaultEmbed, { getFailedEmbed, getUserReportEmbed } from "../tools/defaultEmbeds";
import { getGuildChannel } from "../tools/discord";
import { Color, Emoji } from "../tools/design";
@ -89,6 +89,13 @@ client.on(Events.ChannelCreate, async (newChannel) => {
return;
}
if (responsibleUser) {
const embed = getUserReportEmbed(guild.name, newChannel.name);
responsibleUser.send({
embeds: [embed]
}).catch(() => {});
}
if (!logChannel || !logChannel.isTextBased()) return;
const embed = getDefaultEmbed();
embed.setTitle(`${Emoji.SECURITY_CHALLENGE_FAILED} Blocked word detected`);

View File

@ -3,7 +3,7 @@ import { AuditLogEvent, Events, GuildAuditLogsEntry, PermissionFlagsBits, User }
import { getGuildSetting } from "../tools/data";
import { Badword, database } from "../data";
import { IsNull } from "typeorm";
import getDefaultEmbed, { getFailedEmbed } from "../tools/defaultEmbeds";
import getDefaultEmbed, { getFailedEmbed, getUserReportEmbed } from "../tools/defaultEmbeds";
import { getGuildChannel } from "../tools/discord";
import { Color, Emoji } from "../tools/design";
@ -89,6 +89,13 @@ client.on(Events.ChannelUpdate, async (oldChannel, newChannel) => {
return;
}
if (responsibleUser) {
const embed = getUserReportEmbed(guild.name, newChannel.name);
responsibleUser.send({
embeds: [embed]
}).catch(() => {});
}
if (!logChannel || !logChannel.isTextBased()) return;
const embed = getDefaultEmbed();
embed.setTitle(`${Emoji.SECURITY_CHALLENGE_FAILED} Blocked word detected`);

View File

@ -1,4 +1,3 @@
import "./uptime";
import runCleanup from "./cleanup";
export {

View File

@ -1,19 +0,0 @@
import express from "express";
import pack from "../../package.json";
import startupTime from "../tools/startupTime";
const app = express();
app.get("/", (_req, res) => {
res.status(200).json({
running: true,
version: pack.version,
runningSince: startupTime.toISOString()
});
});
app.all("*", (_req, res) => {
res.status(404).end();
});
app.listen(80);

View File

@ -30,3 +30,14 @@ export function getFailedEmbed(): EmbedBuilder {
embed.setColor(Color.STOPSIGN_RED);
return embed;
}
export function getUserReportEmbed(guildName: string, channelName: string): EmbedBuilder {
const embed = getDefaultEmbed();
embed.setColor(Color.STOPSIGN_RED);
embed.setTitle(`${Emoji.SECURITY_CHALLENGE_FAILED} A channel you modified has been deleted`);
embed.setDescription(`Hey there ${Emoji.WAVING}
Your channel (#${channelName}) on the "${guildName}" server contained a blacklisted word and was deleted automatically.
Please make sure to keep channel names friendly for everyone!`);
return embed;
}