新增 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: 类型定义
87 lines
2.3 KiB
Python
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}"),
|
|
]
|
|
])
|