← Back to PRs

#19059: feat(telegram): add commands.include/exclude for selective menu registration

by moxunjinmu open 2026-02-17 09:10 View on GitHub →
channel: telegram size: M
## Problem Telegram limits bots to 100 commands via `setMyCommands`. When bundled skills, plugins, and custom commands exceed this cap, commands are silently truncated from the end. Users currently have no way to control which commands appear in the Telegram menu — only `commands.native: false` (disable all) or `true` (enable all). Refs #17061 ## Solution Add optional `include` and `exclude` string arrays to `ProviderCommandsConfig`: - **`commands.include`** (whitelist): only listed commands are registered in the menu - **`commands.exclude`** (blacklist): listed commands are hidden from the menu - When both are set, `include` takes priority; Zod emits a warning on the `exclude` path - Command names are normalized (strip `/` prefix, lowercase) for matching - Filtering only affects menu registration (`setMyCommands`) — handlers remain callable via manual `/command` input - Filtering runs after command merging but before the 100-command cap truncation ### Example config ```json { "channels": { "telegram": { "commands": { "include": ["start", "help", "settings", "status"] } } } } ``` ### Changed files | File | Change | |------|--------| | `src/config/types.messages.ts` | Add `include?` and `exclude?` to `ProviderCommandsConfig` | | `src/config/zod-schema.core.ts` | Extend `ProviderCommandsSchema` with array validation + mutual exclusion warning | | `src/config/schema.help.ts` | Add help text for telegram/discord/slack | | `src/telegram/bot-native-command-menu.ts` | Add `filterTelegramMenuCommands` pure function | | `src/telegram/bot-native-commands.ts` | Wire filter between command merge and cap truncation | ## Test Plan - [x] 8 unit tests for `filterTelegramMenuCommands` (no filter, empty arrays, whitelist, blacklist, include priority, normalize `/` prefix, normalize case, no match → empty) - [x] 2 integration tests in `bot-native-commands.test.ts` (include filters menu, exclude filters menu) - [x] All 361 config tests pass — no regressions - [x] Pre-commit lint passes <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds optional `commands.include` (whitelist) and `commands.exclude` (blacklist) arrays to `ProviderCommandsConfig`, allowing users to control which commands appear in the Telegram bot menu via `setMyCommands`. The filtering is implemented as a pure function that runs after command merging but before the 100-command cap truncation, and only affects menu registration — handlers remain callable via direct `/command` input. - The core filtering logic in `filterTelegramMenuCommands` is well-implemented with proper normalization (strip `/` prefix, lowercase) and correct include-takes-priority semantics - **Issue**: The Zod `superRefine` validation rejects config when both `include` and `exclude` are set, contradicting the PR description's claim that "include takes priority, exclude will be ignored" — users setting both will get a config validation error, not a warning - **Issue**: Help text and schema accept `include`/`exclude` for Discord and Slack channels, but filtering is only implemented for Telegram — configuring these for Discord/Slack will have no effect - Good test coverage with 8 unit tests for the filter function and 2 integration tests verifying end-to-end behavior <h3>Confidence Score: 3/5</h3> - The core Telegram filtering logic is correct, but the Zod validation will reject configs that the PR explicitly intends to handle gracefully. - Score of 3 reflects that the main feature (Telegram command menu filtering) works correctly, but there's a behavioral mismatch: the superRefine validation blocks configs with both include and exclude set, contradicting the documented behavior. Additionally, Discord/Slack help text promises functionality that isn't implemented. - `src/config/zod-schema.core.ts` — the `superRefine` block will reject configs rather than warn. `src/config/schema.help.ts` — help text for Discord/Slack is premature. <sub>Last reviewed commit: 0bc2ca9</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs