This Discord bot monitors reactions in a specific channel, classifies them as positive or negative, and posts a weekly leaderboard with the top-scoring posts.
- Track reactions across multiple channels
- Configure positive and negative reaction sets
- Weekly summary message with best/worst authors and posts
- Threaded leaderboard with full author rankings, top posts, and worst posts
- Persistent storage in
data/leaderboard.json - Self-hostable with Docker
- A Discord application with a bot user
- Enabled Message Content Intent (so the bot can summarize post content)
- Bot permissions in the target channel:
- View Channel
- Read Message History
- Read Messages
- Add Reactions (optional)
- Send Messages
- Embed Links
Copy .env.example to .env and fill in values:
DISCORD_TOKEN(required)TARGET_CHANNEL_IDS(required, comma-separated)SUMMARY_CHANNEL_ID(required)NEGATIVE_REACTIONS(comma-separated; all other reactions count as positive)IGNORED_REACTIONS(comma-separated; excluded entirely)LEADERBOARD_CRON(optional, default0 9 * * 1)CRON_TIMEZONE(optional, IANA tz likeEurope/Prague; defaults to server time zone)LEADERBOARD_LIMIT(optional, default10)WORST_POST_LIMIT(optional, default3)KVIK_REACTION(optional, emoji that marks a post for Kvík of the week)KVIK_CRON(optional, schedule for Kvík of the week)KVIK_TITLE(optional, title for the Kvík of the week post)MESSAGE_CONTENT_INTENT(optional, set totrueonly if you enabled the Message Content Intent)
Negative reaction values accept unicode or custom emojis. Custom emojis can be provided as either name:id or the full <:name:id> format.
bun install
cp .env.example .env
# edit .env with your values
bun run start
cp .env.example .env
# edit .env with your values
docker compose up -d --build
Data is persisted to ./data via the Docker volume defined in docker-compose.yml.
- Scoring is per user per message:
- If a user reacts only with positive emojis, the message gets +1.
- If a user reacts only with negative emojis, the message gets -1.
- If a user uses both positive and negative emojis, it counts as 0.
- Reactions from the message author are ignored.
- Ignored emojis are excluded from scoring entirely.
- Kvík of the week posts are collected when the configured reaction is present, and sent on the configured cron schedule.
- The bot only tracks reactions while it is running. If you want to backfill historical data, let me know and I can add a one-time sync.
- Leaderboard scheduling uses
CRON_TIMEZONEwhen provided; otherwise it uses the container/server time zone.