137 lines
4.4 KiB
Markdown
137 lines
4.4 KiB
Markdown
# Joel Discord Bot
|
|
|
|
A Discord bot with AI-powered responses and message tracking.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Install dependencies
|
|
bun install
|
|
|
|
# Set environment variables
|
|
cp .env.example .env
|
|
# Edit .env with your tokens
|
|
|
|
# Run in development mode
|
|
bun run dev
|
|
|
|
# Run in production
|
|
bun run start
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
See [src/README.md](src/README.md) for detailed architecture documentation.
|
|
|
|
```
|
|
src/
|
|
├── core/ # Bot client, config, logging
|
|
├── commands/ # Slash commands
|
|
├── events/ # Discord event handlers
|
|
├── features/ # Feature modules (Joel AI, message logging)
|
|
├── services/ # External services (AI providers)
|
|
├── database/ # Database schema and repositories
|
|
└── utils/ # Shared utilities
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Description |
|
|
| ----------------------- | --------------------------------------- |
|
|
| `DISCORD_TOKEN` | Discord bot token |
|
|
| `DISCORD_CLIENT_ID` | Discord application client ID |
|
|
| `DISCORD_CLIENT_SECRET` | Discord application client secret |
|
|
| `OPENROUTER_API_KEY` | OpenRouter API key for AI |
|
|
| `FAL_API_KEY` or `FAL_KEY` | Fal API key for image generation |
|
|
| `AI_CLASSIFICATION_FALLBACK_MODELS` | Comma-separated fallback model IDs for classification requests |
|
|
| `KLIPY_API_KEY` | Klipy API key for GIF search (optional) |
|
|
| `ELEVENLABS_API_KEY` | ElevenLabs API key for voiceover |
|
|
| `ELEVENLABS_VOICE_ID` | Default ElevenLabs voice ID (optional) |
|
|
| `ELEVENLABS_MODEL` | ElevenLabs model ID (default: `eleven_multilingual_v2`) |
|
|
| `DATABASE_PATH` | SQLite file path (default: `./data/db.sqlite3`) |
|
|
| `WEB_PORT` | Port for web dashboard (default: 3000) |
|
|
| `WEB_BASE_URL` | Base URL for web dashboard |
|
|
| `SESSION_SECRET` | Secret for session encryption |
|
|
|
|
## Data Persistence
|
|
|
|
- Bot options and other runtime state are stored in SQLite.
|
|
- Keep `DATABASE_PATH` on persistent storage so updates/redeploys do not reset settings.
|
|
- Backward compatibility: if `DATABASE_PATH` is unset and `src/database/db.sqlite3` exists, it is used automatically.
|
|
- Recommended one-time migration:
|
|
|
|
```bash
|
|
mkdir -p data && cp src/database/db.sqlite3 data/db.sqlite3
|
|
```
|
|
- Docker example:
|
|
|
|
```bash
|
|
docker run -d \
|
|
--name joel-discord \
|
|
-v joel_data:/data \
|
|
--env-file .env \
|
|
your-image:latest
|
|
```
|
|
|
|
## Docker
|
|
|
|
Build the image:
|
|
|
|
```bash
|
|
docker build -t ghcr.io/your-org/joel-bot:latest .
|
|
```
|
|
|
|
Run it locally:
|
|
|
|
```bash
|
|
docker run -d \
|
|
--name joel-bot \
|
|
-p 3000:3000 \
|
|
-v joel_data:/data \
|
|
--env-file .env \
|
|
ghcr.io/your-org/joel-bot:latest
|
|
```
|
|
|
|
The container now starts in production mode and does not enable the CSS file watcher.
|
|
|
|
## k3s
|
|
|
|
The repo includes starter manifests in [`k8s/deployment.yaml`](/Users/eric/Projects/joel-discord/k8s/deployment.yaml), [`k8s/secret.example.yaml`](/Users/eric/Projects/joel-discord/k8s/secret.example.yaml), and [`k8s/ingress.example.yaml`](/Users/eric/Projects/joel-discord/k8s/ingress.example.yaml).
|
|
|
|
Typical flow:
|
|
|
|
```bash
|
|
# Build and push the image
|
|
docker build -t ghcr.io/your-org/joel-bot:latest .
|
|
docker push ghcr.io/your-org/joel-bot:latest
|
|
|
|
# Create your secret manifest from the example and fill in real values
|
|
cp k8s/secret.example.yaml k8s/secret.yaml
|
|
|
|
# Apply namespace, PVC, deployment, and service
|
|
kubectl apply -f k8s/deployment.yaml
|
|
kubectl apply -f k8s/secret.yaml
|
|
|
|
# Optional if you want the web UI exposed through Traefik
|
|
kubectl apply -f k8s/ingress.example.yaml
|
|
```
|
|
|
|
Notes:
|
|
|
|
- Update the image in `k8s/deployment.yaml` to your registry path.
|
|
- Set `WEB_BASE_URL` in the secret to the public HTTPS URL you expose through ingress.
|
|
- The deployment mounts `/data` on a PVC and stores SQLite at `/data/db.sqlite3`.
|
|
- k3s usually provisions the PVC automatically via the default `local-path` storage class.
|
|
|
|
## Scripts
|
|
|
|
| Script | Description |
|
|
| --------------------- | --------------------------- |
|
|
| `bun run dev` | Development with hot reload |
|
|
| `bun run start` | Production start |
|
|
| `bun run build` | Build for production |
|
|
| `bun run db:generate` | Generate DB migrations |
|
|
| `bun run db:migrate` | Run DB migrations |
|
|
| `bun run db:studio` | Open Drizzle Studio |
|
|
| `bun run typecheck` | Type check without emit |
|