Moderation Update
This commit is contained in:
407
README.md
407
README.md
@@ -1,320 +1,161 @@
|
||||
# ECS Full Stack
|
||||
|
||||
A full-stack example project that integrates a React frontend, an Express backend, and a Discord bot. The app provides a dashboard for server admins to manage bot settings and invites, plus Discord moderation/integration features via a bot running with discord.js.
|
||||
A full-stack Discord bot management dashboard with React frontend, Express backend, and Discord.js bot integration. Server admins can manage bot settings, invites, moderation, and live notifications through a modern web interface.
|
||||
|
||||
This README documents how to get the project running, what environment variables are required, where to get Discord keys, how the invite token flow works, and basic troubleshooting tips.
|
||||
## Features
|
||||
|
||||
Note: The backend has been updated to support Postgres persistence (see `CHANGELOG.md`). The backend now requires `DATABASE_URL` to run in the default configuration; if you prefer the legacy encrypted file store, see the notes under "Developer notes".
|
||||
- **Dashboard**: View Discord servers and manage per-server settings
|
||||
- **Invite Management**: Create, list, and revoke server invites with custom options
|
||||
- **Moderation**: Direct ban/kick/timeout actions from web interface with user autocomplete
|
||||
- **Live Notifications**: Twitch stream notifications with rich embeds
|
||||
- **Admin Logs**: Complete moderation action logging with real-time updates
|
||||
- **Theme Support**: Light, dark, and Discord-themed UI options
|
||||
|
||||
## Repository layout
|
||||
## Quick Start
|
||||
|
||||
- `frontend/` — React (Create React App) frontend. Uses `REACT_APP_API_BASE` to communicate with the backend in dev and production.
|
||||
- `backend/` — Express backend and API server that also coordinates with the `discord-bot` library to manage guilds, invites, and settings. Uses environment variables for configuration.
|
||||
- `discord-bot/` — small wrapper that logs the bot in and exposes the discord.js client used by the backend.
|
||||
- `checklist.md`, `README.md`, other docs and small scripts at repo root.
|
||||
### Prerequisites
|
||||
- Node.js 18+
|
||||
- PostgreSQL database
|
||||
- Discord application with bot user
|
||||
|
||||
## What this project does
|
||||
### Setup
|
||||
|
||||
- Provides a React dashboard where a user can view servers the bot is connected to and manage per-server settings (welcome/leave messages, autorole, toggling commands, invite creation/listing/deletion).
|
||||
- Runs a Discord bot (discord.js) that performs moderation and server features. The backend and bot are closely integrated: the backend hosts the API and the bot client is shared to fetch guild data and manipulate invites/channels/roles.
|
||||
- Uses a short-lived token flow to authorize invite deletions from the frontend without embedding long-lived secrets in the client.
|
||||
1. **Clone and install dependencies:**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd ECS-FullStack
|
||||
npm install # Run in both frontend/ and backend/ directories
|
||||
```
|
||||
|
||||
Expanded: what this app does
|
||||
2. **Configure Discord App:**
|
||||
- Go to [Discord Developer Portal](https://discord.com/developers/applications)
|
||||
- Create new application and bot user
|
||||
- Copy Client ID, Client Secret, and Bot Token
|
||||
|
||||
- Hosts a dashboard (React) that lists Discord guilds where the bot is present and lets server admins:
|
||||
- create and manage invites (create invites with options, view persisted invites, copy and revoke)
|
||||
- configure Welcome and Leave messages and channels
|
||||
- enable/disable bot commands per server
|
||||
- set autorole behavior for new members
|
||||
- Provides a backend API (Express) that coordinates with a discord.js bot to perform live guild operations (fetch channels/roles, create invites, leave guilds)
|
||||
- Stores configuration and invites in Postgres (recommended) or a legacy encrypted `db.json`
|
||||
3. **Database Setup:**
|
||||
```sql
|
||||
CREATE DATABASE ecs_fullstack;
|
||||
CREATE USER ecs_user WITH PASSWORD 'your_password';
|
||||
GRANT ALL PRIVILEGES ON DATABASE ecs_fullstack TO ecs_user;
|
||||
```
|
||||
|
||||
## Quickstart — prerequisites
|
||||
4. **Environment Configuration:**
|
||||
|
||||
- Node.js (recommended 18.x or later) and npm
|
||||
- A Discord application with a Bot user (to get `DISCORD_CLIENT_ID` and `DISCORD_CLIENT_SECRET`) — see below for setup steps
|
||||
- Optional: a VPS or Tailscale IP if you want to run the frontend/backend on a non-localhost address
|
||||
**backend/.env:**
|
||||
```env
|
||||
DATABASE_URL=postgres://ecs_user:password@localhost:5432/ecs_fullstack
|
||||
DISCORD_CLIENT_ID=your_client_id
|
||||
DISCORD_CLIENT_SECRET=your_client_secret
|
||||
DISCORD_BOT_TOKEN=your_bot_token
|
||||
ENCRYPTION_KEY=your_32_byte_secret
|
||||
BACKEND_BASE=http://localhost:3002
|
||||
FRONTEND_BASE=http://localhost:3001
|
||||
```
|
||||
|
||||
## Environment configuration (.env)
|
||||
**frontend/.env:**
|
||||
```env
|
||||
REACT_APP_API_BASE=http://localhost:3002
|
||||
```
|
||||
|
||||
There are env files used by the backend and frontend. Create `.env` files in the `backend/` and `frontend/` folders for local development. Examples follow.
|
||||
5. **Start the application:**
|
||||
```bash
|
||||
# Backend (includes Discord bot)
|
||||
cd backend && npm start
|
||||
|
||||
### backend/.env (example)
|
||||
# Frontend (separate terminal)
|
||||
cd frontend && npm start
|
||||
```
|
||||
|
||||
PORT=3002
|
||||
HOST=0.0.0.0
|
||||
BACKEND_BASE=http://your-server-or-ip:3002
|
||||
FRONTEND_BASE=http://your-server-or-ip:3001
|
||||
CORS_ORIGIN=http://your-server-or-ip:3001
|
||||
DISCORD_CLIENT_ID=your_discord_client_id
|
||||
DISCORD_CLIENT_SECRET=your_discord_client_secret
|
||||
ENCRYPTION_KEY=a-32-byte-or-longer-secret
|
||||
INVITE_TOKEN_SECRET=optional-second-secret-for-invite-tokens
|
||||
6. **Invite Bot to Server:**
|
||||
- Use OAuth2 URL Generator in Discord Developer Portal
|
||||
- Select `bot` and `applications.commands` scopes
|
||||
- Choose appropriate permissions
|
||||
- Visit generated URL to invite bot
|
||||
|
||||
# Postgres example (optional but recommended)
|
||||
# DATABASE_URL=postgres://dbuser:dbpass@100.111.50.59:5432/ecs_db
|
||||
## Project Structure
|
||||
|
||||
- `PORT` / `HOST`: where the backend listens.
|
||||
- `BACKEND_BASE` and `FRONTEND_BASE`: used for constructing OAuth redirect URIs and links.
|
||||
- `CORS_ORIGIN`: optional; set to your frontend origin to restrict CORS.
|
||||
- `DISCORD_CLIENT_ID` / `DISCORD_CLIENT_SECRET`: from the Discord Developer Portal (see below).
|
||||
- `ENCRYPTION_KEY` or `INVITE_TOKEN_SECRET`: used to sign short-lived invite tokens. Keep this secret.
|
||||
|
||||
Note: This project previously supported an `INVITE_API_KEY` static secret; that requirement has been removed. Invite deletes are authorized via short-lived invite tokens by default.
|
||||
|
||||
### Twitch Live Notifications (optional)
|
||||
|
||||
This project can detect when watched Twitch users go live and post notifications to a configured Discord channel for each guild. To enable this feature, add the following to `backend/.env`:
|
||||
|
||||
- `TWITCH_CLIENT_ID` — your Twitch app client id
|
||||
- `TWITCH_CLIENT_SECRET` — your Twitch app client secret
|
||||
- `TWITCH_POLL_INTERVAL_MS` — optional, poll interval in milliseconds (default 30000)
|
||||
|
||||
When configured, the backend exposes:
|
||||
|
||||
- GET /api/twitch/streams?users=user1,user2 — returns stream info for the listed usernames (used by the frontend and bot watcher)
|
||||
|
||||
The bot includes a watcher that polls watched usernames per-guild and posts a message to the configured channel when a streamer goes live. The message includes the stream title and a link to the Twitch stream.
|
||||
|
||||
If you run the backend and the bot on separate hosts, you can configure the backend to push setting updates to the bot so toggles and watched users propagate immediately:
|
||||
|
||||
- `BOT_PUSH_URL` — the URL the bot will expose for the backend to POST setting updates to (e.g., http://bot-host:4002)
|
||||
- `BOT_SECRET` — a shared secret used by the backend and bot to secure push requests
|
||||
- `BOT_PUSH_PORT` — optional, the port the bot listens on for push requests (if set the bot starts a small HTTP receiver)
|
||||
|
||||
|
||||
### frontend/.env (example)
|
||||
|
||||
HOST=0.0.0.0
|
||||
PORT=3001
|
||||
REACT_APP_API_BASE=http://your-server-or-ip:3002
|
||||
|
||||
Set `REACT_APP_API_BASE` to point at the backend so the frontend can call API endpoints.
|
||||
|
||||
## Create a Discord Application and Bot (short)
|
||||
|
||||
1. Go to the Discord Developer Portal: https://discord.com/developers/applications
|
||||
2. Create a new application.
|
||||
3. Under "OAuth2" -> "General", add your redirect URI:
|
||||
- For dev: `http://your-server-or-ip:3002/auth/discord/callback`
|
||||
- Make sure `BACKEND_BASE` matches the host/port you set in `backend/.env`.
|
||||
4. Under "Bot" create a Bot user and copy the Bot token (NOT committed to source).
|
||||
5. Under "OAuth2" -> "URL Generator" select scopes `bot` and `applications.commands` and select permissions (e.g., Administrator if you want full access for testing). Use the generated URL to invite the bot to your guild during testing.
|
||||
|
||||
Store the Client ID / Client Secret in your `backend/.env` as `DISCORD_CLIENT_ID` and `DISCORD_CLIENT_SECRET`.
|
||||
|
||||
## Invite token flow (why and how)
|
||||
|
||||
- To avoid embedding long-lived secrets in a web client, invite deletions are authorized with a short-lived HMAC-signed token.
|
||||
- The frontend requests a token with:
|
||||
GET /api/servers/:guildId/invite-token
|
||||
- The backend returns `{ token: '...' }`. The frontend then calls
|
||||
DELETE /api/servers/:guildId/invites/:code
|
||||
with header `x-invite-token: <token>`
|
||||
- Token TTL is short (default 5 minutes) and is signed using `INVITE_TOKEN_SECRET` or `ENCRYPTION_KEY` from backend `.env`.
|
||||
|
||||
Security note: Currently the `/invite-token` endpoint issues tokens to any caller. For production you should restrict this endpoint by requiring OAuth authentication and checking that the requesting user is authorized for the target guild.
|
||||
|
||||
## Run the app locally
|
||||
|
||||
1. Backend
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
npm install
|
||||
# create backend/.env from the example above
|
||||
npm start
|
||||
```
|
||||
ECS-FullStack/
|
||||
├── frontend/ # React dashboard
|
||||
├── backend/ # Express API + Discord bot
|
||||
├── discord-bot/ # Bot wrapper
|
||||
├── checklist.md # Feature tracking
|
||||
└── README.md
|
||||
```
|
||||
|
||||
Optional: using Postgres (recommended)
|
||||
## API Endpoints
|
||||
|
||||
1. Create a Postgres database and user (pgAdmin or psql)
|
||||
2. Set `DATABASE_URL` in `backend/.env`, e.g.:
|
||||
DATABASE_URL=postgres://dbuser:dbpass@100.111.50.59:5432/ecs_db
|
||||
3. Start the backend; on startup the backend will create simple tables if missing.
|
||||
### Server Management
|
||||
- `GET /api/servers/:guildId` - Server info and settings
|
||||
- `GET /api/servers/:guildId/members` - Server member list
|
||||
- `GET /api/servers/:guildId/channels` - Text channels
|
||||
- `GET /api/servers/:guildId/roles` - Server roles
|
||||
|
||||
Migration note:
|
||||
- If you have existing data in `backend/db.json`, a migration script is planned to import invites and server settings into Postgres. I can add that script on request.
|
||||
### Invites
|
||||
- `GET /api/servers/:guildId/invites` - List invites
|
||||
- `POST /api/servers/:guildId/invites` - Create invite
|
||||
- `DELETE /api/servers/:guildId/invites/:code` - Delete invite
|
||||
|
||||
2. Frontend
|
||||
### Moderation
|
||||
- `POST /api/servers/:guildId/moderate` - Ban/kick/timeout users
|
||||
- `GET /api/servers/:guildId/admin-logs` - View moderation logs
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
npm install
|
||||
# create frontend/.env with REACT_APP_API_BASE pointing to the backend
|
||||
npm run start
|
||||
### Live Notifications
|
||||
- `GET/POST /api/servers/:guildId/live-notifications` - Settings
|
||||
- `GET/POST /api/servers/:guildId/twitch-users` - Watched users
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Required
|
||||
- `DATABASE_URL` - PostgreSQL connection string
|
||||
- `DISCORD_CLIENT_ID` - Discord app client ID
|
||||
- `DISCORD_CLIENT_SECRET` - Discord app client secret
|
||||
- `DISCORD_BOT_TOKEN` - Bot token
|
||||
|
||||
### Optional
|
||||
- `TWITCH_CLIENT_ID` - Twitch app client ID
|
||||
- `TWITCH_CLIENT_SECRET` - Twitch app client secret
|
||||
- `BOT_PUSH_URL` - For separate bot/backend deployment
|
||||
- `CORS_ORIGIN` - Restrict API access
|
||||
|
||||
## Development
|
||||
|
||||
### Running Tests
|
||||
```bash
|
||||
cd frontend && npm test
|
||||
cd backend && npm test
|
||||
```
|
||||
|
||||
3. Discord bot
|
||||
|
||||
- The backend boots the bot client (see `discord-bot/`), so if the backend is started and credentials are correct, the bot will log in and register slash commands. You can also run the `discord-bot` project separately if you prefer.
|
||||
### Building for Production
|
||||
```bash
|
||||
cd frontend && npm run build
|
||||
cd backend && npm run build # If applicable
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Backend refuses to start or missing package.json: ensure you run `npm install` in the `backend` folder and run `npm start` from that folder.
|
||||
- If the backend exits with "DATABASE_URL is not set": either set `DATABASE_URL` in `backend/.env` pointing to your Postgres DB, or restore the legacy behavior by editing `backend/index.js` to re-enable the encrypted `db.json` fallback (not recommended for production).
|
||||
- CORS errors: verify `CORS_ORIGIN` and `REACT_APP_API_BASE` match your frontend origin.
|
||||
- Invite delete unauthorized: ensure backend `INVITE_TOKEN_SECRET` or `ENCRYPTION_KEY` is present and token TTL has not expired. Check the backend logs for validation details.
|
||||
- Token issues: clock skew can cause tokens to appear expired — ensure server and client clocks are reasonably in sync.
|
||||
### Common Issues
|
||||
- **Database connection failed**: Verify `DATABASE_URL` format and credentials
|
||||
- **CORS errors**: Check `CORS_ORIGIN` matches your frontend URL
|
||||
- **Bot not responding**: Ensure bot has proper permissions in server
|
||||
- **Invite deletion fails**: Check `ENCRYPTION_KEY` is set
|
||||
|
||||
## Developer notes
|
||||
### Logs
|
||||
- Backend logs Discord bot status and API requests
|
||||
- Frontend console shows API calls and errors
|
||||
- Check browser Network tab for failed requests
|
||||
|
||||
- The dashboard UI is in `frontend/src/components/` (notable files: `Dashboard.js`, `ServerSettings.js`, `Login.js`).
|
||||
- The Express API is in `backend/index.js` and uses `discord-bot` (discord.js client) to operate on guilds, invites, channels and roles.
|
||||
- Invite delete flow: frontend fetches a short-lived token then requests DELETE with header `x-invite-token`.
|
||||
## Contributing
|
||||
|
||||
## Next steps / suggestions
|
||||
1. Fork the repository
|
||||
2. Create feature branch
|
||||
3. Make changes with tests
|
||||
4. Submit pull request
|
||||
|
||||
- Harden `/api/servers/:guildId/invite-token` to require an authenticated user and verify the user has admin permissions for the guild.
|
||||
- Add rate-limiting to token issuance and optionally keep the old `INVITE_API_KEY` option for server-to-server automation.
|
||||
- Updated docs: the README and CHANGELOG were updated to reflect Postgres integration and recent frontend/backend changes. See `CHANGELOG.md` and `checklist.md` for details.
|
||||
## License
|
||||
|
||||
If you want, I can add step-by-step instructions to create the `.env` files from templates, or implement the production safe option of authenticating `/invite-token` requests. Tell me which you'd prefer.
|
||||
MIT License - see LICENSE file for details.
|
||||
|
||||
---
|
||||
Updated: Oct 4, 2025
|
||||
|
||||
## Full setup guide (detailed)
|
||||
|
||||
This section walks through the exact steps to get the project running locally or on a machine reachable via Tailscale/Nginx Proxy Manager.
|
||||
|
||||
Prerequisites
|
||||
1. Node.js 18+ and npm
|
||||
2. Postgres (local or remote) or use an existing Postgres server reachable over your network/Tailscale
|
||||
3. Discord application + Bot credentials and (optional) Twitch app credentials
|
||||
|
||||
Database (Postgres) setup
|
||||
1. Create a Postgres database and user. Example psql commands:
|
||||
|
||||
```bash
|
||||
sudo -u postgres psql
|
||||
CREATE DATABASE ecs_fullstack;
|
||||
CREATE USER ecs_user WITH PASSWORD 'supersecret';
|
||||
GRANT ALL PRIVILEGES ON DATABASE ecs_fullstack TO ecs_user;
|
||||
\q
|
||||
```
|
||||
|
||||
2. Set the `DATABASE_URL` in `backend/.env`:
|
||||
|
||||
```
|
||||
DATABASE_URL=postgres://ecs_user:supersecret@127.0.0.1:5432/ecs_fullstack
|
||||
```
|
||||
|
||||
3. Start the backend (it will run migrations / ensure tables at startup):
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Backend configuration (.env)
|
||||
- `DATABASE_URL` - required for Postgres persistence
|
||||
- `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET`, `DISCORD_BOT_TOKEN` - from Discord Developer Portal
|
||||
- `FRONTEND_BASE` - public frontend URL (used for OAuth redirect)
|
||||
- `PORT`, `HOST` - where backend listens
|
||||
- `CORS_ORIGIN` - optional restrict origin to your frontend URL
|
||||
- `TWITCH_CLIENT_ID`, `TWITCH_CLIENT_SECRET` - optional for Twitch integration
|
||||
|
||||
Frontend configuration
|
||||
1. In `frontend/.env` set:
|
||||
|
||||
```
|
||||
REACT_APP_API_BASE=https://your-domain-or-ip:3002
|
||||
```
|
||||
|
||||
2. For development behind an HTTPS domain (Nginx Proxy Manager), ensure the CRA dev client uses `wss` by setting the `WDS_SOCKET_*` variables in `frontend/.env` (see docs if using a TLS domain)
|
||||
|
||||
Start the frontend dev server:
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Bot behaviour and deployment
|
||||
- The `backend` process will boot the Discord bot client when valid `DISCORD_BOT_TOKEN` is present. The bot registers slash commands per guild on startup and responds to backend pushes for setting updates.
|
||||
- If you prefer to run the bot separately, you can run the `discord-bot` module separately; ensure `BOT_PUSH_URL`/`BOT_SECRET` are configured if backend and bot are on different hosts.
|
||||
|
||||
Useful endpoints
|
||||
- `GET /api/servers/:guildId/commands` — returns the authoritative list of commands and per-guild enabled/locked status.
|
||||
- `GET/POST /api/servers/:guildId/live-notifications` — get/update live notification settings
|
||||
- `GET /api/twitch/streams?users=user1,user2` — proxy to twitch helix for streams (backend caches app-token)
|
||||
- `GET /api/events?guildId=...` — Server-Sent Events for real-time updates (ServerSettings subscribes to this)
|
||||
|
||||
### Twitch Live Notification Settings (Detailed)
|
||||
|
||||
Endpoint: `GET/POST /api/servers/:guildId/live-notifications`
|
||||
|
||||
Shape returned by GET:
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"channelId": "123456789012345678",
|
||||
"twitchUser": "deprecated-single-user-field",
|
||||
"message": "🔴 {user} is now live!",
|
||||
"customMessage": "Custom promo text with link etc"
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `twitchUser` is a legacy single-user field retained for backward compatibility. The active watched users list lives under `/api/servers/:guildId/twitch-users`.
|
||||
- `message` (default message) and `customMessage` (override) are persisted. If `customMessage` is non-empty it is used when announcing a live stream; otherwise `message` is used. If both are empty the bot falls back to `🔴 {user} is now live!`.
|
||||
- Update by POSTing the same shape (omit fields you don't change is okay; unspecified become empty unless preserved on server).
|
||||
|
||||
### Discord Bot Twitch Embed Layout
|
||||
|
||||
When a watched streamer goes live the bot posts a standardized embed. The layout is fixed to keep consistency:
|
||||
|
||||
Embed fields:
|
||||
1. Title: Stream title (hyperlinked to Twitch URL) or fallback "{user} is live".
|
||||
2. Author: Twitch display name with avatar and link.
|
||||
3. Thumbnail: Stream thumbnail (or profile image fallback).
|
||||
4. Fields:
|
||||
- Category: Game / category name (or "Unknown").
|
||||
- Viewers: Current viewer count.
|
||||
5. Description: Twitch user bio (if available via Helix `users` endpoint) else truncated stream description (200 chars).
|
||||
6. Footer: `ehchadservices • Started: <localized start time>`.
|
||||
|
||||
Pre-Embed Message (optional):
|
||||
- If `customMessage` is set it is posted as normal message content above the embed.
|
||||
- Else if `message` is set it is posted above the embed.
|
||||
- Else no prefix content is posted (embed alone).
|
||||
|
||||
Variables:
|
||||
- `{user}` in messages will not be auto-replaced server-side yet; include the username manually if desired. (Can add template replacement in a future iteration.)
|
||||
|
||||
### Watched Users
|
||||
|
||||
- Add/remove watched Twitch usernames via `POST /api/servers/:guildId/twitch-users` and `DELETE /api/servers/:guildId/twitch-users/:username`.
|
||||
- Frontend polls `/api/twitch/streams` every ~15s to refresh live status and renders a "Watch Live" button per user.
|
||||
- The watcher announces a stream only once per live session; when a user goes offline the session marker clears so a future live event re-announces.
|
||||
|
||||
### SSE Event Types Relevant to Twitch
|
||||
|
||||
- `twitchUsersUpdate`: `{ users: ["user1", "user2"], guildId: "..." }`
|
||||
- `liveNotificationsUpdate`: `{ enabled, channelId, twitchUser, message, customMessage, guildId }`
|
||||
|
||||
Consume these to live-update UI without refresh (the `BackendContext` exposes an `eventTarget`).
|
||||
|
||||
### Customizing Messages
|
||||
|
||||
- In the dashboard under Live Notifications you can set both a Default Message and a Custom Message.
|
||||
- Clear Custom to fall back to Default.
|
||||
- Save persists to backend and pushes an SSE `liveNotificationsUpdate`.
|
||||
|
||||
### Future Improvements
|
||||
|
||||
- Template variable replacement: support `{user}`, `{title}`, `{category}`, `{viewers}` inside message strings.
|
||||
- Per-user custom messages (different prefix for each watched streamer).
|
||||
- Embed image improvements (dynamic preview resolution trimming for Twitch thumbnails).
|
||||
|
||||
Notes about Postgres requirement
|
||||
- The backend now assumes Postgres persistence (via `DATABASE_URL`). If `DATABASE_URL` is not set the server will exit and complain. This change makes server settings authoritative and persistent across restarts.
|
||||
|
||||
Logs and verbosity
|
||||
- The bot and watcher log messages have been reduced to avoid per-guild spam. You will see concise messages like "🔁 TwitchWatcher started" and "✅ ECS - Full Stack Bot Online!" rather than one-line-per-guild spam.
|
||||
|
||||
Troubleshooting
|
||||
- If you see mixed-content errors in the browser when using a TLS domain with the CRA dev server, configure Nginx to proxy websockets and set CRA `WDS_SOCKET_*` env vars (see docs/nginx-proxy-manager.md)
|
||||
**Updated**: October 9, 2025
|
||||
|
||||
Reference in New Issue
Block a user