新增 LINE 官方账号对接的全套功能,包括: 1. 基础的 Bot 探测、会话解析、消息格式化能力 2. 富媒体消息模板、快速回复、卡片指令支持 3. Webhook 签名验证、重放防护、多账户路由管理 4. 消息发送、回复、分块传输、用户绑定管理 5. 交互式配置向导与诊断工具
65 lines
2.2 KiB
Python
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]}]
|