Ekaii Discord bot — gallery curation (🖼️) + whitelist slash commands (EkaiiAPI)
- JavaScript 99.4%
- Dockerfile 0.6%
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| index.js | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| test-jellyfin.js | ||
ekaii-bot
Discord bot for the Ekaii community — one process / one gateway connection, two features today, more on the roadmap. Deployed as a standalone container on the NAS.
Features (live)
🖼️ Gallery curation (reaction-based)
- A curator reacts 🖼️ on a message that has image(s) → those images are added to the
website gallery (
POST /api/gallery, uploaded to Zipline, attributed to the poster). - Removing the last 🖼️ reaction → the image(s) are removed from the gallery
(
DELETE /api/gallery/:id). The bot tracksattachmentId → galleryItemIdin/data/state.json. - Gated to
CURATOR_ROLE_IDS(else Manage Messages). Confirms with ✅ / 🔁 / ⚠️.
✅ Whitelist (slash commands)
/whitelist <pseudo>and/unwhitelist <pseudo>— resolves the MC username → UUID (Mojang), then calls EkaiiAPI onmc-ekaii(POST/DELETE /whitelist/{uuid}). Whitelist changes auto-propagate to the other backends via the stack'swl-auto-sync.- Gated to
WHITELISTER_ROLE_IDS(else Manage Messages). Optional audit log inAUDIT_CHANNEL_ID. - Guild slash commands are (re)registered on startup.
Run
cp .env.example .env # fill secrets, chmod 600
docker build -t ekaii-gallery-bot:latest .
docker run -d --restart unless-stopped --name ekaii-gallery-bot \
--network website-net \ # the Ekaii Website Coolify net (to reach the site app)
--env-file .env -v ekaii_gallery_bot_state:/data \
ekaii-gallery-bot:latest
The bot must be on the website's Coolify network to reach app:3000, and have LAN egress to
reach EkaiiAPI at mc-host:14623. Note: a website redeploy can detach the container
from that network → docker network connect website-net ekaii-gallery-bot && docker restart it.
Roadmap (next phases)
- Role sync — Discord whitelisteur role ⇄ site
WHITELISTERrole (and member ↔ whitelist), replacing the NASekaii-promote-whitelisterscron stopgap. Needs the whitelisteur role id + a site role-set endpoint. - Account link —
/linkbinding Discord ↔ website (Microsoft/Xbox) account ↔ MC UUID, so every feature can trust identity. Lightweight code-based link first. - Onboarding —
/applymodal → staff approve/reject → auto-whitelist + role + welcome. - Service provisioning —
/jellyfin create-account(Jellyfin user + Jellyseerr import, DM creds). - Service directory —
/services(+ health) pulling fromhub.ekaii.fr. - Live MC status embed/presence (EkaiiAPI
/server/ping), tickets,/whois, etc.
Least-privilege for prod: invite with a scoped permission integer (not Administrator), drop the Message Content / Presence intents if the gallery uses a slash command instead of reactions.