You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+3-21Lines changed: 3 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,15 +7,14 @@ Thank you for your interest in contributing to TitanBot! This guide covers local
7
7
- Bug fixes and reliability improvements
8
8
- New commands or enhancements to existing features
9
9
- Documentation updates
10
-
- Test coverage for behavior that is easy to regress
11
10
12
11
Before starting large features, open an issue or discuss in the [support server](https://discord.gg/8kJBYhTGW9) so we can align on scope and avoid duplicate work.
13
12
14
13
## Getting Started
15
14
16
15
### Prerequisites
17
16
18
-
-**Node.js 18+** (CI uses Node 20)
17
+
-**Node.js 20+** (Docker and CI use Node 20)
19
18
-**PostgreSQL** (recommended for development; the bot can fall back to in-memory storage if PostgreSQL is unavailable)
20
19
- A **Discord bot application** with the intents listed in [README.md](README.md#required-bot-intents)
21
20
@@ -46,31 +45,14 @@ For Docker-based setup, see [README.md](README.md#docker-deployment-recommended)
46
45
47
46
1.**Fork the repository** and create a branch from `main`.
48
47
2.**Make focused changes** — one logical change per pull request when possible.
49
-
3.**Run tests** before opening a PR (see below).
50
-
4.**Open a pull request** with a clear description of what changed and why.
48
+
3.**Open a pull request** with a clear description of what changed and why.
51
49
52
50
Use descriptive branch names, for example:
53
51
54
52
-`fix/ticket-panel-refresh`
55
53
-`feat/economy-shop-filter`
56
54
-`docs/contributing-guide`
57
55
58
-
## Running Tests
59
-
60
-
Tests use Node's built-in test runner:
61
-
62
-
```bash
63
-
npm test
64
-
```
65
-
66
-
Test files live in `tests/` and follow the `*.test.js` naming pattern. When adding or changing behavior, add or update tests for:
67
-
68
-
- Permission checks and command access rules
69
-
- Parsing, validation, and utility logic
70
-
- UI/panel builders and status helpers
71
-
72
-
CI runs `npm test` on every pull request and on pushes to `main` and `master`. A separate workflow also validates database migrations against PostgreSQL when migration-related code changes.
73
-
74
56
## Database & Migrations
75
57
76
58
TitanBot uses PostgreSQL as its primary store. If PostgreSQL is unreachable at startup, the bot can operate in a **degraded in-memory mode** — but that mode is not suitable for production and should not be the only way you test persistence-related changes.
@@ -91,7 +73,7 @@ Test features that read or write guild data with **both** PostgreSQL and the mem
91
73
92
74
-**Match existing style** — ES modules (`import`/`export`), async/await, and the conventions used in neighboring files.
93
75
-**Handle errors gracefully** — catch failures, log with context, and send user-friendly embed replies where appropriate.
94
-
-**Avoid breaking guild isolation** — guild-specific config and data must stay scoped per server, especially when `MULTI_GUILD=true`.
76
+
-**Avoid breaking guild isolation** — guild-specific config and data must stay scoped per server (`guild:{guildId}:...` keys, `interaction.guildId`).
95
77
-**Keep changes minimal** — prefer extending existing utilities and services over duplicating logic.
96
78
-**Document user-facing behavior** — update README.md when setup steps or configuration change; mention new env vars in `.env.example`.
Copy file name to clipboardExpand all lines: README.md
+28-17Lines changed: 28 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -109,28 +109,38 @@ TitanBot is fully containerized for easy deployment.
109
109
```
110
110
111
111
2.**Configure environment variables:**
112
-
Create a `.env` file from `.env.example` and fill in your bot details and PostgreSQL credentials.
112
+
```bash
113
+
cp .env.example .env
114
+
```
115
+
Set at minimum `DISCORD_TOKEN`, `CLIENT_ID`, and `GUILD_ID`. Docker Compose also reads `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` from `.env` (defaults: `titanbot` / `password` / `titanbot`).
113
116
114
-
3.**Start the containers:**
117
+
3.**Build and start the containers:**
115
118
```bash
116
-
docker-compose up -d
119
+
dockercompose up -d --build
117
120
```
118
121
119
-
This will start the bot, PostgreSQL, and Lavalink (when music is enabled).
122
+
4.**Check status:**
123
+
```bash
124
+
docker compose ps
125
+
curl http://localhost:3000/health
126
+
```
127
+
128
+
This starts the bot and PostgreSQL. The compose file sets `POSTGRES_SSL=false` and `AUTO_MIGRATE=true` for the bundled database. Music uses public Lavalink v4 nodes from `lavalink/nodes.json` by default.
120
129
121
130
### Music
122
131
123
132
Music uses [Lavalink v4](https://github.com/lavalink-devs/Lavalink) via [Riffy](https://github.com/riffy-rb/riffy), similar to [Musicify](https://github.com/codebymitch/Musicify).
124
133
125
-
1. Set in `.env`:
134
+
1. By default, the bot loads multiple public v4 SSL nodes from [`lavalink/nodes.json`](lavalink/nodes.json) (sourced from [lavalink.darrennathanael.com](https://lavalink.darrennathanael.com/SSL/Lavalink-SSL/)). Edit that file to add or remove nodes.
135
+
2. To self-host Lavalink instead, run `docker compose --profile local-lavalink up -d` and set single-node env vars in `.env`:
126
136
```env
127
137
LAVALINK_HOST=lavalink
128
138
LAVALINK_PORT=2333
129
139
LAVALINK_PASSWORD=youshallnotpass
130
140
LAVALINK_SECURE=false
131
141
```
132
-
2. With Docker Compose, Lavalink is included automatically when you `docker compose up`.
133
-
3.On Railway, deploy Lavalink separately or as another service and point `LAVALINK_HOST`at the private hostname.
142
+
Remove or rename `lavalink/nodes.json` so the bot falls back to those env vars.
143
+
3.Override nodes inline with `LAVALINK_NODES` (JSON array) or point at another file with `LAVALINK_NODES_FILE`.
134
144
4. Use `/play <song>` from a voice channel, or `/join` to connect without playing. Prefix shortcuts: `join`, `np`, `leave`, `pause`, `resume`, `skip`, `stop`, `volume <0-100>`, or `music <subcommand>`. Use `/nowplaying` and `/queue` for status; `/music` for loop, shuffle, seek, and other controls.
This gives clear startup/online status messages while keeping logs simple for non-technical operators.
203
213
If port `3000` is busy, the bot tries the next available ports automatically (up to `PORT_RETRY_ATTEMPTS`).
204
214
205
-
### Running in multiple servers (optional)
206
-
207
-
Most users run TitanBot on a **single server** with `GUILD_ID` set (default tutorial setup). If you want commands to work in **every server** the bot is invited to, opt in with:
215
+
### Multiple servers
208
216
209
-
```env
210
-
MULTI_GUILD=true
211
-
```
217
+
Slash commands are registered **globally** on startup (via `CLIENT_ID`), so the bot works in every server it is invited to. `GUILD_ID` stays in the tutorial `.env` for setup steps but is not used for command registration.
212
218
213
-
Notes for multi-server mode:
214
-
-`GUILD_ID` is not used for command registration when `MULTI_GUILD=true` (you can leave it set or remove it)
219
+
Notes:
215
220
- Global slash commands may take up to about an hour to propagate on first deploy
216
-
- Each server still has **isolated** config, economy, tickets, leveling, and other data
221
+
- Each server has **isolated**data: config, economy, tickets, leveling, dashboards, warnings, etc. (all keys are scoped as `guild:{guildId}:...`)
217
222
- In the [Discord Developer Portal](https://discord.com/developers/applications), ensure your bot is not restricted to a single guild if you plan to invite it elsewhere
218
223
- Generate an OAuth2 invite URL from the [Discord Developer Portal](https://discord.com/developers/applications) (OAuth2 → URL Generator, scopes: `bot` and `applications.commands`)
219
224
@@ -235,6 +240,12 @@ Notes for multi-server mode:
235
240
```bash
236
241
npm start
237
242
```
243
+
244
+
> **Note on database migrations:** Schema tables and legacy key migrations run
245
+
> **automatically on startup**, so` managed hosts like **Railway** need no manual
246
+
> migration step — just deploy/restart. To disable auto-migration set
247
+
> `AUTO_MIGRATE=false`. You can still run a manual key migration locally with
248
+
> `node scripts/migrate-keys.js --dry-run` (preview) or `node scripts/migrate-keys.js`.
0 commit comments