Skip to content
This repository has been archived by the owner on Oct 12, 2024. It is now read-only.

v3 #30

Merged
merged 57 commits into from
Apr 26, 2024
Merged

v3 #30

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
9a23c1a
Initialize
RealEthanPlayzDev Feb 11, 2024
97fa4ce
Config: Update
RealEthanPlayzDev Feb 11, 2024
eb63248
Library: Import my logging library
RealEthanPlayzDev Feb 11, 2024
11e5ab8
Client: Initial client code
RealEthanPlayzDev Feb 11, 2024
32b7c02
Interactions: Initial code
RealEthanPlayzDev Feb 12, 2024
04e75a4
Interactions: Change casing
RealEthanPlayzDev Feb 12, 2024
a5ad2e8
Events: Initial code
RealEthanPlayzDev Feb 12, 2024
94cdf4c
Client: Move interatioc & event registration to constructor, hook eve…
RealEthanPlayzDev Feb 13, 2024
3c0869c
Event: Manager provides a seperate event logging namespace
RealEthanPlayzDev Feb 13, 2024
ed460d9
Event-ReadyInit: Deploy interactions, Event-PresenceResumption: Setup
RealEthanPlayzDev Feb 13, 2024
9b68e51
EmbedBuilder: Initial code
RealEthanPlayzDev Feb 13, 2024
2a0a722
Events-ReadyInit: Runtime logs
RealEthanPlayzDev Feb 13, 2024
e7dd8e8
Interactions: Dispatch handling
RealEthanPlayzDev Feb 14, 2024
a231f4a
Events: Fix incorrect callback invoke
RealEthanPlayzDev Feb 15, 2024
3a52ffb
Events-ReadyInit: Fix typo
RealEthanPlayzDev Feb 15, 2024
503454c
InstallUtils: FillMissingGuildData
RealEthanPlayzDev Feb 16, 2024
855a5a9
Interactions: Add config for not registering test interactions
RealEthanPlayzDev Feb 16, 2024
4e37c2b
InstallUtils-FillMissingGuilData: createMany needs to use skipDuplicates
RealEthanPlayzDev Feb 16, 2024
9ace265
Events-GuildDataSetup: Make a new guild data at join
RealEthanPlayzDev Feb 16, 2024
f4c833f
Database: Case counting system change
RealEthanPlayzDev Feb 16, 2024
64a01ff
DatabaseUtils: Initial code
RealEthanPlayzDev Feb 16, 2024
c1b71f2
Interactions: ChatCommand interaction data use Pick and pick toJson a…
RealEthanPlayzDev Feb 16, 2024
4c5a7ca
Int-CI-Moderation-Case: Initial code
RealEthanPlayzDev Feb 16, 2024
87b275f
Int-CI-Moderation: Fix typo with ephmeral to ephemeral
RealEthanPlayzDev Feb 17, 2024
668d78d
DatabaseUtils: getCasesWithLatestHistory
RealEthanPlayzDev Feb 17, 2024
a232678
Int-CI-Moderation-Cases: Initial code
RealEthanPlayzDev Feb 17, 2024
3c7baf4
Int-CI-Moderation-Case: Use timestamp strings instead
RealEthanPlayzDev Feb 17, 2024
7d6fccb
Events-ReadyInit: Guild interaction registry logging change and use t…
RealEthanPlayzDev Feb 17, 2024
b7eaf94
Client: Destroy will now explicitly disconnect database
RealEthanPlayzDev Feb 18, 2024
d162bd0
DatabaseUtils: generateCaseEmbedFromData & generateCaseEmbedFromCaseId
RealEthanPlayzDev Feb 18, 2024
646aa1a
Int-CI-Moderation-Case: Migrate embed generation to using generateCas…
RealEthanPlayzDev Feb 18, 2024
d05cf16
Int-CI-Moderation-RemoveCase
RealEthanPlayzDev Feb 18, 2024
e3e930a
Int-CI-Moderation-EditCase: Initial code
RealEthanPlayzDev Feb 18, 2024
17960ee
DatabaseUtils: sendGuildLog
RealEthanPlayzDev Feb 25, 2024
9cea3d6
Int-CI-Moderation: Logging
RealEthanPlayzDev Feb 25, 2024
6ad336e
Database: ModerationCase now has a Active and RelatedCaseId field
RealEthanPlayzDev Mar 10, 2024
9eef227
DatabaseUtils: Update getCaseData to reflect latest schema
RealEthanPlayzDev Mar 10, 2024
e69adde
DatabaseUtils: Update generateCaseEmbedFromData to add active and rel…
RealEthanPlayzDev Mar 10, 2024
1c76de9
Int-CI-Moderation-EditCase: Reflect latest CaseData change
RealEthanPlayzDev Mar 10, 2024
56b33d1
Int-CI-Moderation-CreateCase: Initial code
RealEthanPlayzDev Mar 10, 2024
65dd906
DatabaseUtils: sendGuildPubLog
RealEthanPlayzDev Mar 10, 2024
b8a06b8
Int-CI-Moderation-CreateCase: Use DatabaseUtil's sendGuildPubLog
RealEthanPlayzDev Mar 10, 2024
baaa954
Database: Update schema for guild features system
RealEthanPlayzDev Mar 10, 2024
5a852da
GuildFeatures: Initial code
RealEthanPlayzDev Mar 10, 2024
24afc70
GuildFeature: Implement requirement checking
RealEthanPlayzDev Mar 10, 2024
7cdbab3
InstallUtils: EnableGuildFeature
RealEthanPlayzDev Mar 10, 2024
36a48da
Int-CI-Moderation-CreateCase: Ban creation should check for existing …
RealEthanPlayzDev Mar 11, 2024
054aacd
Int-CI-Moderation: Add warn, mute, kick, and ban commands
RealEthanPlayzDev Apr 24, 2024
63f383e
Int-CI-Moderation-Ban: Fix NotAppealable field not set during db
RealEthanPlayzDev Apr 25, 2024
1f5c9b9
Int-CI-Moderation: TempBan and UnBan command
RealEthanPlayzDev Apr 25, 2024
2bcc993
Project: Update dependencies
RealEthanPlayzDev Apr 25, 2024
9b95465
Int-CI-Moderation-Ban: Fix using uninitialized caseId instead of from…
RealEthanPlayzDev Apr 25, 2024
593f0dd
Int-CI-Moderation-UnBan: Fix relcid get failing and actually unban user
RealEthanPlayzDev Apr 25, 2024
c6adce9
Interaction: Call initialize if a interaction has them implemented
RealEthanPlayzDev Apr 25, 2024
a0edd71
Int-CI-Moderation-TempBan: Fix a bunch of stuff and add logging
RealEthanPlayzDev Apr 25, 2024
fd262fb
README: Feature parity section
RealEthanPlayzDev Apr 26, 2024
5ea7912
Project: Fix conflicts
RealEthanPlayzDev Apr 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[*]
charset = utf-8
insert_final_newline = true
end_of_line = lf
indent_style = space
indent_size = 4
max_line_length = 150
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
METEORIUM_POSTGRES_URL=
METEORIUM_BOT_TOKEN=
METEORIUM_APPLICATION_ID=
METEORIUM_HOLODEX_APIKEY=
METEORIUM_GENIUS_APIKEY=
METEORIUM_APPDEPLOY_GUILDIDS=
METEORIUM_RUNTIMELOG_CHANNELIDS=
METEORIUM_NOREG_TESTINTERACTIONS=
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
config.json
# Compile deps and results
node_modules
.ENV
dist
dist

