# 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: - Reddit app registration: - discord.py docs: - asyncpraw docs: - Forgejo repo: - Secrets live in local `config.env` (gitignored) — never in git.