Files
tiennm99 53e569ca12 feat(blacklist): add /blacklist shorthand and /whitelist_rnd
/blacklist is the short form of the two read commands: bare it lists both
lists like /blacklist_rules, and given text it judges that text like
/blacklist_check. Both long names stay for when the intent should be
explicit. An argument of only whitespace is not an argument, so it lists.

/whitelist_rnd returns one whitelist entry chosen at random, and says the
list is empty rather than answering with nothing. It reads only the
whitelist, and only for the calling topic.

The six existing command descriptions are shortened alongside. /help
renders as one un-chunked message pinned at 4096 runes, and two more
commands pushed it to 4123; the shorter wording brings it to 4049. That
ceiling is a shared limit this module did not create, and it will bind again
on the next command added anywhere in the repo.
2026-09-15 13:58:45 +07:00

4.9 KiB

Blacklist

The blacklist module lets a chat keep a list of forbidden text and a list of exceptions, then ask whether a given text is blocked.

Command Parameters What it does
/blacklist [text...] Bare, lists both lists; with text, judges it
/blacklist_add [text...] Adds text to the blacklist, or the message you replied to
/blacklist_del <text...> Removes text from the blacklist
/whitelist_add [text...] Adds an exception, or the message you replied to
/whitelist_del <text...> Removes an exception
/blacklist_rules — Lists both lists in one message
/blacklist_check <text...> Judges a text against both lists
/whitelist_rnd — Returns one whitelist entry at random

All are public and single-shot.

/blacklist is the short form of the two read commands: on its own it does what /blacklist_rules does, and given text it does what /blacklist_check does. Nothing is lost by using it — the long names remain for when the intent should be explicit.

/whitelist_rnd returns a single whitelist entry chosen at random, and says so plainly when the whitelist is empty rather than answering with nothing.

The bot does not police the chat

This is the first thing to know, because the module's name promises something it deliberately does not do. Nothing happens automatically. The bot never reads ordinary messages, never deletes anything, and never warns or restricts anyone. The lists sit inert until /blacklist_check asks about a specific text.

Automatic moderation would need three things this bot does not have: a message-level hook in the dispatcher, privacy mode disabled in BotFather so Telegram delivers ordinary group messages at all, and admin rights with permission to delete in every group. All three are out of scope by choice.

Lists belong to a topic, not to the bot

Each thread keeps its own two lists. In a forum supergroup, entries added in one topic are invisible in the next. A non-forum group has one set of lists; a private chat with the bot has its own, shared with nobody.

This is the most common surprise: running /blacklist_check in the wrong topic gives a different answer than the same command one topic over, and it is not a bug. Every reply says "in this topic" for that reason.

Within a thread, anyone can add and anyone can remove — including entries someone else added. The lists belong to the conversation, so the permission to edit them does too. A per-owner rule would strand entries whose author has left the group.

How the whitelist works

The whitelist is not a second independent list. It is an exception layer over the blacklist, and it rescues a match only when it covers that match in the text being checked.

With ass blacklisted and assassin whitelisted:

Checked text Verdict Why
assassin Allowed The whitelist entry spans the whole match
dumbass Blacklisted Nothing whitelisted covers this ass
I met an assassin, dumbass Blacklisted The first match is rescued; the second is not

The third row is the one worth remembering. A whitelist entry does not make a whole message safe — it only rescues the occurrences it actually contains.

Matching

Matching is by substring, after the text is normalized:

  • Case does not matter. Cat, CAT and cat are one rule.
  • Spacing does not matter. cat dog and cat dog are one rule, and a newline is just a space.
  • Diacritics do matter. ma, má and mà are three separate entries. To catch all three, add all three.
  • The same word matches across devices. Vietnamese typed on an iPhone and on an Android phone can differ in how the accents are encoded; normalization resolves that, so the two forms match each other.
  • Full-width and other presentation variants fold onto their plain forms.

/blacklist_check accepts text of any length. Entries themselves are capped at 200 bytes — roughly 200 plain letters, or about 65 Vietnamese characters.

Listing

Every /blacklist_add, /blacklist_del, /whitelist_add and /whitelist_del answers with the current contents of the list it touched, so you see the result without running anything else. That includes the two outcomes that change nothing — text already present, or text that was not there to remove — since those are exactly the moments you want to see what the list actually holds. A whitelist command shows the whitelist; a blacklist command shows the blacklist.

/blacklist_rules prints both lists in one message, each with its entry count, showing entries as they were typed rather than in the normalized form. Each entry is tappable to copy, ready to paste into a _del command.

Telegram caps a message at 4096 characters. A list longer than that is trimmed with a count of what was left out; both headings always appear, so a long blacklist never hides the whitelist entirely.