新增大量渠道适配器相关的协议、策略、工具类与基础设施代码,包括: 1. 多协议定义:认证、消息、配置、网关等核心接口 2. 策略模块:上下文、群聊、去重、防抖等业务策略 3. 工具集:重试、去重、文本分块、消息格式化等SDK工具 4. 基础设施:外部进程管理、事件广播、熔断机制等 5. 账户与管道系统:账户管理、消息处理管道实现 6. 运行时服务:状态收集、维护任务、日志等后台服务
113 lines
3.4 KiB
Python
113 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from yuxi.channels.models import ChannelResponse, DeliveryResult
|
|
|
|
|
|
class OutboundMixin:
|
|
"""出站消息能力 Mixin — 提供 send_text/send_media_url 等默认实现"""
|
|
|
|
async def send_text(self, chat_id: str, content: str) -> DeliveryResult:
|
|
identity = self._build_simple_identity(chat_id)
|
|
response = ChannelResponse(identity=identity, content=content)
|
|
return await self.send(response)
|
|
|
|
async def send_media_url(self, chat_id: str, media_url: str, media_type: str = "image") -> DeliveryResult:
|
|
identity = self._build_simple_identity(chat_id)
|
|
response = ChannelResponse(identity=identity, content=media_url, message_type=media_type) # type: ignore[arg-type]
|
|
return await self.send(response)
|
|
|
|
def _build_simple_identity(self, chat_id: str) -> Any:
|
|
from yuxi.channels.models import ChannelIdentity
|
|
|
|
return ChannelIdentity(
|
|
channel_id=getattr(self, "channel_id", ""),
|
|
channel_type=getattr(self, "channel_type", None),
|
|
channel_user_id="",
|
|
channel_chat_id=chat_id,
|
|
)
|
|
|
|
def sanitize_text(self, text: str) -> str:
|
|
return text
|
|
|
|
def chunker(self, text: str, limit: int) -> list[str]:
|
|
if len(text) <= limit:
|
|
return [text]
|
|
chunks = []
|
|
for i in range(0, len(text), limit):
|
|
chunks.append(text[i : i + limit])
|
|
return chunks
|
|
|
|
|
|
class MediaMixin:
|
|
"""媒体发送能力 Mixin"""
|
|
|
|
async def send_media(self, chat_id: str, media_type: str, data: Any) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
|
|
class ReactionMixin:
|
|
"""表情回应能力 Mixin"""
|
|
|
|
async def send_reaction(self, chat_id: str, msg_id: str, emoji: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
async def remove_reaction(self, chat_id: str, msg_id: str, emoji: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
|
|
class EditDeleteMixin:
|
|
"""消息编辑/删除能力 Mixin"""
|
|
|
|
async def edit_message(self, chat_id: str, msg_id: str, content: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
async def delete_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
|
|
class PinMixin:
|
|
"""消息置顶/取消置顶能力 Mixin"""
|
|
|
|
async def pin_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
async def unpin_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
async def list_pins(self, chat_id: str) -> list[dict]:
|
|
raise NotImplementedError
|
|
|
|
|
|
class UserInfoMixin:
|
|
"""用户信息获取能力 Mixin"""
|
|
|
|
async def get_user_info(self, channel_user_id: str) -> dict[str, Any]:
|
|
raise NotImplementedError
|
|
|
|
async def download_media(self, file_id: str) -> bytes:
|
|
raise NotImplementedError
|
|
|
|
|
|
class PollMixin:
|
|
"""投票能力 Mixin"""
|
|
|
|
async def create_poll(self, chat_id: str, question: str, options: list[str]) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
|
|
class StreamingMixin:
|
|
"""流式输出能力 Mixin"""
|
|
|
|
async def send_stream_chunk(self, chat_id: str, msg_id: str, chunk: str, finished: bool) -> DeliveryResult:
|
|
raise NotImplementedError
|
|
|
|
@property
|
|
def streaming_modes(self) -> list[str]:
|
|
return ["off"]
|
|
|
|
@property
|
|
def block_streaming(self) -> bool:
|
|
return False
|