Jared Vititoe 4b3864bb77 Add Bazarr + Huntarr webhook notifications via Apprise jsons://
Both services now send notifications to the hookshot webhook endpoint:
- Bazarr: switched from broken Apprise Matrix URL to JSON notifier
  with jsons://matrix.lotusguild.org/webhook/<uuid>
- Huntarr: fixed apprise_url from raw https:// to jsons:// scheme

Both hookshot transforms updated to parse Apprise JSON payload:
{version, title, message, type, attachments}

Huntarr avatar set from selfhst icons CDN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 14:59:04 -05:00

Lotus Matrix Bot & Server Roadmap

Matrix bot and server infrastructure for the Lotus Guild homeserver (matrix.lotusguild.org).

Repo: https://code.lotusguild.org/LotusGuild/matrixBot

Status: Phase 4 — Webhooks & Integrations


Priority Order

  1. PostgreSQL migration
  2. TURN server
  3. Room structure + space setup
  4. Matrix bot (core + commands)
  5. LiveKit / Element Call
  6. SSO / OIDC (Authelia)
  7. Webhook integrations (hookshot)
  8. Discord bridge (lets people transition gradually)
  9. Custom Element Web (chat.lotusguild.org with branding)
  10. Custom emoji packs
  11. Moderation bot
  12. Everything else

Infrastructure

Service Host IP LXC Notes
Synapse large1 10.10.10.29 151 Homeserver + coturn + LiveKit + hookshot
PostgreSQL 17 large1 10.10.10.2 109 Synapse database backend
NPM compute-storage-01 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:

  • Synapse config: /etc/matrix-synapse/homeserver.yaml
  • coturn config: /etc/turnserver.conf
  • LiveKit config: /etc/livekit/config.yaml
  • LiveKit service: livekit-server.service
  • Hookshot: /opt/hookshot/, service: matrix-hookshot.service
  • Hookshot config: /opt/hookshot/config.yml
  • Hookshot registration: /etc/matrix-synapse/hookshot-registration.yaml
  • Landing page: /var/www/matrix-landing/index.html (on NPM LXC 139)
  • Bot: /opt/matrixbot/, service: matrixbot.service

Port forwarding (router → 10.10.10.29):

  • TCP+UDP 3478 (TURN/STUN signaling)
  • TCP+UDP 5349 (TURNS/TLS)
  • TCP 7881 (LiveKit ICE TCP fallback)
  • TCP+UDP 49152-65535 (TURN relay + LiveKit WebRTC media)

Rooms (all v12)

Room Room ID Join Rule
The Lotus Guild (Space) !-1ZBnAH-JiCOV8MGSKN77zDGTuI3pgSdy8Unu_DrDyc public
General !wfokQ1-pE896scu_AOcCBA2s3L4qFo-PTBAFTd0WMI0 public
Commands !ou56mVZQ8ZB7AhDYPmBV5_BR28WMZ4x5zwZkPCqjq1s restricted (Space members)
Memes !GK6v5cLEEnowIooQJv5jECfISUjADjt8aKhWv9VbG5U public
Management !mEvR5fe3jMmzwd-FwNygD72OY_yu8H3UP_N-57oK7MI invite
Cool Kids !R7DT3QZHG9P8QQvX6zsZYxjkKgmUucxDz_n31qNrC94 invite
Spam and Stuff !GttT4QYd1wlGlkHU3qTmq_P3gbyYKKeSSN6R7TPcJHg invite, no E2EE (hookshot)

Power level roles (Cinny tags):

  • 100: Owner (jared)
  • 50: The Nerdy Council (enhuynh, lonely)
  • 48: Panel of Geeks
  • 35: Cool Kids
  • 0: Member

Webhook Integrations (matrix-hookshot 7.3.2)

Generic webhooks bridged into Spam and Stuff via matrix-hookshot. Each service gets its own virtual user (@hookshot_<service>) with a unique avatar. Webhook URL format: https://matrix.lotusguild.org/webhook/<uuid>

