Metadata-Version: 2.5
Name: python-library-napcat-adapter
Version: 0.3.6
Summary: NapCat CQ 消息段与 OneBot 载荷互转及接入
Requires-Python: >=3.10
Requires-Dist: napcat-sdk
Requires-Dist: pydantic<3,>=2.0
Requires-Dist: python-library-onebot-protocol==0.4.0
Description-Content-Type: text/markdown

# NapCat Adapter API

`napcat_adapter.Adapter` 把 NapCat 正向 WebSocket 消息转换为统一的 OneBot 消息载荷，并提供发送与历史消息读取能力。

## 模块职责

- `adapter.py`：对外入口，暴露生命周期、消息回调、发送、状态和历史读取。
- `bot.py`：管理 NapCat 客户端连接，执行 SDK 收发、`get_status`、`get_msg` 与 `get_forward_msg` 查询。
- `raw_media.py`：比较 OneBot 消息和 `debug.raw`，补回转换阶段缺少的媒体段。
- `protocol_adapt.py`：转换 NapCat/CQ 消息段和 `onebot_protocol.MessagePayload`。
- `models.py`：保存适配器内部消息与消息段模型。

## Adapter

### 生命周期

`Adapter(ws_url, token=None, reconnect_interval_seconds=5.0, listeners=None)` 创建实例。重连间隔以秒为单位，`listeners` 接收 `Listener` 列表。调用 `run()` 后开始连接；调用 `stop()` 请求停止。连接未就绪时，发送和历史读取会抛出 `RuntimeError`。

### 接收入站消息

`on_message(callback)` 注册异步回调，也支持 `@adapter.on_message()` 装饰器写法。回调接收一个 `MessagePayload`。群聊实时入站会无损上报全部消息；`mentioned_self` 表示是否 @ 当前机器人，触发策略由上层应用决定。载荷同时保留发送者 ID、显示名称和平台时间戳。

NapCat 开启 `debug` 后，如果 `raw.elements` 中的图片、语音、视频、文件或长消息没有出现在 OneBot `message` 中，Adapter 会补回有 URL、路径或资源 ID 的段。图片缺少直接引用，或 QQ 返回的本地缓存路径已经失效时，Adapter 调用 `get_image` 获取新 URL；每张最多等待 2.5 秒且多张并发查询。长消息交给现有 `get_forward_msg` 展开。仍不可读的媒体合并为一条文本说明。没有 `raw`、OneBot 段完整或本地路径仍可读时不增加接口请求。

当 NapCat 丢失引用段时，Adapter 会用 `raw.elements.replyElement` 定位 `raw.records` 中的被引用记录，在有界内存缓存中恢复引用文字和媒体。引用记录只供 `get_message()` 查询，不会混入当前消息附件；缓存最多保留 256 条。

真实 OneBot 引用 ID 始终优先通过 `get_msg` 读取，以刷新可能已经过期的图片 URL；事件内 `raw.records` 缓存只在平台查询失败时兜底。仅 Adapter 生成的 `raw-record:` 合成 ID 会直接读取缓存。

### 发送消息

`await send(payload)` 发送一个 `MessagePayload`。图片、语音、文件和视频按 NapCat 支持的 CQ 消息段转换；底层发送失败时异常向调用方传播。

### 读取账号状态

`await get_status()`主动调用NapCat `get_status`并返回`AccountStatus`。字段分别表示WebSocket连接、探针成功、QQ在线、NapCat运行健康、账号ID与原因。只有`connected`、`probe_ok`、`online`、`good`全部为真且账号ID可用时，`reason`才是`ready`。

探针超时返回`probe_failed`，QQ离线返回`offline`，运行状态异常返回`degraded`。历史`self_id`只用于诊断，不能把这些状态提升为`ready`。

### 读取历史消息

`await get_message(message_id, *, message_type=None, peer_id=None)` 返回 `MessagePayload | None`。省略可选参数时保持原有行为。

- 查询通过 NapCat OneBot `get_msg` 完成，不改变机器人状态。
- `message_type` 和 `peer_id` 指定当前会话。返回的群号与 `peer_id` 不同时返回 `None`；NapCat 未返回群号时使用 `peer_id` 补全。
- 历史群消息不执行实时入站的 @ 过滤，便于恢复被引用内容。
- 消息不存在、类型不支持、缺少会话或发送者字段时返回 `None`。
- 客户端未连接时抛出 `RuntimeError`；其他 SDK 异常向调用方传播。

### 合并转发消息

实时消息和 `get_message` 返回值中的 `forward` 段会通过 NapCat `get_forward_msg` 补充节点内容。已有内联 `content` 时不再请求接口。节点保留发送者、昵称、时间和消息段，嵌套转发最多展开 4 层，单条输入最多读取 100 个节点；重复 ID 时停止继续展开。接口失败会保留段 ID 和空内容，不中断整条消息。
