Add public mode with channel membership requirements
Completes TODO #2. PUBLIC_MODE swaps the ALLOWED_USERS allowlist for a membership check against REQUIRED_CHATS, with REQUIRE_MODE choosing between needing every chat or just one. - Stop is_admin() falling back to "everyone is an admin" when ADMIN_USERS is unset once PUBLIC_MODE is on. That fallback is the original single-owner convenience, but under public mode it handed moderation, /edit and /delete to anyone who found the bot. Public mode now grants admin to nobody until ADMIN_USERS is set, and says so at startup. Private deployments are unaffected. - Cache membership answers: inline search queries on every keystroke, so an uncached check meant several API calls per typed character. Grants last five minutes, refusals thirty seconds, so a user who has just joined is not locked out for the full window. - Fail closed when the membership check errors, and validate REQUIRED_CHATS at startup so a chat the bot cannot read is reported rather than silently refusing every user. - Refused users get a join prompt with real links instead of silence; inline shows a tappable bar that opens the bot and explains why. A private bot stays silent as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,25 @@ Telegram suggests these commands as you type `/`, with a short description besid
|
||||
| `/delete <id>` | Remove an entry (get ID from `/list`; admin only) |
|
||||
| `/cancel` | Cancel current add operation |
|
||||
|
||||
### Making the bot public
|
||||
|
||||
Set `PUBLIC_MODE=true` to open the bot to anyone who meets a membership requirement, instead of the `ALLOWED_USERS` list:
|
||||
|
||||
```env
|
||||
PUBLIC_MODE=true
|
||||
ADMIN_USERS=123456789
|
||||
REQUIRED_CHATS=@mychannel,@mygroup
|
||||
REQUIRE_MODE=all
|
||||
```
|
||||
|
||||
`REQUIRED_CHATS` accepts `@username` or numeric ids. **The bot must be an admin in each one**, otherwise it cannot check membership and everyone is refused. The bot verifies this at startup and logs an error naming any chat it cannot read. `REQUIRE_MODE=all` demands every chat; `any` accepts one. With `REQUIRED_CHATS` empty the bot is open to everyone.
|
||||
|
||||
Users who don't qualify get a message listing what to join. In inline search they see a tappable bar that opens the bot and explains the same thing, rather than empty results with no reason given.
|
||||
|
||||
> **Set `ADMIN_USERS` before turning this on.** With no `ADMIN_USERS`, a private bot treats its users as admins — convenient for a one-person bot, but in public mode that would mean everyone. Public mode therefore grants admin to nobody until `ADMIN_USERS` is set, and logs an error at startup if you forget.
|
||||
|
||||
Membership answers are cached for five minutes, since inline search would otherwise query Telegram on every keystroke. Refusals are cached for only thirty seconds, so a user who has just joined gets in almost immediately.
|
||||
|
||||
### Accepting submissions
|
||||
|
||||
Set `ACCEPT_SUBMISSIONS=true` in `.env` to let non-admin users send media too. Their submissions are stored but stay invisible — they don't appear in inline search or `/list` until a moderator approves them. Admins' own media is still saved directly.
|
||||
|
||||
Reference in New Issue
Block a user