Service Webhook UUID Notes
Grafana df4a1302-2d62-4a01-b858-fb56f4d3781a Unified alerting contact point
Proxmox 9b3eafe5-7689-4011-addd-c466e524661d Notification system (8.1+)
Sonarr aeffc311-0686-42cb-9eeb-6757140c072e All event types
Radarr 34913454-c1ac-4cda-82ea-924d4a9e60eb All event types
Readarr e57ab4f3-56e6-4dc4-8b30-2f4fd4bbeb0b All event types
Lidarr 66ac6fdd-69f6-4f47-bb00-b7f6d84d7c1c All event types
Uptime Kuma 1a02e890-bb25-42f1-99fe-bba6a19f1811 Status change notifications
Seerr 555185af-90a1-42ff-aed5-c344e11955cf Request/approval events
Owncast 9993e911-c68b-4271-a178-c2d65ca88499 STREAM_STARTED / STREAM_STOPPED
Bazarr 470fb267-3436-4dd3-a70c-e6e8db1721be Subtitle events (Apprise JSON notifier)
Huntarr 78af735b-7802-4e6c-987b-db22f8636ceb Hunt/search events (Apprise jsons://)
Tinker-Tickets 6e306faf-8eea-4ba5-83ef-bf8f421f929e Custom code needed

Hookshot notes:

  • Spam and Stuff is intentionally unencrypted — hookshot bridges cannot join E2EE rooms
  • Webhook tokens stored in Synapse PostgreSQL room_account_data for @hookshot
  • JS transformation functions use hookshot v2 API: set result = { version: "v2", plain, html, msgtype }
  • The result variable must be assigned without var/let/const (needs implicit global scope in the QuickJS IIFE sandbox)
  • NPM proxies https://matrix.lotusguild.org/webhook/*http://10.10.10.29:9003
  • Virtual user avatars: set via appservice token (as_token in hookshot-registration.yaml) impersonating each user

Server Checklist

Quality of Life

  • Migrate from SQLite to PostgreSQL
  • TURN/STUN server (coturn) for reliable voice/video
  • URL previews
  • Upload size limit 200MB
  • Full-text message search (PostgreSQL backend)
  • Media retention policy (remote: 1yr, local: 3yr)
  • Sliding sync (native Synapse)
  • LiveKit for Element Call video rooms
  • Default room version v12, all rooms upgraded
  • Landing page with client recommendations (Cinny, Commet, Element, Element X mobile)
  • Push notifications gateway (Sygnal) for mobile clients

Auth & SSO

  • Token-based registration
  • SSO/OIDC via Authelia
  • allow_existing_users: true for linking accounts to SSO
  • Password auth alongside SSO

Webhooks & Integrations

  • matrix-hookshot 7.3.2 installed and running
  • Generic webhook bridge for 13 services (incl. Bazarr + Huntarr via Apprise jsons://)
  • Per-service JS transformation functions (formatted messages with emoji)
  • Per-service virtual user avatars
  • NPM reverse proxy for /webhook path
  • Tinker Tickets custom code

Bridging

  • mautrix-discord bridge
  • Bridge key channels (general, gaming, memes)
  • Puppet bridging

Room Structure

  • The Lotus Guild space
  • All core rooms with correct power levels and join rules
  • Spam and Stuff room for service notifications (hookshot)
  • Custom room avatars
  • Read-only announcements room

Hardening

  • Rate limiting
  • E2EE on all rooms (except Spam and Stuff — intentional for hookshot)
  • Federation allow/deny lists
  • Regular Synapse updates
  • Automated database + media backups

Admin

  • Synapse admin API dashboard (synapse-admin at http://10.10.10.29:8080)
  • Power levels per room
  • Mjolnir/Draupnir moderation bot

Bot Checklist

Core

  • matrix-nio async client with E2EE
  • Device trust (auto-trust all devices)
  • Graceful shutdown (SIGTERM/SIGINT)
  • Initial sync token (ignores old messages on startup)
  • Auto-accept room invites
  • Deployed as systemd service (matrixbot.service) on LXC 151

Commands

  • !help — list commands
  • !ping — latency check
  • !8ball <question> — magic 8-ball
  • !fortune — fortune cookie
  • !flip — coin flip
  • !roll <NdS> — dice roller
  • !random <min> <max> — random number
  • !rps <choice> — rock paper scissors
  • !poll <question> — poll with reactions
  • !trivia — trivia game (reactions, 30s reveal)
  • !champion [lane] — random LoL champion
  • !agent [role] — random Valorant agent
  • !wordle — full Wordle game (daily, hard mode, stats, share)
  • !minecraft <username> — RCON whitelist add
  • !ask <question> — Ollama LLM (lotusllm, 2min cooldown)
  • !health — bot uptime + service status

Welcome System

  • Watches Space joins and DMs new members automatically
  • React-to-join: react with in DM → bot invites to General, Commands, Memes
  • Welcome event ID persisted to welcome_state.json

Wordle

  • Daily puzzles with two-pass letter evaluation
  • Hard mode with constraint validation
  • Stats persistence (wordle_stats.json)
  • Cinny-compatible rendering (inline <span> tiles)
  • DM-based gameplay, !wordle share posts result to public room
  • Virtual keyboard display

Tech Stack

Component Technology
Bot language Python 3
Bot library matrix-nio (E2EE)
Homeserver Synapse 1.147+
Database PostgreSQL 17
TURN coturn
Video calls LiveKit + lk-jwt-service
SSO Authelia (OIDC) + LLDAP
Webhook bridge matrix-hookshot 7.3.2
Reverse proxy Nginx Proxy Manager
Bot dependencies matrix-nio[e2ee], aiohttp, python-dotenv, mcrcon

Bot Files

matrixBot/
├── bot.py              # Entry point, client setup, event loop
├── callbacks.py        # Message + reaction event handlers
├── commands.py         # 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 variable template
└── requirements.txt    # Python dependencies
Description
Matrix bot for the Lotus Guild homeserver
Readme 373 KiB
Languages
HTML 61.3%
JavaScript 25.2%
Shell 13.5%