11 KiB
Wordle Score Tracker Slack Bot
A high-performance Slack bot written in Go that automatically tracks Wordle scores and provides daily summaries.
Features
- 🎯 Automatic Detection: Detects Wordle scores in any channel the bot is added to
- 📊 Daily Summaries: Posts a configurable morning summary of yesterday's results
- 🏆 Leaderboard: Shows who solved the puzzle and their scores
- 📈 Statistics: Calculates success rate and average scores
- 🔥 Streaks: Track individual and group solve streaks
- 📅 Weekly Reports: View the last 7 days of results
- 👤 Personal Stats: See your own average, win rate, and distribution
- 🛡️ Anti-Cheat: Validates puzzle numbers and prevents duplicate submissions
- ⚙️ Configurable: Set custom summary times and channels
- 💬 Thread Replies: Replies with updated standings when you post a score
- 🚀 High Performance: Written in Go for minimal resource usage
Quick Start
Prerequisites
- Go 1.21 or higher
- A Slack workspace where you can create apps
Project Structure
This project follows standard Go project layout:
cmd/wordle-bot/- Main application entry pointinternal/- Private application packages (bot, config, tracker)pkg/- Public library code (reusable pattern matching)
See PROJECT_STRUCTURE.md for detailed documentation.
Build and Run
# Clone the repository
git clone <your-repo-url>
cd wordle-bot
# Download dependencies and generate go.sum
go mod tidy
# Build the binary
go build -o wordle-bot ./cmd/wordle-bot
# Set environment variables
export SLACK_BOT_TOKEN="xoxb-your-bot-token"
export SLACK_APP_TOKEN="xapp-your-app-token"
# Run the bot
./wordle-bot
Or use the included Makefile (handles go mod tidy automatically):
make build
make run
Slack App Setup
1. Create a Slack App
- Go to api.slack.com/apps
- Click "Create New App" → "From scratch"
- Give it a name (e.g., "Wordle Tracker") and select your workspace
2. Configure Bot Permissions
Navigate to OAuth & Permissions and add these Bot Token Scopes:
channels:history- Read messages in channelschannels:read- View basic channel infochat:write- Post messagescommands- Add slash commandsreactions:write- Add reactions to messagesusers:read- Read user profile info
3. Enable Socket Mode
- Go to Socket Mode in the sidebar
- Enable Socket Mode
- Click Generate Token and give it a name (e.g., "Socket Token")
- Save the App-Level Token (starts with
xapp-)
4. Add Slash Commands
Go to Slash Commands and create these commands:
Command 1: /wordle-config
- Command:
/wordle-config - Request URL: (leave blank for Socket Mode)
- Short Description:
Configure Wordle bot settings - Usage Hint:
[time HH:MM | channel | status]
Command 2: /wordle-stats
- Command:
/wordle-stats - Request URL: (leave blank for Socket Mode)
- Short Description:
View Wordle statistics - Usage Hint:
[today | yesterday]
5. Enable Event Subscriptions
- Go to Event Subscriptions
- Enable Events
- Under Subscribe to bot events, add:
message.channels- Listen to messages in channels
6. Install the App to Your Workspace
- Go to Install App in the sidebar
- Click Install to Workspace
- Review permissions and click Allow
- Save the Bot User OAuth Token (starts with
xoxb-)
7. Get Your Tokens
You now have two tokens:
- Bot Token (from OAuth & Permissions):
xoxb-... - App Token (from Socket Mode):
xapp-...
8. Invite Bot to Channels
In Slack, invite the bot to channels where you want it to track scores:
/invite @Wordle Tracker
9. Configure the Bot
Use slash commands to configure:
# Set this channel for daily summaries
/wordle-config channel
# Set summary time (24-hour format)
/wordle-config time 09:00
# Check current configuration
/wordle-config status
Usage in Slack
Posting Wordle Scores
Users just post their Wordle scores normally:
Wordle 1662 5/6
⬜⬜⬜⬜⬜
⬜🟨⬜🟨🟨
🟨🟨🟨⬜⬜
🟨🟩⬜🟩🟩
🟩🟩🟩🟩🟩
The bot will automatically:
- Detect the score
- Validate the puzzle number (must be today's puzzle ±1 day for timezones)
- Check for duplicates (only one score per person per day)
- Track it for daily summary
- Reply in thread with confirmation and updated standings
Anti-Cheat Reactions:
- Thread reply with ✅ = Score accepted and tracked (includes today's standings)
- ❌ reaction = Invalid puzzle number (not today's Wordle)
- 🔁 reaction = Duplicate (you already posted today)
Slash Commands
View today's scores:
/wordle-stats today
View yesterday's summary:
/wordle-stats yesterday
View last 7 days:
/wordle-stats week
View all-time leaderboard:
/wordle-stats leaderboard
View your personal stats (with streaks!):
/wordle-stats me
Configure summary time:
/wordle-config time 09:00
Set current channel for summaries:
/wordle-config channel
Check configuration:
/wordle-config status
Running as a Service
Linux (systemd)
Create /etc/systemd/system/wordle-bot.service:
[Unit]
Description=Wordle Score Tracker Bot
After=network.target
[Service]
Type=simple
User=wordle-bot
WorkingDirectory=/opt/wordle-bot
Environment="SLACK_BOT_TOKEN=xoxb-your-token"
Environment="SLACK_APP_TOKEN=xapp-your-token"
ExecStart=/opt/wordle-bot/wordle-bot
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable wordle-bot
sudo systemctl start wordle-bot
sudo systemctl status wordle-bot
macOS (launchd)
Create ~/Library/LaunchAgents/com.wordle-bot.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.wordle-bot</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/wordle-bot</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>SLACK_BOT_TOKEN</key>
<string>xoxb-your-token</string>
<key>SLACK_APP_TOKEN</key>
<string>xapp-your-token</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>/path/to/wordle-bot</string>
</dict>
</plist>
Load and start:
launchctl load ~/Library/LaunchAgents/com.wordle-bot.plist
launchctl start com.wordle-bot
FreeBSD (rc.d)
An rc.d service script is included (wordle_bot.rc).
Copy to /usr/local/etc/rc.d/wordle_bot, make it executable, and configure /etc/rc.conf.d/wordle_bot:
wordle_bot_enable="YES"
wordle_bot_user="wordle"
wordle_bot_dir="/path/to/bot"
wordle_bot_bot_token="xoxb-your-token"
wordle_bot_app_token="xapp-your-token"
Then: service wordle_bot start
Docker
Build and run with Docker:
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY main.go ./
RUN go build -o wordle-bot main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/wordle-bot .
CMD ["./wordle-bot"]
docker build -t wordle-bot .
docker run -d \
--name wordle-bot \
-e SLACK_BOT_TOKEN="xoxb-your-token" \
-e SLACK_APP_TOKEN="xapp-your-token" \
-v $(pwd)/data:/root \
wordle-bot
Data Storage
The bot stores data in two JSON files:
wordle_scores.json: Historical score databot_config.json: Bot configuration (summary time, channel)
These files are created automatically in the working directory.
Backup recommendations:
# Backup data files
cp wordle_scores.json wordle_scores.json.bak
cp bot_config.json bot_config.json.bak
# Scheduled backup (add to crontab)
0 2 * * * cp /home/wordle/bot/*.json /home/wordle/backups/
Building for Production
Optimized Build
# Build with optimizations (smaller binary)
go build -ldflags="-s -w" -o wordle-bot main.go
# Or use the Makefile
make build
Cross-Compilation
Build for different platforms:
# Linux amd64
GOOS=linux GOARCH=amd64 go build -o wordle-bot-linux-amd64 ./cmd/wordle-bot
# Linux arm64
GOOS=linux GOARCH=arm64 go build -o wordle-bot-linux-arm64 ./cmd/wordle-bot
# macOS amd64
GOOS=darwin GOARCH=amd64 go build -o wordle-bot-darwin-amd64 ./cmd/wordle-bot
# macOS arm64 (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o wordle-bot-darwin-arm64 ./cmd/wordle-bot
# Windows
GOOS=windows GOARCH=amd64 go build -o wordle-bot-windows-amd64.exe ./cmd/wordle-bot
# FreeBSD amd64
GOOS=freebsd GOARCH=amd64 go build -o wordle-bot-freebsd-amd64 ./cmd/wordle-bot
Monitoring and Logs
Check Logs
# View live logs (if running as service with log file)
tail -f wordle-bot.log
# Search for errors
grep -i error wordle-bot.log
# View last 50 lines
tail -n 50 wordle-bot.log
Using systemd journalctl (Linux)
# View logs
sudo journalctl -u wordle-bot -f
# View last 100 lines
sudo journalctl -u wordle-bot -n 100
# View logs since boot
sudo journalctl -u wordle-bot -b
Troubleshooting
Bot doesn't start
# Check if tokens are set
echo $SLACK_BOT_TOKEN
echo $SLACK_APP_TOKEN
# Check permissions on binary
ls -la wordle-bot
# Run manually to see errors
export SLACK_BOT_TOKEN="xoxb-..."
export SLACK_APP_TOKEN="xapp-..."
./wordle-bot
Bot doesn't respond in Slack
- Verify bot is invited to channel:
/invite @Wordle Tracker - Check that Socket Mode is enabled in Slack app settings
- Verify event subscription for
message.channels - Check bot permissions include
channels:history
Scores not detected
- Ensure message contains "Wordle XXXX Y/6" format
- Check bot has
channels:historypermission - Verify bot is running:
ps aux | grep wordle-botor check your service manager
Daily summary not posting
- Run
/wordle-config statusto verify channel is set - Check summary time is correct (24-hour format)
- Ensure bot has permissions in summary channel
- Check logs for errors
- Verify the system time is correct
Resource Usage
Typical resource usage:
- Memory: ~15-25 MB
- CPU: <1% idle, ~2-5% when processing
- Disk: <10 MB (binary + data files)
Lightweight and efficient!
Security Notes
- Protect tokens: Never commit tokens to version control
- Use environment variables: Keep tokens in env vars or secure config files
- Run as non-root: Always run as a dedicated user account
- File permissions: Restrict access to config files containing tokens
- Regular updates: Keep Go and dependencies updated
Example secure setup:
# Create dedicated user (Linux)
sudo useradd -r -s /bin/false wordle-bot
# Secure config file
chmod 600 .env
chown wordle-bot:wordle-bot .env
License
MIT License - feel free to modify and use as needed!