feat: 添加带有消息处理和路由功能的NEW_napcat_adapter插件
- 为NEW_napcat_adapter插件实现了核心模块,包括消息处理、事件处理和路由。 - 创建了MessageHandler、MetaEventHandler和NoticeHandler来处理收到的消息和事件。 - 开发了SendHandler,用于向Napcat发送回消息。 引入了StreamRouter来管理多个聊天流,确保消息的顺序和高效处理。 - 增加了对各种消息类型和格式的支持,包括文本、图像和通知。 - 建立了一个用于监控和调试的日志系统。
This commit is contained in:
110
src/mofox_bus/builder.py
Normal file
110
src/mofox_bus/builder.py
Normal file
@@ -0,0 +1,110 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import uuid
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from .types import GroupInfoPayload, MessageEnvelope, MessageInfoPayload, SegPayload, UserInfoPayload
|
||||
|
||||
|
||||
class MessageBuilder:
|
||||
"""
|
||||
Fluent helper to build MessageEnvelope safely with type hints.
|
||||
|
||||
Example:
|
||||
msg = (
|
||||
MessageBuilder()
|
||||
.text("Hello")
|
||||
.image("http://example.com/1.png")
|
||||
.to_user("123", platform="qq")
|
||||
.build()
|
||||
)
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._direction: str = "outgoing"
|
||||
self._message_info: MessageInfoPayload = {}
|
||||
self._segments: List[SegPayload] = []
|
||||
self._metadata: Dict[str, Any] | None = None
|
||||
self._timestamp_ms: int | None = None
|
||||
self._message_id: str | None = None
|
||||
|
||||
def direction(self, value: str) -> "MessageBuilder":
|
||||
self._direction = value
|
||||
return self
|
||||
|
||||
def message_id(self, value: str) -> "MessageBuilder":
|
||||
self._message_id = value
|
||||
return self
|
||||
|
||||
def timestamp_ms(self, value: int | None = None) -> "MessageBuilder":
|
||||
self._timestamp_ms = value or int(time.time() * 1000)
|
||||
return self
|
||||
|
||||
def metadata(self, value: Dict[str, Any]) -> "MessageBuilder":
|
||||
self._metadata = value
|
||||
return self
|
||||
|
||||
def platform(self, value: str) -> "MessageBuilder":
|
||||
self._message_info["platform"] = value
|
||||
return self
|
||||
|
||||
def from_user(self, user_id: str, *, platform: str | None = None, nickname: str | None = None) -> "MessageBuilder":
|
||||
if platform:
|
||||
self.platform(platform)
|
||||
user_info: UserInfoPayload = {"user_id": user_id}
|
||||
if nickname:
|
||||
user_info["user_nickname"] = nickname
|
||||
self._message_info["user_info"] = user_info
|
||||
return self
|
||||
|
||||
def from_group(self, group_id: str, *, platform: str | None = None, name: str | None = None) -> "MessageBuilder":
|
||||
if platform:
|
||||
self.platform(platform)
|
||||
group_info: GroupInfoPayload = {"group_id": group_id}
|
||||
if name:
|
||||
group_info["group_name"] = name
|
||||
self._message_info["group_info"] = group_info
|
||||
return self
|
||||
|
||||
def seg(self, type_: str, data: Any) -> "MessageBuilder":
|
||||
self._segments.append({"type": type_, "data": data})
|
||||
return self
|
||||
|
||||
def text(self, content: str) -> "MessageBuilder":
|
||||
return self.seg("text", content)
|
||||
|
||||
def image(self, url: str) -> "MessageBuilder":
|
||||
return self.seg("image", url)
|
||||
|
||||
def reply(self, target_message_id: str) -> "MessageBuilder":
|
||||
return self.seg("reply", target_message_id)
|
||||
|
||||
def raw_segment(self, segment: SegPayload) -> "MessageBuilder":
|
||||
self._segments.append(segment)
|
||||
return self
|
||||
|
||||
def build(self) -> MessageEnvelope:
|
||||
# message_info defaults
|
||||
if not self._segments:
|
||||
raise ValueError("message_segment is required, add at least one segment before build()")
|
||||
if self._message_id is None:
|
||||
self._message_id = str(uuid.uuid4())
|
||||
info = dict(self._message_info)
|
||||
info.setdefault("message_id", self._message_id)
|
||||
info.setdefault("time", time.time())
|
||||
|
||||
segments = [seg.copy() if isinstance(seg, dict) else seg for seg in self._segments]
|
||||
envelope: MessageEnvelope = {
|
||||
"direction": self._direction, # type: ignore[assignment]
|
||||
"message_info": info,
|
||||
"message_segment": segments[0] if len(segments) == 1 else list(segments),
|
||||
}
|
||||
if self._metadata is not None:
|
||||
envelope["metadata"] = self._metadata
|
||||
if self._timestamp_ms is not None:
|
||||
envelope["timestamp_ms"] = self._timestamp_ms
|
||||
return envelope
|
||||
|
||||
|
||||
__all__ = ["MessageBuilder"]
|
||||
Reference in New Issue
Block a user