460 lines
10 KiB
Markdown
460 lines
10 KiB
Markdown
# 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
|
|
- ⚙️ **Configurable**: Set custom summary times and channels
|
|
- ✅ **Reaction Confirmation**: Adds a checkmark reaction when it tracks 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 point
|
|
- `internal/` - Private application packages (bot, config, tracker)
|
|
- `pkg/` - Public library code (reusable pattern matching)
|
|
|
|
### Build and Run
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://git.ewnix.net/phlux/slack-wordle-scores.git
|
|
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:
|
|
|
|
```bash
|
|
make build
|
|
make run
|
|
```
|
|
|
|
## Slack App Setup
|
|
|
|
### 1. Create a Slack App
|
|
|
|
1. Go to [api.slack.com/apps](https://api.slack.com/apps)
|
|
2. Click **"Create New App"** → **"From scratch"**
|
|
3. 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 channels
|
|
- `channels:read` - View basic channel info
|
|
- `chat:write` - Post messages
|
|
- `commands` - Add slash commands
|
|
- `reactions:write` - Add reactions to messages
|
|
- `users:read` - Read user profile info
|
|
|
|
### 3. Enable Socket Mode
|
|
|
|
1. Go to **Socket Mode** in the sidebar
|
|
2. **Enable Socket Mode**
|
|
3. Click **Generate Token** and give it a name (e.g., "Socket Token")
|
|
4. 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
|
|
|
|
1. Go to **Event Subscriptions**
|
|
2. **Enable Events**
|
|
3. Under **Subscribe to bot events**, add:
|
|
- `message.channels` - Listen to messages in channels
|
|
|
|
### 6. Install the App to Your Workspace
|
|
|
|
1. Go to **Install App** in the sidebar
|
|
2. Click **Install to Workspace**
|
|
3. Review permissions and click **Allow**
|
|
4. 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
|
|
- Track it for daily summary
|
|
- Add a ✅ reaction to confirm
|
|
|
|
### Slash Commands
|
|
|
|
**View today's scores:**
|
|
```
|
|
/wordle-stats today
|
|
```
|
|
|
|
**View yesterday's summary:**
|
|
```
|
|
/wordle-stats yesterday
|
|
```
|
|
|
|
**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`:
|
|
|
|
```ini
|
|
[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:
|
|
|
|
```bash
|
|
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
|
|
<?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:
|
|
|
|
```bash
|
|
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`:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```dockerfile
|
|
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"]
|
|
```
|
|
|
|
```bash
|
|
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 data
|
|
- `bot_config.json`: Bot configuration (summary time, channel)
|
|
|
|
These files are created automatically in the working directory.
|
|
|
|
**Backup recommendations:**
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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:history` permission
|
|
- Verify bot is running: `ps aux | grep wordle-bot` or check your service manager
|
|
|
|
### Daily summary not posting
|
|
|
|
- Run `/wordle-config status` to 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
|
|
|
|
1. **Protect tokens**: Never commit tokens to version control
|
|
2. **Use environment variables**: Keep tokens in env vars or secure config files
|
|
3. **Run as non-root**: Always run as a dedicated user account
|
|
4. **File permissions**: Restrict access to config files containing tokens
|
|
5. **Regular updates**: Keep Go and dependencies updated
|
|
|
|
Example secure setup:
|
|
|
|
```bash
|
|
# 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!
|