Files
memes_bot/README.md
T
goyban 82b5da41b8 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>
2026-09-01 21:50:01 +00:00

4.4 KiB

Memes Bot

A personal Telegram inline bot to store and search media (photos, GIFs, videos, voice, music, stickers, files) by keywords.

فارسی


Requirements

Setup

1. Create the bot in BotFather

  • /newbot → get your token
  • /setinline → enable inline mode, set a placeholder (e.g. Search memes...)

2. Find your Telegram user ID

You need your numeric Telegram user ID to whitelist yourself.

  • Easiest: forward any message to @userinfobot — it replies with your ID
  • Alternative: open Telegram Web, click your profile, the number in the URL is your ID
  • For multiple users: repeat for each person and separate IDs with commas

3. Clone and configure

git clone https://git.goyban.com/goyban/memes_bot
cd memes_bot
cp .env.example .env

Edit .env:

BOT_TOKEN=your_telegram_bot_token_here
ALLOWED_USERS=123456789,987654321

4. Run

docker compose up -d --build

The database will be saved in ./bot_db/media.db.

Usage

Adding media — send the bot a photo, GIF, video, voice message, music file, sticker, or any document, then type keywords when prompted (comma-separated or one per message), then /done.

Round video messages are stored as regular videos: Telegram has no inline result type for video notes, so keeping them as video is what makes them searchable.

Searching inline — in any chat type @yourbotusername keyword to search and send.

Telegram suggests these commands as you type /, with a short description beside each suggestion.

Commands

Command Description
/start Start the bot and show usage instructions
/menu Show the available commands
/list Show all saved media
/review Review pending submissions one by one (admin only)
/edit [search] Select a meme and edit its keywords (admin only)
/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:

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.

Run /review to work through the queue. Each item is shown with its keywords and four buttons: approve, reject, fix keywords, or stop.

The queue keeps no cursor. /review always fetches the oldest pending item, so you can stop after three and come back tomorrow, and several moderators can review at the same time without stepping on each other — if two open the same item, the first decision wins and the second is told it was already handled.

Leave this off unless you mean it. With ALLOWED_USERS empty, everyone is an allowed user, so turning submissions on would accept media from anyone who finds the bot.

Moving to another server

The only files you need to transfer are:

  • .env
  • bot_db/media.db