subreddit-announcer/memory.md

56 lines
2.9 KiB
Markdown

# memory — subreddit-announcer
Durable memory for this project. Read at session start, update before session end. Date format: `YYYY-MM-DD`.
## Decisions & rationale
- **Full bot user, not a webhook.** Chosen so runtime management via slash
commands (`/watch`, `/unwatch`, …) is possible per-server. A webhook would be
simpler but one-way and static.
- **discord.py + asyncpraw, long-running poll loop.** Single foreground process;
`discord.ext.tasks.loop` drives a sweep every `ANNOUNCER_POLL_INTERVAL` (60s
default). Reddit has no realtime push for /new, so polling is the model.
- **Reddit read-only app creds** (client id/secret + user agent) — no Reddit
account login needed; we only read public /new listings.
- **SQLite for state** (matching `quotebot`'s pattern). `watches` maps
subreddit→channel per guild with a `bootstrapped` flag; `seen_posts` dedups.
- **Silent bootstrap on first watch.** A freshly-added subreddit's existing
/new posts are marked seen but not announced, so adding a busy sub doesn't
dump its backlog. Only posts after the watch starts are announced. Re-watching
(re-pointing the channel) resets the flag for a clean baseline.
- **No privileged intents.** The bot only posts embeds; it never reads message
content, so the invite needs just `bot` + `applications.commands` and
Send Messages / Embed Links.
- **uv for env/deps** rather than quotebot's stdlib-only approach, because
discord.py + asyncpraw are third-party. `uv run bot.py`.
## Open questions / TODOs
- [ ] Not yet run against a live Discord/Reddit (no creds configured). Needs a
real `config.env` to smoke-test end to end.
- [ ] No flair/keyword filtering yet — every new post is announced. Add a
per-watch filter if the channel gets noisy.
- [ ] `prune_seen` keeps 500 ids/subreddit; revisit if a sub exceeds 500 posts
within one poll interval (would risk re-announcing pruned ids).
- [ ] No persistent run supervisor wired up (systemd unit sketched in README).
## Session log
### 2026-06-04
- Created project scaffold from template.
- Built `bot.py`: `Store` (SQLite) + `AnnouncerBot` (discord.Client with
app_commands tree + `tasks.loop` poller) + slash commands
`/watch`, `/unwatch`, `/watching`, `/setinterval`.
- Added `pyproject.toml` (uv-managed: discord.py, asyncpraw), `config.example.env`,
README, gitignore entries for `config.env`/`announcer.db`.
- Verified: `uv sync` installs cleanly; `py_compile` passes; module imports and
`Store`/`_clean_subreddit` smoke-tested in-memory. Not yet run live (no creds).
## External references
- Discord developer portal: <https://discord.com/developers/applications>
- Reddit app registration: <https://www.reddit.com/prefs/apps>
- discord.py docs: <https://discordpy.readthedocs.io/>
- asyncpraw docs: <https://asyncpraw.readthedocs.io/>
- Forgejo repo: <https://git.rdx4.com/megaproxy/subreddit-announcer>
- Secrets live in local `config.env` (gitignored) — never in git.