Mastodon bot that creates daily rankings of all #CluesBySam posts that comes its way
https://mastodon.denibol.com/@CluesByRank
- Java 97.6%
- Dockerfile 1.5%
- Shell 0.9%
| src/main | ||
| .gitignore | ||
| build.sh | ||
| docker-compose.yaml | ||
| Dockerfile | ||
| LICENSE | ||
| pom.xml | ||
| README.md | ||
clues-by-rank
A Mastodon bot that tracks and ranks CluesBySam puzzle solutions.
Features
- Streaming Listener: Monitors the #CluesBySam hashtag in real-time using Mastodon's streaming API
- Account Following: Automatically follows accounts that post with #CluesBySam and accounts that follow the bot
- Daily Rankings: Generates and publishes daily rankings at midnight (America/New_York timezone)
- Error Classification: Separates rankings into two categories:
- Perfect solves (only 🟩 emoji)
- Solves with errors (containing 🟨 emoji)
- Time Tracking: Records solve times in HH:MM format
Prerequisites
- Java 25+
- Maven 3.9+
- Docker and Docker Compose (optional, for containerized deployment)
- A Mastodon account with an access token that has the following scopes:
read:statuseswrite:statusesfollowread:accountsread:followsread:notificationsprofilewrite:follows
Quick Start
1. Clone
git clone <repository-url>
cd clues-by-rank
2. Run the Bot
Development Mode
CLUES_MASTODON_BASE_URL=<YOUR_MASTODON_INSTANCE_URL_HERE> CLUES_MASTODON_TOKEN=<YOUR_ACCESS_TOKEN_HERE> mvn spring-boot:run
Production Build
mvn package
CLUES_MASTODON_BASE_URL=<YOUR_MASTODON_INSTANCE_URL_HERE> CLUES_MASTODON_TOKEN=<YOUR_ACCESS_TOKEN_HERE> java -jar target/clues-by-rank-1.0.0.jar
Docker Deployment
Edit `docker-compose.yml` to add your Mastodon instance URL and token as environment variables
docker-compose up -d
How It Works
Every day at midnight (America/New_York timezone), the bot:
- Collects all #CluesBySam posts from the past 24 hours
- Parses the format: "Mon 1st 2026 (Difficulty), in HH:MM" (with several time variations)
- Filters results to the current date only
- Classifies by error status (🟩 vs 🟨)
- Generates rankings of the top N fastest times (configurable via
clues.top-count) - Posts one toot with both rankings (perfect solves and solves with errors) in a formatted message
Example Output
The bot posts rankings like:
🧩 #CluesBySam — Daily Rankings
📅 March 11th, 2026
――――――――――――――――――――
🏆 Perfect Solvers
Not a single error in sight! 🔥
🥇 @alice@fosstodon.org ⏱️ 01:23
🥈 @bob@mastodon.social ⏱️ 02:05
🥉 @carol@infosec.exchange ⏱️ 03:41
――――――――――――――――――――
🤔 Brave Detectives
A few mistakes along the way… still impressive! 💪
🥇 @dave@mastodon.online ⏱️ 02:00
🥈 @eve@hachyderm.io ⏱️ 03:15
――――――――――――――――――――
Keep solving, detectives! 🕵️♀️🕵️♂️
Configuration
Environment Variables / application.properties
| Property | Default | Description |
|---|---|---|
clues.mastodon.base-url |
Required | Mastodon instance URL |
clues.mastodon.token |
Required | Mastodon access token |
clues.mastodon.hashtag |
CluesBySam |
Hashtag to monitor |
clues.locale |
en-US |
Locale for date formatting |
clues.top-count |
5 |
Number of top results to include in rankings |
clues.scheduler.cron |
0 0 0 * * * |
Cron expression for daily job (12:00 AM) |
clues.scheduler.timezone |
America/New_York |
Timezone for the daily job |
Troubleshooting
Token Issues
- Ensure the token is copied correctly without extra spaces
- Verify the token has the required scopes
Streaming Not Working
- The bot retries connection automatically every 10 seconds
- Check logs for authentication errors
- Verify the Mastodon instance URL is correct
Rankings Not Posted
- Ensure at least one post with the expected format is made with the #CluesBySam hashtag
- Check that the post date matches the current day
License
See LICENSE file for details.