docs(bots/discord): add docs

This commit is contained in:
PalmDevs
2024-03-29 17:26:04 +07:00
parent 9f1ac37927
commit b104472e47
6 changed files with 369 additions and 0 deletions

View File

@@ -66,7 +66,13 @@ export type ConfigMessageScanResponse = {
}
export type ConfigMessageScanResponseLabelConfig = {
/**
* Label name
*/
label: string
/**
* Confidence threshold
*/
threshold: number
}

View File

@@ -0,0 +1,124 @@
# ⚙️ Configuration
This is the default configuration (provided in [config.ts](../config.ts)):
```ts
export default {
owners: ["USER_ID_HERE"],
allowedGuilds: ["GUILD_ID_HERE"],
messageScan: {
channels: ["CHANNEL_ID_HERE"],
roles: ["ROLE_ID_HERE"],
users: ["USER_ID_HERE"],
whitelist: false,
humanCorrections: {
falsePositiveLabel: "false_positive",
allowUsers: ["USER_ID_HERE"],
memberRequirements: {
permissions: 8n,
roles: ["ROLE_ID_HERE"],
},
},
allowedAttachmentMimeTypes: ["image/jpeg", "image/png", "image/webp"],
responses: [
{
triggers: [/^regexp?$/, { label: "label", threshold: 0.85 }],
response: {
title: "Embed title",
description: "Embed description",
fields: [
{
name: "Field name",
value: "Field value",
},
],
},
},
],
},
logLevel: "log",
api: {
websocketUrl: "ws://127.0.0.1:3000",
},
} as Config;
```
This may look very overwhelming but configurating it is pretty easy.
---
### `config.owners`
User IDs of the owners of the bot. They'll be able to execute specific commands that others can't and take control of the bot.
### `config.allowedGuilds`
Servers the bot is allowed to be and register commands in. The bot will leave servers that are not in this list automatically once detected.
### `config.logLevel`
The level of logs to print to console. If the level is more important or equally important to set level, it will be forwarded to the console.
The possible levels (sorted by their importance descendingly) are:
- `none`
- `fatal`
- `error`
- `warn`
- `info`
- `log`
- `debug`
### `config.api.websocketUrl`
The WebSocket URL to connect to (including port).
### `config.messageScan`
Message scan configuration.
##### `config.messageScan.roles` & `config.messageScan.users` & `config.messageScan.channels`
Roles, users, and channels which will be affected by the blacklist/whitelist rule.
##### `config.messageScan.whitelist`
Whether to use whitelist (`true`) or blacklist (`false`) mode.
- Blacklist mode **will refuse** to scan messages of any roles or users who **are** in the list above.
- Whitelist mode **will refuse** to scan messages of any roles or users who **aren't** in the list above.
##### `config.messageScan.responses`
An array containing response configurations. A response can be triggered by multiple ways[^1], which can be specified in the `response.triggers` field.
The `response` field contains the embed data that the bot should send. If it is set to `null`, the bot will not send a response or delete the current response if editing.
```ts
{
triggers: [
/cool regex/i,
{
label: 'some_label',
threshold: 0.8,
},
],
response: {
title: 'Embed title',
description: 'Embed description',
fields: [
{
name: 'Field name',
value: 'Field value',
},
],
}
}
```
[^1]: Possible triggers are regular expressions or [label configurations](../config.example.ts#68).
## ⏭️ What's next
The next page will tell you how to run and bundle the bot.
Continue: [🏃🏻‍♂️ Running the bot](./2_running.md)

View File

@@ -0,0 +1,24 @@
# 🏃🏻‍♂️ Running the bot
There are two methods to run the bot. Choose one that suits best for the situation.
## 👷🏻 Development mode (recommended)
There will be no compilation step, and Bun will automatically watch changes and restart the bot for you.
You can quickly start the bot by running:
```sh
bun dev
```
## 📦 Building
There's unfortunately no way to build/bundle the bot yet due to how dynamic imports currently work, though we have a few ideas that may work.
As a workaround, you can zip up the whole project, unzip, and run it in development mode using Bun.
## ⏭️ What's next
The next page will tell you how to add commands and listen to events to the bot.
Continue: [✨ Adding commands and listening to events](./3_commands_and_events.md)

View File

@@ -0,0 +1,110 @@
# ✨ Adding commands and listening to events
Adding commands and listening to new events is easy once you learn the project's structure.
## 🗄️ Project structure
In the source directory, you'll find multiple other directories:
- [Commands](#💬-commands) are located in `src/commands`
- [Events](#🚩-events) are located in `src/events`
- [Utility functions](../src/utils) are located in `src/utils`
You'll also find multiple files:
- [`index.ts`](../src/index.ts) is the entry of the bot
- [`context.ts`](../src/context.ts) is the context object that will be referenced in multiple places
## 💬 Commands
> [!IMPORTANT]
> You are currently developing with the temporary system which isn't very great in terms of development experience.
> A new system will be made and pushed soon and all commands will be migrated to it.
If you feel the need to categorize commands into directories, you absolutely can, as the system does not restrict subdirectories.
You can start developing commands with this template:
```ts
// src/commands/my-command.ts
import { SlashCommandBuilder } from "discord.js";
import type { Command } from ".";
export default {
data: new SlashCommandBuilder()
.setName("my-command")
.setDescription("My cool command")
// Allowing this command to be used in DMs
.setDMPermission(true)
// DO NOT forget this line!
.toJSON(),
// Member requirements, will only apply to
memberRequirements: {
// Match mode, can be `all` or `any` (`all` by default)
// - All mode means all of the following conditions have to match
// - Any mode means one of the following conditions have to match
mode: "all",
// This will always match in Any mode, which means the member must have one of these roles to pass
roles: ["955220417969262612", "973886585294704640"],
// Permissions required to execute this command
// -1n means bot owners only (default for security reasons)
permissions: -1n,
},
// Whether this command should be able to be executed by only bot owners
// (true by default)
ownerOnly: false,
// Whether to register this command globally
// This is turned off by default for security reasons
global: true,
// What to do when this command executes
async execute(_context, interaction) {
await interaction.reply({
content: "Hello!",
});
},
} satisfies Command;
```
## 🚩 Events
Events are a bit different. We have 2 different event systems for both Discord API and our own bot API. This means the [`src/events`](../src/events) directory will have 2 separate directories inside. They are specific to the respective API, but the utility functions make the experience with both of them very similar.
To start adding events, you can use this template:
```ts
// For Discord events (remove functions you do not use)
import { on, once } from '$utils/discord/events'
// You will have auto-complete and types for all of them, don't worry!
// WARNING: The first argument is the `context` object for Discord events
// This is intended by design because Discord events usually always use it.
on('eventName', async (context, arg1, arg2, ...) => {
// Do something in here when the event is triggered
})
```
```ts
// For "Helper" events (remove functions you do not use)
import { on, once } from '$utils/api/events'
// You will have auto-complete and types for all of them, don't worry!
on('eventName', async (arg1, arg2, ...) => {
// Do something in here when the event is triggered
})
```
API events are stored in [`src/events/api`](../src/events/api), and Discord events are in [`src/events/discord`](../src/events/discord).
> [!NOTE]
> If you need multiple event listeners for the same exact event, you can put them in a directory with the event name and rename the listeners to what they handle specifically. You can see how we do it in [`src/events/discord/interactionCreate`](../src/events/discord/interactionCreate).
## ⏭️ What's next
The next page will tell you how to create and interact with a database.
Continue: [🫙 Storing data](./4_databases.md)

View File

@@ -0,0 +1,88 @@
# 🫙 Storing data
We use SQLite to store every piece of persistent data. By using Bun, we get access to the `bun:sqlite` module which allows us to easily do SQLite operations.
## 🪄 Creating a database
You can easily create a database by initializing the `BasicDatabase` class:
```ts
interface MyDatabase {
field: string
key: string
}
const db = new BasicDatabase<MyDatabase>(
// File path
'database_file.db',
// Database schema, in SQL
`field TEXT NOT NULL, key TEXT PRIMARY KEY NOT NULL`,
// Custom table name (optional, defaults to 'data'),
'data'
)
```
## 📝 Writing data
Initializing `MyDatabase` will immediately create/open the `database_file.db` file. To write data, you can use the `insert` or `update` method:
```ts
const key = 'my key'
const field = 'some data'
// Order is according to the schema
// db.insert(...columns)
db.insert(field, key)
const field2 = 'some other data'
// db.update(data, filter)
db.update({
field: field2
}, `key = ${key}`)
```
You can also delete a row:
```ts
db.delete(`key = ${key}`)
console.log(db.select(`key = ${key}`)) // null
```
## 👀 Reading data
To get data using a filter, you can use the `select` method:
```ts
// We insert it back
db.insert(field, key)
const data = db.select('*', `key = ${key}`)
console.log(data) // { key: 'my key', field: 'some other data' }
const { key: someKey } = db.select('key', `field = '${field2}'`)
console.log(someKey) // 'my key'
```
If the existing abstractions aren't enough, you can also use the `run`, `prepare`, or `query` method:
```ts
// Enable WAL
db.run('PRAGMA journal_mode=WAL')
const selectFromKey = db.prepare('SELECT * FROM data WHERE key = $key')
console.log(
selectFromKey.get({
$key: key
})
) // { key: 'my key', field: 'some other data' }
console.log(
selectFromKey.get({
$key: 'non existent key'
})
) // null
```

View File

@@ -0,0 +1,17 @@
# 🤖 ReVanced Discord Bot
This documentation explains how to start developing, and how to configure the bot.
## 📖 Table of contents
0. [🏗️ Set up the development environment (if you haven't already)](../../../docs/0_development_environment.md)
1. [⚙️ Configuration](./1_configuration.md)
2. [🏃🏻‍♂️ Running the server](./2_running.md)
3. [🗣️ Command and events](./3_commands_and_events.md)
4. [🫙 Storing data](./4_databases.md)
## ⏭️ Start here
The next page will tell you how to configure the bot.
Continue: [⚙️ Configuration](./1_configuration.md)