feat(telegram): support quick-command-only menus

This commit is contained in:
stevehq26-bot 2026-05-18 14:38:37 +01:00 committed by Teknium
parent e80d3084e5
commit b1acf80e17
7 changed files with 144 additions and 3 deletions

View file

@ -1070,7 +1070,7 @@ def load_gateway_config() -> GatewayConfig:
if isinstance(group_allowed_chats, list):
group_allowed_chats = ",".join(str(v) for v in group_allowed_chats)
os.environ["TELEGRAM_GROUP_ALLOWED_CHATS"] = str(group_allowed_chats)
for _telegram_extra_key in ("guest_mode", "disable_link_previews"):
for _telegram_extra_key in ("guest_mode", "disable_link_previews", "command_menu"):
if _telegram_extra_key in telegram_cfg:
plat_data = platforms_data.setdefault(Platform.TELEGRAM.value, {})
if not isinstance(plat_data, dict):

View file

@ -1507,11 +1507,28 @@ class TelegramAdapter(BasePlatformAdapter):
BotCommandScopeDefault,
BotCommandScopeChat,
)
from hermes_cli.commands import telegram_menu_commands
from hermes_cli.commands import (
telegram_menu_commands,
telegram_quick_menu_commands,
)
# Telegram allows up to 100 commands but has an undocumented
# payload size limit (~4KB total). Limit to 30 core commands
# to stay well under the threshold while covering all categories.
menu_commands, hidden_count = telegram_menu_commands(max_commands=MAX_COMMANDS_PER_SCOPE)
if self.config.extra.get("command_menu") == "quick_commands_only":
# Fetch quick_commands via the gateway runner reference if
# available; otherwise fall back to PlatformConfig.extra.
_qc = self.config.extra.get("quick_commands")
if not isinstance(_qc, dict) or not _qc:
_runner_ref = getattr(self, "_runner_ref", None)
_runner = _runner_ref() if callable(_runner_ref) else None
_gw_cfg = getattr(_runner, "config", None) if _runner else None
_qc = getattr(_gw_cfg, "quick_commands", {}) or {}
menu_commands, hidden_count = telegram_quick_menu_commands(
_qc,
max_commands=MAX_COMMANDS_PER_SCOPE,
)
else:
menu_commands, hidden_count = telegram_menu_commands(max_commands=MAX_COMMANDS_PER_SCOPE)
bot_commands = [BotCommand(name, desc) for name, desc in menu_commands]
# Register for all scopes independently — Telegram picks the
# narrowest matching scope per chat type (forum topics fall