Mastodon bot that creates daily rankings of all #CluesBySam posts that comes its way
https://mastodon.denibol.com/@CluesByRank
- Java 98.4%
- Dockerfile 1%
- Shell 0.6%
| 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)
- Weekly Rankings: Every Monday at 00:15, publishes the top 5 leaderboard for the previous Monday–Sunday
- Error Classification: Separates daily rankings into two categories:
- Perfect solves (only 🟩 emoji)
- Solves with errors (containing 🟨, 🟠 or 🟡 emojis — 🟠 counts as 2 errors, 🟨/🟡 as 1)
- Error Count: Displays the weighted error count per participant in the "Brave Detectives" section
- Tie-breaking:
- Perfect Solvers: time tie → earliest post wins
- Brave Detectives: time tie → fewer errors wins → earliest post wins
- Weekly leaderboard: points tie → most gold medals → most silver medals → most bronze medals → fewest total errors
- 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 🟨/🟠/🟡)
- Counts weighted errors per participant (🟠=2, 🟨=1, 🟡=1)
- Ranks by fastest time; ties broken by fewer errors (Brave Detectives only), then by earliest post time
- 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
Every Monday at 00:15 (America/New_York timezone), the bot additionally:
- Collects all #CluesBySam posts from the previous Monday through Sunday
- For each day, splits participants into the same two categories as the daily ranking:
- Perfect solvers ranked by time → earliest post (tie-break)
- Brave Detectives ranked by time → fewer errors → earliest post (tie-break)
- Awards points within each daily group independently:
- 1st place → 3 pts, 2nd → 2 pts, 3rd → 1 pt, rest → 0 pts
- Each error deducts 1 pt from that day's earned points (minimum 0 per day)
- Accumulates points, medals (🥇/🥈/🥉) and total errors across all 7 days into a single unified leaderboard
- Weekly tie-breaking (equal points): most gold medals → most silver → most bronze → fewest total errors
- Posts the top N weekly leaderboard (configurable); skipped entirely if no valid data exists for the whole week
Example Output
Daily Rankings
The bot posts rankings like:
🧩 #CluesBySam — Daily Rankings
📅 March 11th, 2026 📊 Easy
――――――――――――――――――――
🏆 Perfect Solvers (3 participants)
Not a single error in sight! 🔥
🥇 @alice@fosstodon.org ⏱️ 01:23
🥈 @bob@mastodon.social ⏱️ 02:05
🥉 @carol@infosec.exchange ⏱️ 03:41
――――――――――――――――――――
🤔 Brave Detectives (2 participants)
A few mistakes along the way… still impressive! 💪
🥇 @dave@mastodon.online ⏱️ 02:00 ❌ 1 error
🥈 @eve@hachyderm.io ⏱️ 03:15 ❌ 3 errors
――――――――――――――――――――
Keep solving, detectives! 🕵️♀️🕵️♂️
Weekly Rankings
Every Monday the bot posts the previous week's leaderboard:
🧩 #CluesBySam — Weekly Rankings
📅 May 5, 2026 – May 11, 2026
――――――――――――――――――――
🏆 Top Detectives of the Week
🥇 @alice@fosstodon.org ⭐ 18 pts
🥇×3 🥈×2 🥉×1
🥈 @bob@mastodon.social ⭐ 14 pts
🥇×2 🥈×1 🥉×0 ❌ 2 errors
🥉 @carol@infosec.exchange ⭐ 11 pts
🥇×1 🥈×2 🥉×1 ❌ 5 errors
🎖️ @dave@mastodon.online ⭐ 8 pts
🥇×0 🥈×1 🥉×2 ❌ 3 errors
🎖️ @eve@hachyderm.io ⭐ 6 pts
🥇×1 🥈×0 🥉×0 ❌ 8 errors
――――――――――――――――――――
📊 How points are calculated:
🥇 1st place → 3 pts
🥈 2nd place → 2 pts
🥉 3rd place → 1 pt
❌ Each error → −1 pt (min. 0 per day)
――――――――――――――――――――
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.ranking.top-count |
5 |
Top N results shown in daily rankings |
clues.ranking.weekly-top-count |
5 |
Top N results shown in weekly rankings |
clues.scheduler.cron |
0 0 0 * * * |
Cron expression for daily job (12:00 AM) |
clues.scheduler.weekly-cron |
0 15 0 * * MON |
Cron expression for weekly job (Mondays at 00:15 AM) |
clues.scheduler.timezone |
America/New_York |
Timezone for daily and weekly jobs |
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.