A lightweight Go application that monitors your Slack DMs and sends phone notifications via ntfy.sh.
- 🔔 Real-time monitoring of Slack direct messages
- 📱 Push notifications to your phone via ntfy.sh
- 🔄 Configurable polling interval (default: 60 seconds)
- 💾 Persistent state to avoid duplicate notifications
- 🔒 Simple manual token setup
- 🚀 No external dependencies (stdlib only)
- ⚡ Lightweight and fast (clean package architecture)
- Go 1.21 or higher
- A Slack workspace account
- ntfy.sh app on your phone (free, no account needed)
For experienced developers:
-
Clone and build:
git clone git@github.com:FourPalms/golang-slack-monitor.git cd golang-slack-monitor make build -
Extract Slack tokens (see Step 2 below for detailed instructions)
-
Create config (see
config.example.jsonfor reference):mkdir -p ~/.slack-monitor cp config.example.json ~/.slack-monitor/config.json # Edit with your tokens and ntfy topic chmod 600 ~/.slack-monitor/config.json
-
Run:
./slack-monitor
git clone git@github.com:FourPalms/golang-slack-monitor.git
cd golang-slack-monitor
make buildmake installMake sure ~/bin is in your PATH:
export PATH="$HOME/bin:$PATH"- Install the ntfy app on your phone:
- Choose a random topic name (this is your "password")
- Example:
my-slack-monitor-89234792 - Important: Use a random suffix to prevent others from guessing your topic
- Example:
You need two tokens from your Slack browser session. This app uses "stealth mode" authentication (same method as slack-mcp-server).
Important: Both tokens work together - you need BOTH for authentication to work.
-
Open Slack in your browser: https://app.slack.com/client/YOUR_WORKSPACE
-
Open DevTools: Press
F12(Windows/Linux) orCmd+Option+I(Mac) -
Extract xoxd token (Cookie "d"):
- Go to Application (Chrome) or Storage (Firefox) tab
- Navigate to Cookies → https://app.slack.com
- Find the cookie named
d - Copy its Value - this is your xoxd token (starts with
xoxd-) ⚠️ Note: The cookie is named "d" but contains the "xoxd" token (not "xoxc")
-
Extract xoxc token (API requests):
- Go to Network tab in DevTools
- Refresh the Slack page or click around to generate some API traffic
- Filter by "api" or search for
slack.com/api/ - Click on any API request (e.g.,
conversations.list,users.info) - Look at the Request URL or Query String Parameters
- Find the
tokenparameter - this is your xoxc token (starts withxoxc-) - Copy the entire token value
Why both tokens?
- xoxd: Cookie-based session authentication
- xoxc: API request parameter authentication
- Both required for "stealth mode" (no Slack app needed)
Create ~/.slack-monitor/config.json (see config.example.json in the repo for reference):
mkdir -p ~/.slack-monitor
cat > ~/.slack-monitor/config.json << 'EOF'
{
"slack": {
"xoxc_token": "xoxc-PASTE-YOUR-XOXC-TOKEN-HERE",
"xoxd_token": "xoxd-PASTE-YOUR-XOXD-TOKEN-HERE",
"poll_interval_seconds": 60
},
"notifications": {
"ntfy_topic": "your-topic-name-here"
},
"monitor": {
"dms_only": true
}
}
EOFReplace the placeholder values:
xoxc-PASTE-YOUR-XOXC-TOKEN-HERE→ Your xoxc token from Step 2.4xoxd-PASTE-YOUR-XOXD-TOKEN-HERE→ Your xoxd token from Step 2.3your-topic-name-here→ Your ntfy.sh topic from Step 1
Set secure permissions:
chmod 600 ~/.slack-monitor/config.jsonUsing make (keeps Mac awake automatically):
make runOr run directly:
./slack-monitorYou'll see output like:
2025/12/30 11:00:00 Slack Monitor starting...
2025/12/30 11:00:00 Starting monitoring...
2025/12/30 11:00:00 Authenticated as yourusername (U123ABC) in workspace YourWorkspace
2025/12/30 11:00:00 State loaded successfully (0 conversations tracked)
2025/12/30 11:00:00 Checking for new messages...
2025/12/30 11:00:00 Checking 5 DM conversation(s)
2025/12/30 11:00:00 Monitoring 5 active conversation(s) (skipped 0 deleted)
2025/12/30 11:00:01 Check cycle completed in 123ms, waiting 60s before next cycle
make run (which uses caffeinate) to keep your Mac awake while monitoring, or see the Run as a service section below.
nohup caffeinate -i ./slack-monitor > ~/.slack-monitor/monitor.log 2>&1 &Save the process ID:
echo $! > ~/.slack-monitor/monitor.pidNote: Using caffeinate -i prevents your Mac from sleeping while the monitor runs. The display can still sleep to save power.
kill $(cat ~/.slack-monitor/monitor.pid)Or:
pkill slack-monitorCreate ~/Library/LaunchAgents/com.user.slack-monitor.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.user.slack-monitor</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/caffeinate</string>
<string>-i</string>
<string>/Users/YOUR_USERNAME/bin/slack-monitor</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/YOUR_USERNAME/.slack-monitor/monitor.log</string>
<key>StandardErrorPath</key>
<string>/Users/YOUR_USERNAME/.slack-monitor/monitor.log</string>
</dict>
</plist>Replace YOUR_USERNAME with your actual username.
Note: This configuration uses caffeinate -i to keep your Mac awake while the monitor runs. The display can still sleep to save power.
Load the service:
launchctl load ~/Library/LaunchAgents/com.user.slack-monitor.plistCheck status:
launchctl list | grep slack-monitorUnload the service:
launchctl unload ~/Library/LaunchAgents/com.user.slack-monitor.plist| Field | Type | Required | Default | Description |
|---|---|---|---|---|
slack.xoxc_token |
string | Yes | - | Slack user token (starts with xoxc-). Found in API request token parameter. |
slack.xoxd_token |
string | Yes | - | Slack session token (starts with xoxd-). Found in cookie "d". |
slack.poll_interval_seconds |
int | No | 60 | How often to check for new messages (in seconds). Minimum: 30, recommended: 60-300. |
notifications.ntfy_topic |
string | Yes | - | Your ntfy.sh topic name. Use a random suffix for security. |
monitor.dms_only |
bool | No | true | Monitor only DMs. Currently only true is supported. |
Automatically created and managed. Tracks the last checked timestamp for each conversation to avoid duplicate notifications.
Do not edit manually unless you know what you're doing.
Your tokens have expired. Slack tokens typically last several months but may expire sooner. Re-extract tokens following Step 2.
-
Test ntfy.sh directly:
curl -d "Test message" ntfy.sh/your-topic-nameYou should receive a notification immediately.
-
Check logs for errors:
tail -f ~/.slack-monitor/monitor.log -
Verify config file has correct topic:
cat ~/.slack-monitor/config.json | grep ntfy_topic
The monitor has built-in rate limiting (2 seconds between notifications), but if you're getting too many:
-
Increase poll interval in config (e.g., 300 = 5 minutes):
"poll_interval_seconds": 300
-
Check state file to see which conversations are tracked:
cat ~/.slack-monitor/state.json
On first run, the monitor starts tracking from "now" to avoid spamming you with old messages. If you're still getting old messages:
- Stop the monitor
- Delete state file:
rm ~/.slack-monitor/state.json - Start the monitor again
make buildmake testmake cleanFollows Ben Johnson's Standard Package Layout:
slack-monitor/
├── monitor.go # Domain types & interfaces
├── slack/ # Slack API client (xoxc/xoxd auth)
├── notification/ # ntfy.sh service (2s rate limit)
├── storage/ # State persistence (atomic writes)
└── cmd/slack-monitor/ # Main entry point & dependency wiring
- Tokens: Stored in plain text in
config.json. Set file permissions to600(owner read/write only). - Token lifespan: Slack tokens typically last months. Re-extract when they expire.
- ntfy.sh: No authentication. Use a random topic name that others cannot guess.
- Rate limiting: 2-second minimum between notifications to avoid spam.
- DMs only: Currently only monitors direct messages (no channels or @mentions)
- Token expiration: No automatic token refresh (manual re-extraction required)
- Single workspace: Monitors one Slack workspace at a time
MIT License - feel free to use and modify.
Pull requests welcome! Please include tests for new features.