ForcePilot/backend/package/yuxi/channels/adapters/line/formatter.py
Kris a4ec94ef9d feat(line): 实现完整的 LINE 聊天适配器功能
新增 LINE 官方账号对接的全套功能,包括:
1. 基础的 Bot 探测、会话解析、消息格式化能力
2. 富媒体消息模板、快速回复、卡片指令支持
3. Webhook 签名验证、重放防护、多账户路由管理
4. 消息发送、回复、分块传输、用户绑定管理
5. 交互式配置向导与诊断工具
2026-05-12 00:45:33 +08:00

65 lines
2.2 KiB
Python

from __future__ import annotations
from yuxi.channels.adapters.line.directives import parse_line_directives
from yuxi.channels.adapters.line.markdown_to_line import (
_safe_truncate,
markdown_to_line_decorated,
markdown_to_line_text,
)
from yuxi.channels.models import ChannelResponse
class LINEMessageFormatter:
MAX_CONTENT_LENGTH = 5000
MAX_MESSAGES_PER_REQUEST = 5
def format(self, response: ChannelResponse) -> list[dict]:
content = response.content
directive_messages = parse_line_directives(content)
if directive_messages:
return directive_messages[: self.MAX_MESSAGES_PER_REQUEST]
msg_type = response.metadata.get("line_message_type", "text")
metadata = response.metadata
if msg_type == "flex":
alt_text = metadata.get("alt_text", "Flex Message")
contents = metadata.get("flex_contents", {})
return [
{
"type": "flex",
"altText": alt_text[:400],
"contents": contents,
}
]
if msg_type == "template":
template = metadata.get("template", {})
alt_text = metadata.get("alt_text", "Template Message")
return [
{
"type": "template",
"altText": alt_text[:400],
"template": template,
}
]
use_decorated = metadata.get("line_decorated_text", True)
if metadata.get("strip_markdown", True):
if use_decorated:
content = markdown_to_line_decorated(content)
else:
content = markdown_to_line_text(content)
if len(content) > self.MAX_CONTENT_LENGTH:
messages = []
remaining = content
while remaining and len(messages) < self.MAX_MESSAGES_PER_REQUEST:
chunk = _safe_truncate(remaining, self.MAX_CONTENT_LENGTH)
remaining = remaining[len(chunk) :]
messages.append({"type": "text", "text": chunk})
return messages
return [{"type": "text", "text": content[: self.MAX_CONTENT_LENGTH]}]