feat: add NapCat built-in adapter with configuration, filters, and transport layer
- Implemented configuration parsing for NapCat adapter including server, chat, and filter settings. - Added message filtering logic to handle inbound chat messages based on user and group lists. - Developed a transport layer for WebSocket communication with the NapCat server. - Created a query service for fetching user and group information from the QQ platform. - Implemented runtime state management to report connection status to the host. - Added notice handling for various QQ platform events.
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.platform_io.drivers.base import PlatformIODriver
|
||||
|
||||
@@ -438,12 +435,17 @@ class PlatformIOManager:
|
||||
|
||||
Returns:
|
||||
Optional[str]: 若可以构造稳定去重键则返回该键,否则返回 ``None``。
|
||||
|
||||
Notes:
|
||||
这里仅接受上游显式提供的稳定消息身份,例如 ``dedupe_key``、
|
||||
平台侧 ``external_message_id`` 或已经完成规范化的
|
||||
``session_message.message_id``。Broker 不再根据 ``payload`` 内容
|
||||
猜测语义去重键,避免把“短时间内两条内容刚好完全相同”的合法消息
|
||||
误判为重复入站。
|
||||
"""
|
||||
raw_dedupe_key = envelope.dedupe_key or envelope.external_message_id
|
||||
if raw_dedupe_key is None and envelope.session_message is not None:
|
||||
raw_dedupe_key = envelope.session_message.message_id
|
||||
if raw_dedupe_key is None and envelope.payload is not None:
|
||||
raw_dedupe_key = PlatformIOManager._build_payload_fingerprint(envelope.payload)
|
||||
if raw_dedupe_key is None:
|
||||
return None
|
||||
|
||||
@@ -453,29 +455,6 @@ class PlatformIOManager:
|
||||
|
||||
return f"{envelope.route_key.to_dedupe_scope()}:{normalized_dedupe_key}"
|
||||
|
||||
@staticmethod
|
||||
def _build_payload_fingerprint(payload: Dict[str, Any]) -> Optional[str]:
|
||||
"""根据消息载荷构造稳定指纹。
|
||||
|
||||
Args:
|
||||
payload: 待构造指纹的原始载荷字典。
|
||||
|
||||
Returns:
|
||||
Optional[str]: 若成功生成指纹则返回十六进制摘要,否则返回 ``None``。
|
||||
"""
|
||||
try:
|
||||
serialized_payload = json.dumps(
|
||||
payload,
|
||||
default=str,
|
||||
ensure_ascii=True,
|
||||
separators=(",", ":"),
|
||||
sort_keys=True,
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
return hashlib.sha256(serialized_payload.encode()).hexdigest()
|
||||
|
||||
@staticmethod
|
||||
def _validate_binding_against_driver(binding: RouteBinding, driver: PlatformIODriver) -> None:
|
||||
"""校验路由绑定与驱动描述是否一致。
|
||||
|
||||
@@ -198,8 +198,9 @@ class InboundMessageEnvelope:
|
||||
driver_kind: 产出该消息的驱动类型。
|
||||
external_message_id: 可选的平台侧消息 ID,用于去重。
|
||||
dedupe_key: 可选的显式去重键。当外部消息没有稳定 ``message_id`` 时,
|
||||
可由上游驱动提供消息指纹。若这里为空,中间层仍可能继续回退到
|
||||
``session_message.message_id`` 或 ``payload`` 指纹。
|
||||
可由上游驱动提供稳定的技术性幂等键。若这里为空,中间层仅会继续
|
||||
回退到 ``external_message_id`` 或 ``session_message.message_id``,
|
||||
不会再根据 ``payload`` 内容猜测语义去重键。
|
||||
session_message: 可选的、已经完成规范化的 ``SessionMessage`` 对象。
|
||||
payload: 可选的原始字典载荷,供延迟转换或调试使用。
|
||||
metadata: 额外入站元数据,例如连接信息或追踪上下文。
|
||||
|
||||
Reference in New Issue
Block a user