ForcePilot/backend/package/yuxi/channel/extensions/telegram/inline_keyboard.py

87 lines
2.3 KiB
Python
Raw Normal View History

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}"),
]
])