titlebot-ng
A Matrix chat bot for Jupiter Broadcasting's “The Lunch” and “Linux Unplugged” chat rooms that collects title suggestions and runs voting through 👍 reactions.
From the Owner
This has gotten out of hand. I've been working 7 days a week for a couple years now and this has been my most recent mortar between the bricks of time that I've been squeezing out of my life between sleep. Simplification needs to happen whenever possible.
Quick Start
-
Create a Python environment and install dependencies:
python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt -
Copy the example config for each room you want to monitor:
cp configs/config_example.yaml configs/main-room.yaml cp configs/config_example.yaml configs/second-room.yamlEdit each file with the appropriate Matrix bot credentials and a different
room_id. -
Start the room bots:
./run_all.sh
The launcher creates the Python environment and installs dependencies if the environment is missing. It starts two independent processes per room: a suggestion scraper and a command/posting bot. Logs and PID files include the full config filename. A failed room process is retried without stopping the others. Press Ctrl+C to stop the services.
Commands
| Command | Action |
|---|---|
!suggest <title> |
Submit a title suggestion. Also accepts !Suggest, !suggestion, !Suggestion, SUGGEST, and !sug. |
!gettitles |
Post pending suggestions as individual messages, each with a 👍 reaction, preceded by voting instructions and the command list. |
!countvotes |
Report the latest voting round's current emoji results, ranked most to fewest votes. |
!getvotes |
Alias for !countvotes. |
!clear |
Mark all pending suggestions as posted so they are excluded from future rounds. |
!mayhem |
Generate chaotic text using Ollama. |
React with 👍 on a suggestion post to vote. Each person's thumbs-up counts once per title; the bot's starter reaction does not count. Thumbs-up skin-tone variants count as votes too. Removed reactions are excluded. Results include titles with zero votes, and ties appear in suggestion order. Run either results command again to refresh the ranking as people keep voting.
Successfully posted suggestions leave the pending queue. Results commands leave the queue untouched, and !clear preserves existing voting posts and their reactions. After clearing, !gettitles responds “No new title suggestions posted.” unless new suggestions have been collected.
Configuration
Put one .yaml or .yml file per room in configs/, with any filename. config.yaml is not required. The bundled config_example.yaml template and files ending in .hold are ignored. Restart the launcher after adding or removing configs.
Example:
username: "@your-bot:matrix.org"
password: "your_bot_password"
homeserver: "https://matrix.org"
room_id: "!your_room_id:matrix.org"
lookback_limit: 7200
batch_size: 100
poll_interval: 30
sync_timeout: 3000
command_sync_timeout: 30000
initial_sync_timeout: 300
post_interval: 0.5
post_loop_interval: 1
Each room has its own suggestion database and command history. The bot acknowledges newly collected suggestions with ✅ and rejects submissions from accounts in the shared banned-users database.
Components and Storage
room.py: Matrix connection, suggestion storage, command handling, posting, and live reaction counting.post.py: Suggestion data model.scraper.py: Collects and acknowledges suggestions.post_results.py: Handles commands and posts suggestions when!gettitlesis received.run_all.sh: Starts and monitors the two Python services for each room.simulate_suggestions.py: Sends suggestions from a text file for manual testing.dbutil.py: SQLite connections and commit handling.
Per-room suggestions_<room>.db files store suggestions, posted status, original event IDs, and command deduplication records. Shared last_run.db and last_post.db track collection and posting timestamps; banned_users.db stores blocked accounts. Vote totals are read from Matrix reactions whenever results are requested.
To run the components individually, use the same config path for both:
.venv/bin/python scraper.py configs/main-room.yaml
.venv/bin/python post_results.py configs/main-room.yaml
Dependencies and Tests
Python 3, matrix-nio, PyYAML, requests, and Python's built-in SQLite support.
.venv/bin/python -m unittest discover -v
Optional: Ollama Integration
For !mayhem, install Ollama, then build the custom model:
ollama create mad_cat_man:latest -f customOllama/Modelfile
Run Ollama on localhost:11434.