ForcePilot/backend/package/yuxi/channel/extensions/telegram/inline_keyboard.py
Kris 8a3601250e feat(channel): 添加 Telegram 渠道扩展
新增 Telegram 渠道扩展,支持在 Yuxi 平台中集成 Telegram 即时通讯渠道。

包含以下功能模块:
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- polling: 长轮询模式
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- session: 会话管理
- actions: 动作处理
- inline_keyboard: 内联键盘
- native_commands: 原生指令
- chat: 聊天管理
- delivery: 消息送达确认
- media: 媒体资源处理
- profile: 用户资料
- reactions: 表情反应
- sticker: 贴纸处理
- types: 类型定义
2026-05-21 11:48:09 +08:00

87 lines
2.3 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from enum import StrEnum
class KeyboardScope(StrEnum):
OFF = "off"
DM = "dm"
GROUP = "group"
ALL = "all"
ALLOWLIST = "allowlist"
@dataclass
class InlineButton:
text: str
url: str | None = None
callback_data: str | None = None
copy_text: str | None = None
style: str | None = None
icon_custom_emoji_id: str | None = None
@dataclass
class InlineKeyboard:
rows: list[list[InlineButton]] = field(default_factory=list)
def to_telegram_markup(self) -> dict | None:
if not self.rows:
return None
return {
"inline_keyboard": [
[
_build_button_cell(btn)
for btn in row
]
for row in self.rows
]
}
def _build_button_cell(btn: InlineButton) -> dict:
cell: dict = {"text": btn.text}
if btn.url:
cell["url"] = btn.url
elif btn.callback_data:
cell["callback_data"] = btn.callback_data
if btn.copy_text:
cell["copy_text"] = {"text": btn.copy_text}
if btn.style:
cell["style"] = btn.style
if btn.icon_custom_emoji_id:
cell["icon_custom_emoji_id"] = btn.icon_custom_emoji_id
return cell
def build_model_selector(models: list[str], selected: str | None = None, prefix: str = "model") -> InlineKeyboard:
if not models:
return InlineKeyboard()
rows: list[list[InlineButton]] = []
current_row: list[InlineButton] = []
for i, model in enumerate(models):
label = f"{'' if model == selected else ''}{model}"
btn = InlineButton(text=label, callback_data=f"{prefix}:{model}")
current_row.append(btn)
if len(current_row) >= 2 or i == len(models) - 1:
rows.append(current_row)
current_row = []
if current_row:
rows.append(current_row)
return InlineKeyboard(rows=rows)
def build_approval_keyboard(action_id: str) -> InlineKeyboard:
return InlineKeyboard(rows=[
[
InlineButton(text="✅ 批准", callback_data=f"approval:approve:{action_id}"),
InlineButton(text="❌ 拒绝", callback_data=f"approval:reject:{action_id}"),
]
])