56 lines
2.9 KiB
Markdown
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.
|