115749e232
- _hangman_display compared uppercase word chars against lowercase guessed_letters set, so letters were never revealed after correct guesses - Word guess wrong path now shows the board and remaining guesses - Winner display now includes the guesser's name on correct word guess Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Lotus Matrix Bot & Server Roadmap
Matrix bot and server improvements for the Lotus Guild homeserver (matrix.lotusguild.org).
Repo: https://code.lotusguild.org/LotusGuild/matrixBot
Status: Phase 3 — Bot Features & SSO
Priority Order (suggested)
PostgreSQL migrationTURN serverRoom structure + space setupMatrix bot (core + commands)LiveKit / Element CallSSO / OIDC (Authelia)- Custom Element Web (chat.lotusguild.org with branding)
- Discord bridge (lets people transition gradually)
- Custom emoji packs (makes it feel like home)
- Moderation bot
- Everything else
Infrastructure
| Service | Host | IP | LXC | Notes |
|---|---|---|---|---|
| Synapse | micro1 | 10.10.10.29 | 151 | Homeserver + coturn + LiveKit |
| PostgreSQL 17 | micro1 | 10.10.10.44 | 109 | Synapse database backend |
| NPM | large1 | 10.10.10.27 | 139 | Reverse proxy + landing page |
| Authelia | compute-storage-01 | 10.10.10.36 | 167 | SSO/OIDC provider |
| LLDAP | large1 | 10.10.10.39 | 147 | LDAP user directory |
Key paths on Synapse LXC (10.10.10.29):
- Synapse config:
/etc/matrix-synapse/homeserver.yaml - Synapse venv:
/opt/venvs/matrix-synapse/ - coturn config:
/etc/turnserver.conf - LiveKit config:
/etc/livekit/config.yaml - LiveKit service:
livekit-server.service(systemd) - Synapse admin UI:
/var/www/synapse-admin/(nginx on :8080) - Landing page:
/var/www/matrix-landing/index.html(on NPM LXC 139)
Port forwarding (router -> 10.10.10.29):
- TCP+UDP 3478 (TURN signaling)
- TCP 7881 (LiveKit TCP)
- UDP 49152-65535 (media relay)
- UDP 50100-50200 (LiveKit WebRTC media)
Rooms (all v12)
| Room | Room ID | Join Rule | Bot In |
|---|---|---|---|
| The Lotus Guild (space) | !gSynpxmopNrtoxeSvj |
public | — |
| General | !wfokQ1-pE896scu_AOcCBA2s3L4qFo-PTBAFTd0WMI0 |
public | no |
| Welcome | !Y-wvNosuytqBOWampH9k-ta7bYXW7okqwBQ7PuRVBWE |
public | yes |
| Commands | !ou56mVZQ8ZB7AhDYPmBV5_BR28WMZ4x5zwZkPCqjq1s |
restricted | yes |
| Management | !mEvR5fe3jMmzwd-FwNygD72OY_yu8H3UP_N-57oK7MI |
invite | no |
| Memes | !GK6v5cLEEnowIooQJv5jECfISUjADjt8aKhWv9VbG5U |
public | no |
| Cool Kids | !R7DT3QZHG9P8QQvX6zsZYxjkKgmUucxDz_n31qNrC94 |
invite | no |
Power level roles (Cinny tags):
- 100: Owner (jared)
- 50: The Nerdy Council (enhuynh, lonely)
- 48: Panel of Geeks
- 35: Cool Kids
- 0: Member
Welcome room has events_default: 50 (users can't message) but m.reaction: 0 (users can react to the welcome message to get invited to channels).
Server - Quality of Life
- Migrate from SQLite to PostgreSQL
- Set up TURN/STUN server (coturn) for reliable voice/video calls behind NAT
- Enable URL previews in Synapse
- Increase upload size limit for media/GIFs (200MB)
- Enable message search (full-text search with PostgreSQL backend)
- Configure media retention policy (remote: 1yr, local: 3yr)
- Set up sliding sync (native in Synapse, no proxy needed)
- LiveKit server with systemd service for Element Call video rooms
- Default room version set to v12, all rooms upgraded
- Room publishing rules (jared + lotusbot can publish to directory)
- Enable push notifications gateway for mobile clients
Server - Auth & SSO
- Token-based registration (registration tokens shared in Discord)
- SSO/OIDC via Authelia (
oidc_providersin homeserver.yaml) allow_existing_users: truefor linking existing accounts to SSO- Password auth remains enabled alongside SSO
Server - Hardening
- Rate limiting configuration in Synapse
- E2EE enabled on all rooms
- Federation allow/deny lists (decide if you want open federation or Lotus-only)
- Regular Synapse version updates
- Monitoring with Prometheus + Grafana
- Synapse worker mode if performance becomes an issue
Server - Admin & Moderation
- Synapse admin API dashboard (synapse-admin v0.11.1 at http://10.10.10.29:8080)
- Power levels configured per room (Cinny tags for role hierarchy)
- Invite-only registration flow (token-based)
- Set up Mjolnir or Draupnir (moderation bot for ban lists, spam protection)
- Set up room ACLs for federation control (block known-bad servers)
- Automated backups of Synapse database and media
Bridging (Transition Period)
- Set up mautrix-discord bridge so messages flow between Discord and Matrix
- Bridge key channels (general, gaming, memes, etc.)
- Bridge voice channels if possible (experimental, may not be worth it)
- Puppet bridging so Discord users appear as Matrix users and vice versa
Room Structure
- Set up "The Lotus Guild" space as top-level container
- General, Welcome, Commands, Management, Memes, Cool Kids rooms
- Welcome room with react-to-join onboarding
- Bot commands room (Commands — keeps bot spam contained)
- Voice/video call room (Element Call via LiveKit)
- Custom room avatars with Lotus Guild branding
- Sub-spaces for categories (Gaming, Media, etc.)
- Read-only announcements room
- Game-specific rooms (Minecraft, Valorant, League, Hytale, etc.)
Custom Emoji & Stickers
- Export all custom emojis from Discord server
- Create Matrix emoji packs (per-room or space-wide)
- Set up sticker picker widget in Element
- Import/create Lotus Guild sticker pack
Element/Client Customization
- Landing page at matrix.lotusguild.org with client recommendations (Cinny, Commet, Element)
- Custom Element Web instance (self-hosted on chat.lotusguild.org)
- Custom theme with #980000 branding
- Configure .well-known to point clients to custom Element Web instance
Widgets & Integrations
- RSS bot for game news feeds
- GitHub/Gitea notifications bot (push events to a dev room)
Bot - Core Setup
- Project scaffolding (
bot.py, config,.env, requirements) - matrix-nio async client with E2EE support
- Device verification / trust storage (auto-trust all devices)
- Logging (rotating file + stdout)
- Config validation (homeserver URL, access token, device ID)
- Graceful shutdown handling (SIGTERM/SIGINT)
- Initial sync with startup token (ignores old messages)
- Auto-accept room invites
Bot - Commands (all implemented)
!help— List all available commands!ping— Bot latency check!8ball <question>— Magic 8-ball!fortune— Fortune cookie message!flip— Coin flip!roll <NdS>— Dice roller!random <min> <max>— Random number generator!rps <choice>— Rock Paper Scissors!poll <question>— Poll (reactions)!trivia— Trivia game (reactions, 30s reveal)!champion [lane]— Random LoL champion picker!agent [role]— Random Valorant agent picker!wordle— Full Wordle game (daily puzzles, hard mode, stats, share)
Bot - Integrations
!minecraft <username>— RCON whitelist!ask <question>— Ollama LLM integration (lotusllm, 2min cooldown)
Bot - Admin Commands
!health— Bot stats (uptime, command counts, service status)
Bot - Welcome System
- Auto-post welcome message in Welcome room on startup
- React-to-join: users react with checkmark, bot invites to General, Commands, Memes
- Welcome message event ID persisted to
welcome_state.json - Reaction handler via
UnknownEventcallback form.reactionevents
Bot - Wordle
- Daily puzzles with proper two-pass letter evaluation
- Hard mode with constraint validation
- Statistics tracking with persistence (
wordle_stats.json) - Cinny-compatible rendering (inline
<span>tiles instead of<table>) - DM-based gameplay (games happen in DMs,
!wordle shareposts to public room) - Virtual keyboard display with letter state tracking
Bot - Deployment
- Systemd service (
matrixbot.service) - Auto-deploy from Gitea webhook
- Deployment script
- Bot lives in: Welcome (react-to-join) and Commands (all commands)
Bot - Not Porting (Discord-specific)
- Reaction roles (replaced by react-to-join in Welcome room)
- Status cycling (Matrix presence is simpler)
- Guild-specific event handlers (channel create/delete, boost, etc.)
Tech Stack
- Language: Python 3
- Library: matrix-nio (with E2EE)
- Homeserver: matrix.lotusguild.org (Synapse on 10.10.10.29)
- Database: PostgreSQL 17 on 10.10.10.44
- TURN: coturn on 10.10.10.29 (colocated with Synapse)
- LiveKit: livekit-server on 10.10.10.29 (systemd, public IP 162.192.14.139)
- SSO: Authelia on 10.10.10.36 (OIDC provider, backed by LLDAP)
- Dependencies: matrix-nio[e2ee], aiohttp, python-dotenv, mcrcon
Bot Files
matrixBot/
├── bot.py # Entry point, client setup, event callbacks
├── callbacks.py # Message + reaction event handlers
├── commands.py # Command registry + all command implementations
├── config.py # Environment config + validation
├── utils.py # send_text, send_html, send_reaction, get_or_create_dm
├── welcome.py # Welcome message + react-to-join logic
├── wordle.py # Full Wordle game engine
├── wordlist_answers.py # Wordle answer word list
├── wordlist_valid.py # Wordle valid guess word list
├── .env.example # Environment template
└── requirements.txt # Python dependencies