# Configuration files
.env
4 changes: 3 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"semi": true,
"singleQuote": false,
"useTabs": false,
"printWidth": 120
"printWidth": 120,
"endOfLine": "lf",
"trailingComma": "all"
}
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["EditorConfig.EditorConfig", "esbenp.prettier-vscode", "mikestead.dotenv", "prisma.prisma"]
}
14 changes: 14 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "yarn compile",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
693 changes: 19 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

54 changes: 20 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
# Meteorium

A Discord bot developed by RadiatedExodus (RealEthanPlayzDev) as a side (and personal) project, written in Javascript using Node.js and Discord.js, also being used as a way for me to learn JavaScript and TypeScript.
This is a hobby Discord bot I've written, the bot is only used for a few servers.
Feel free to look around, make suggestion, and report bugs.

Since the ts rewrite, some of the source might ressemble [PojavBot](https://github.com/PojavLauncherTeam/PojavBot) as I took several references from there.

## UNSTABLE - THIS IS A FULL REWRITE
## FULL REWRITE (v3)

This branch is a full rewrite, not all features have been implemented!

## Feature parity with v2

- [*] Moderation
- [ ] Music
- [ ] Info
- [ ] HolodexAPI
- [ ] MojangAPI
- [ ] RbxAPI
- [ ] ServerInfo
- [ ] UserInfo
- [ ] Tag
- [ ] Ping

## Installing required dependencies

Ensure `yarn` is installed (`npm install --global yarn`), then just run it at the root of the repository
Meteorium uses `yarn` to manage Node packages. Ensure `yarn` is installed (`npm install --global yarn`), then just run it at the root of the repository

```
yarn
Expand All @@ -33,34 +45,8 @@ yarn start

## Configuration file

The configuration file uses `dotenv`, create a file named ".ENV" on the project root and use the following example:

```
METEORIUMBOTTOKEN=bot_token_here
METEORIUMPOSTGRESURL=postgres_url_here
METEORIUMHOLODEXTOKEN=holodex_token_here_optional
METEORIUMAPPLICATIONID=bot_app_id_here
RATELIMITMAXLIMIT=rate_limit_maximum_limit_before_nodejs_terminates_PUT_A_NUMBER_HERE
RATELIMITMAXLIMITTIME=after_when_should_ratelimit_reset_PUT_A_NUMBER_HERE
DEPLOYGUILDIDS=guildids_for_deployment_seperated_by,commas,and_so_on
GENIUSAPIKEY=genius_api_key_here
```

## Credits

- [discord.js](https://github.com/discordjs/discord.js)
- [holodex.js](https://github.com/HolodexNet/holodex.js)
- [noblox.js](https://github.com/noblox/noblox.js)
- [Prisma](https://www.prisma.io)
- [dotenv](https://github.com/motdotla/dotenv)
See the `.env.example`

## Acknowledgements
## Special thanks

- All discord.js contributors and authors
- All holodex.js contributors and authors
- All noblox.js contributors and authors
- All mongodb contributors and authors
- All dotenv contributors and authors
- All Prisma contributors and authors
- All PostgreSQL contributors and authors
- Syjalo
- [@Abdelrahmanwalidhassan's `ms` fork](https://github.com/Abdelrahmanwalidhassan/ms)
40 changes: 18 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,47 +1,43 @@
{
"name": "meteorium",
"version": "2.0.0",
"description": "A Discord bot created by RadiatedExodus as a hobby project.",
"version": "3.0.0",
"description": "RadiatedExodus's hobby Discord bot project, built with TypeScript, Prisma, and DiscordJS.",
"main": "dist/index.js",
"type": "module",
"scripts": {
"compile": "tsc",
"start": "node --enable-source-maps --es-module-specifier-resolution=node ."
"start": "node dist",
"installUtils:fillMissingGuildData": "node ./dist/installUtils/fillMissingGuildData.js",
"installUtils:enableGuildFeature": "node ./dist/installUtils/enableGuildFeature.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RealEthanPlayzDev/Meteorium.git"
},
"author": "RadiatedExodus",
"license": "GPL-3.0",
"license": "MIT",
"bugs": {
"url": "https://github.com/RealEthanPlayzDev/Meteorium/issues"
},
"homepage": "https://github.com/RealEthanPlayzDev/Meteorium#readme",
"homepage": "https://github.com/RealEthanPlayzDev/Meteorium",
"devDependencies": {
"prettier": "3.0.3",
"prisma": "^5.2.0",
"typescript": "^5.1.6"
"@types/node": "^20.11.17",
"prettier": "^3.2.5",
"prisma": "^5.9.1",
"typescript": "^5.3.3"
},
"dependencies": {
"@discord-player/extractor": "^4.4.6",
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.16.1",
"@prisma/client": "^5.9.1",
"@types/ms": "^0.7.32",
"axios": "^1.6.3",
"chalk": "4.0.0",
"discord-player": "^6.6.7",
"bufferutil": "^4.0.8",
"chalk": "^5.3.0",
"discord.js": "^14.14.1",
"dotenv": "^16.0.3",
"dotenv": "^16.4.2",
"holodex.js": "^2.0.5",
"libsodium-wrappers": "^0.7.10",
"moment": "^2.29.4",
"ms": "^2.1.3",
"moment": "^2.30.1",
"noblox.js": "^4.15.1",
"play-dl": "^1.9.7",
"soundcloud-scraper": "^5.0.3",
"spotify-url-info": "^3.2.13",
"youtube-sr": "^4.3.10",
"ytdl-core": "^4.11.5"
"utf-8-validate": "^6.0.3",
"zlib-sync": "^0.1.9"
}
}
78 changes: 48 additions & 30 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ generator client {

datasource db {
provider = "postgresql"
url = env("METEORIUMPOSTGRESURL")
}

model Guild {
GuildId String @unique
EnforceSayInExecutor Boolean @default(false)
DisabledCommands String[] @default([])
DisabledCommandCategories String[] @default([])
PublicModLogChannelId String @default("")
LoggingChannelId String @default("")
JoinLeaveLogChannelId String @default("")
CurrentCaseId Int @default(0)
BanAppealLink String @default("")
url = env("METEORIUM_POSTGRES_URL")
}

enum ModerationAction {
Expand All @@ -31,49 +19,79 @@ enum ModerationAction {
Unban
}

enum GuildFeatures {
Moderation
UserVerification
Tags
Music
DiscordInfo
HolodexAPI
MojangAPI
RobloxAPI
}

model Guild {
GuildId String @unique
EnforceSayInExecutor Boolean @default(false)
JoinLeaveLogChannelId String @default("")
PublicModLogChannelId String @default("")
LoggingChannelId String @default("")
BanAppealLink String @default("")
EnabledGuildFeatures GuildFeatures[]
ModerationCase ModerationCase[]
Tag Tag[]
}

model ModerationCase {
GlobalCaseId Int @id @default(autoincrement())
Guild Guild @relation(fields: [GuildId], references: [GuildId], onDelete: Cascade)
GuildId String
CaseId Int
Action ModerationAction
TargetUserId String
ModeratorUserId String
GuildId String
Reason String
AttachmentProof String
AttachmentProof String @default("")
Duration String @default("0")
CreatedAt DateTime @default(now())
ModeratorNote String @default("")
ModeratorAttachment String @default("")
NotAppealable Boolean @default(false)
Active Boolean @default(true) // Used in ban
RelatedCaseId Int @default(-1) // Used in ban, does NOT use GlobalCaseId
PublicModLogMsgId String @default("")
CreatedAt DateTime @default(now())
ActiveTempBans ActiveTempBans[]
ModerationCaseHistory ModerationCaseHistory[]
}

model Tag {
GlobalTagId Int @id @default(autoincrement())
TagName String
GuildId String
Content String
Image String
}

model ActiveTempBans {
ActiveTempBanId Int @id @default(autoincrement())
GlobalCaseId Int
Case ModerationCase @relation(fields: [GlobalCaseId], references: [GlobalCaseId], onDelete: Cascade)
@@unique(name: "UniqueCaseIdPerGuild", fields: [GuildId, CaseId])
}

model ModerationCaseHistory {
ModerationCaseHistoryId Int @id @default(autoincrement())
ModerationCase ModerationCase @relation(fields: [GlobalCaseId], references: [GlobalCaseId], onDelete: Cascade)
GlobalCaseId Int
EditedAt DateTime @default(now())
Editor String
EditorUserId String
Reason String?
AttachmentProof String?
Duration String?
ModeratorNote String?
ModeratorAttachment String?
NotAppealable Boolean?
Removed Boolean?
}

model ActiveTempBans {
ActiveTempBanId Int @id @default(autoincrement())
GlobalCaseId Int @unique
Case ModerationCase @relation(fields: [GlobalCaseId], references: [GlobalCaseId], onDelete: Cascade)
}

model Tag {
GlobalTagId Int @id @default(autoincrement())
Guild Guild @relation(fields: [GuildId], references: [GuildId], onDelete: Cascade)
GuildId String
TagName String
Content String
Attachment String @default("")
}
63 changes: 63 additions & 0 deletions src/classes/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Client, ClientOptions } from "discord.js";
import { config } from "dotenv";
import { PrismaClient } from "@prisma/client";
import { HolodexApiClient } from "holodex.js";

import Logging from "./logging.js";
import MeteoriumInteractionManager from "../interactions/index.js";
import MeteoriumEventManager from "../events/index.js";
import MeteoriumDatabaseUtilities from "./dbUtils.js";
import MeteoriumGuildFeatureManager from "./guildFeatureManager.js";

function parseDotEnvConfig() {
if (!process.env.METEORIUM_BOT_TOKEN) config();
return {
BotToken: String(process.env.METEORIUM_BOT_TOKEN),
ApplicationId: String(process.env.METEORIUM_APPLICATION_ID),
HolodexApiKey: String(process.env.METEORIUM_HOLODEX_APIKEY),
GeniusApiKey: String(process.env.METEORIUM_GENIUS_APIKEY),
ApplicationDeployGuildIds: String(process.env.METEORIUM_APPDEPLOY_GUILDIDS).split(","),
RuntimeLogChannelIds: String(process.env.METEORIUM_RUNTIMELOG_CHANNELIDS).split(","),
DontRegisterTestInteractions: Boolean(process.env.METEORIUM_NOREG_TESTINTERACTIONS),
};
}

export default class MeteoriumClient extends Client<true> {
public logging = new Logging("Meteorium");
public config = parseDotEnvConfig();
public db = new PrismaClient();
public dbUtils = new MeteoriumDatabaseUtilities(this);
public guildFeatures = new MeteoriumGuildFeatureManager(this);
public interactions = new MeteoriumInteractionManager(this);
public events = new MeteoriumEventManager(this);
public holodex = new HolodexApiClient({ apiKey: this.config.HolodexApiKey });

public constructor(options: ClientOptions) {
super(options);

// Register all events and hook them
this.events.register();

// Register all interactions
this.interactions.registerAllInteractions();

return this;
}

public async login() {
const loginNS = this.logging.getNamespace("Login");

// Hook events
this.events.hook();

// Login
loginNS.info("Logging in to Discord");
return super.login(this.config.BotToken);
}

public async destroy() {
await super.destroy();
await this.db.$disconnect();
return;
}
}
Loading
Loading