2.8 KiB
2.8 KiB
subreddit-announcer
A Discord bot that watches subreddits and posts an embed to a Discord channel whenever a new submission appears. Built with discord.py and asyncpraw; state is a local SQLite DB. One long-running process polls Reddit on an interval — no webhooks, no external scheduler.
How it works
- A background loop polls each watched subreddit's
/neweveryANNOUNCER_POLL_INTERVALseconds (default 60). - The first time a subreddit is watched it's bootstrapped silently: the
posts already on
/neware recorded as "seen" without being announced, so adding a busy subreddit doesn't dump its backlog into the channel. Only posts created afterwards are announced. - Seen submission ids are stored in SQLite for dedup and pruned to the most recent 500 per subreddit.
Setup
1. Discord application
- Create an app at https://discord.com/developers/applications.
- Bot tab → reset/copy the token → put it in
config.envasDISCORD_TOKEN. - Invite the bot to your server with the
botandapplications.commandsscopes, and the Send Messages + Embed Links permissions. No privileged intents are required (the bot never reads message content).
2. Reddit app (read-only)
- Go to https://www.reddit.com/prefs/apps → create another app.
- Choose type script. The client id is the string shown under the app name; the secret is labelled secret.
- Put both into
config.env(REDDIT_CLIENT_ID,REDDIT_CLIENT_SECRET).
3. Config + run
cp config.example.env config.env
$EDITOR config.env # fill in the tokens
# uv handles the venv + deps from pyproject.toml
set -a; source config.env; set +a
uv run bot.py
Commands
Slash commands (server-only; replies are ephemeral):
| Command | What it does |
|---|---|
/watch <subreddit> [channel] |
Announce a subreddit's new posts in a channel (defaults to the current one). |
/unwatch <subreddit> |
Stop announcing that subreddit in this server. |
/watching |
List the subreddits announced in this server. |
/setinterval <seconds> |
Change the global poll interval (min 15s). |
Running it persistently
It's a single foreground process; keep it alive however you like — systemd,
tmux, pm2, or a container. A minimal systemd unit:
[Service]
WorkingDirectory=/home/megaproxy/claude/projects/subreddit-announcer
EnvironmentFile=/home/megaproxy/claude/projects/subreddit-announcer/config.env
ExecStart=/home/megaproxy/.local/bin/uv run bot.py
Restart=always
Notes
config.envandannouncer.dbare gitignored — secrets and state stay local.- Syntax check:
uv run python -m py_compile bot.py.