662ee48533
- format_success() creates card with green theme - format_error() creates card with red theme - format_info() creates card with blue theme - format_paginated() adds [N/M] marker - _build_card() creates three-zone structure (header/elements/actions) - _build_actions() creates interactive button elements All 6 tests pass. Card JSON uses schema 2.0 with lark_md content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
"""
|
|
Response formatter for Feishu Card messages.
|
|
|
|
This module provides classes for formatting responses as Feishu Card JSON 2.0
|
|
messages with three-zone structure (header/content/actions).
|
|
"""
|
|
from dataclasses import dataclass
|
|
from typing import Dict, Any, List, Optional
|
|
from enum import Enum
|
|
|
|
|
|
class CardTheme(Enum):
|
|
"""Theme colors for Feishu Card messages."""
|
|
SUCCESS = "green"
|
|
ERROR = "red"
|
|
INFO = "blue"
|
|
WARNING = "orange"
|
|
|
|
|
|
@dataclass
|
|
class CardButton:
|
|
"""Interactive button for Feishu Card actions."""
|
|
text: str
|
|
value: Dict[str, Any]
|
|
button_type: str = "primary" # primary, default, danger
|
|
|
|
|
|
class FeishuResponseFormatter:
|
|
"""Format responses as Feishu Card messages."""
|
|
|
|
def format_success(self, title: str, content: str,
|
|
buttons: Optional[List[CardButton]] = None) -> dict:
|
|
"""Format a success response card with green theme."""
|
|
return self._build_card(title, content, CardTheme.SUCCESS, buttons)
|
|
|
|
def format_error(self, title: str, content: str,
|
|
buttons: Optional[List[CardButton]] = None) -> dict:
|
|
"""Format an error response card with red theme."""
|
|
return self._build_card(title, content, CardTheme.ERROR, buttons)
|
|
|
|
def format_info(self, title: str, content: str,
|
|
buttons: Optional[List[CardButton]] = None) -> dict:
|
|
"""Format an info response card with blue theme."""
|
|
return self._build_card(title, content, CardTheme.INFO, buttons)
|
|
|
|
def format_paginated(self, title: str, content: str,
|
|
page: int, total_pages: int) -> dict:
|
|
"""Format a paginated response with [page/total] marker."""
|
|
footer = f"\n\n---\n[{page}/{total_pages}]"
|
|
return self._build_card(title, content + footer, CardTheme.INFO)
|
|
|
|
def _build_card(self, title: str, content: str, theme: CardTheme,
|
|
buttons: Optional[List[CardButton]] = None) -> dict:
|
|
"""Build complete card JSON structure."""
|
|
card = {
|
|
"schema": "2.0",
|
|
"config": {"wide_screen_mode": True},
|
|
"header": {
|
|
"title": {"tag": "plain_text", "content": title},
|
|
"template": theme.value
|
|
},
|
|
"elements": [
|
|
{"tag": "div", "text": {"tag": "lark_md", "content": content}}
|
|
]
|
|
}
|
|
if buttons:
|
|
card["elements"].append(self._build_actions(buttons))
|
|
return card
|
|
|
|
def _build_actions(self, buttons: List[CardButton]) -> dict:
|
|
"""Build actions element from button list."""
|
|
return {
|
|
"tag": "action",
|
|
"actions": [
|
|
{
|
|
"tag": "button",
|
|
"text": {"tag": "plain_text", "content": btn.text},
|
|
"type": btn.button_type,
|
|
"value": btn.value
|
|
}
|
|
for btn in buttons
|
|
]
|
|
}
|