feat(discord): support per-category mention and ignore rules - #77380
Open
andrexibiza wants to merge 1 commit into
Open
andrexibiza wants to merge 1 commit into
andrexibiza wants to merge 1 commit into
Conversation
Add free_response_categories, ignored_categories, and require_mention_categories config keys (env + YAML) so Discord mention and ignore rules can target a category and everything inside it, instead of enumerating every child channel. Mirrors the existing *_channels helpers: CSV-in-env/list-in-YAML parsing, "*" wildcard sentinel, thread inheritance through the parent channel's category, and a startup warning when a category is listed in both free and ignore lists. Precedence: allowed_channels -> ignored_channels -> ignored_categories -> free_response_channels/free_response_categories -> require_mention_categories -> require_mention global default.
Contributor
Author
|
Discord category gating is complete at head |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related #38539 #38540 #54338 #61593
What & Why
Adds per-category Discord mention/ignore rules so a bot's gating can target a Discord category and everything inside it (channels + threads) instead of enumerating every child channel ID.
Three new config keys mirror the existing channel-ID helpers (
_discord_free_response_channels()et al.):The headline use case from #38539: running two bots with inverse regional coverage. Bot 1 wants "free everywhere except category C" — previously inexpressible without enumerating every non-C channel ID (brittle, breaks when a channel is added). Now:
Implementation:
_discord_free_response_categories(),_discord_ignored_categories(),_discord_require_mention_categories()— same parsing contract as the channel keys: list in YAML, CSV in env (DISCORD_FREE_RESPONSE_CATEGORIES,DISCORD_IGNORED_CATEGORIES,DISCORD_REQUIRE_MENTION_CATEGORIES),"*"wildcard sentinel preserved._discord_category_keys(channel)— resolves the category ID on text channels and threads (discord.py exposesThread.categorythrough the parent; a missing/uncached parent is treated as "no category" so the message falls through to the channel-ID rules)._handle_message+ ingress admission + missed-message backfill dispatch):ignored_categoriessilences even when @mentioned; category-derived free/require-mention scopes augment (union) the channel-derived sets;require_mention_categoriesoverrides a free-response exemption for that category.allowed_channels→ignored_channels→ignored_categories→free_response_channels/free_response_categories→require_mention_categories→require_mentionglobal default.free_response_categoriesandignored_categories(mutual exclusion, per the issue spec)._apply_yaml_configwrites the three env vars following the existing channel-ID pattern.Thread inheritance: a thread whose parent channel sits in a listed category picks up the category rule through
Thread.category— no new inheritance code.How to test
26 new tests cover: free-response category waives mention (channels + threads + wildcard), ignored category silences even when @mentioned (channels + threads + wildcard + beats free-response), require-mention category gates when globally free (and mentions still work, and other channels stay free, and it overrides a channel-level free-response exemption), CSV/YAML/numeric-scalar parsing parity for all three accessors, the mutual-exclusion warning, the ingress admission gate, and the config.yaml → env bridge.
Existing gating suites re-run clean (see Platforms).
What platforms tested on
tests/gateway/test_discord_category_rules.py: 26 passed.tests/gateway/test_discord_channel_controls.py+test_discord_free_response.py+test_discord_allowed_channels.py+test_discord_allowed_mentions.py+test_discord_approval_mentions.py+test_discord_bot_filter.py+test_discord_roles_dm_scope.py: 46 passed.tests/gateway/ -k discord(minustest_discord_voice_mixer.py, which fails collection on this machine from a pre-existing numpy binary mismatch): 294 passed; the only 4 failures (video/attachment send tests) reproduce identically on cleanmainand are unrelated to this diff.python scripts/check-windows-footguns.pyon both files: clean.git diff --check: clean.Why this matters to users
Before: a Discord bot operator who wanted "respond freely everywhere except inside one category" (e.g. a second bot covering the rest of the server) had to maintain a hand-curated list of every channel ID outside that category — a list that silently drifts every time anyone adds a channel. Silencing or whitelisting a whole category likewise required enumerating its children.
After: the rule is one line —
require_mention_categories: ["<category_id>"]orfree_response_categories/ignored_categories. New channels inside the category inherit the rule automatically, and the config survives category renames (IDs only, per the issue's conventions). Multi-bot servers can express complementary per-region gating without drift or enumeration.References
require_mention_categoriesgap — this PR delivers all three keys from the issue spec, including the third key that makes "free everywhere except category C" expressible.