Files
ChatLab/docs/tw/chatlab-format.md
T

394 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ChatLab 標準化格式規範 v0.0.2
ChatLab 定義了一套標準的聊天記錄資料交換格式,用於支援多平台資料的統一匯入和分析。
只要你將聊天記錄轉為該格式,那麼就可以被 ChatLab 解析並使用其分析能力。
::: warning 注意
該格式規範目前仍處於早期制定階段,部分欄位和結構可能會在後續版本中調整。
:::
## 概述
### 支援的檔案格式
| 格式 | 副檔名 | 適用場景 |
| --------- | -------- | --------------------------------------------------- |
| **JSON** | `.json` | 中小型記錄(<100 萬條),結構清晰,易於閱讀 |
| **JSONL** | `.jsonl` | 超大規模記錄(>100 萬條),流式處理,記憶體佔用恆定 |
### 格式對比
| 特性 | JSON | JSONL |
| ------------ | ---------------------- | ----------------------- |
| 記憶體佔用 | 需載入完整結構 | 逐行處理,恆定 (~100MB) |
| 檔案大小限制 | ~1GB(取決於記憶體) | 無實際限制 |
| 追加寫入 | ❌ 需重寫整個檔案 | ✅ 直接追加行 |
| 錯誤復原 | 單處錯誤整檔案失效 | 可跳過錯誤行繼續 |
| 可讀性 | ⭐⭐⭐ 易於閱讀 | ⭐⭐ 每行一條記錄 |
| 推薦場景 | 小中型記錄 (<100 萬條) | 大型記錄 (>100 萬條) |
## 快速說明
以下是一個**最小化**的 ChatLab 格式範例,只包含必要欄位:
```json
{
"chatlab": {
"version": "0.0.2",
"exportedAt": 1703001600
},
"meta": {
"name": "我的群聊",
"platform": "qq",
"type": "group"
},
"members": [
{
"platformId": "123456",
"accountName": "張三"
}
],
"messages": [
{
"sender": "123456",
"accountName": "張三",
"timestamp": 1703001600,
"type": 0,
"content": "大家好!"
}
]
}
```
---
## JSON 格式詳細說明
### 檔案頭 (chatlab)
| 欄位 | 類型 | 必填 | 說明 |
| ------------- | ------ | ---- | ---------------------------- |
| `version` | string | ✅ | 格式版本號,目前為 `"0.0.2"` |
| `exportedAt` | number | ✅ | 匯出時間(秒級 Unix 時間戳) |
| `generator` | string | - | 產生工具名稱 |
| `description` | string | - | 描述資訊 |
### 元資訊 (meta)
| 欄位 | 類型 | 必填 | 說明 |
| ------------- | ------------- | ---- | -------------------------------------------------------- |
| `name` | string | ✅ | 群名或對話名 |
| `platform` | string | ✅ | 平台標識,如 `qq` / `wechat` / `discord` / `whatsapp` 等 |
| `type` | string | ✅ | 聊天類型:`group`(群聊)/ `private`(私聊) |
| `groupId` | string | - | 群 ID(僅群聊) |
| `groupAvatar` | string | - | 群頭像(Data URL 格式) |
| `ownerId` | string | - | 所有者/匯出者的 platformId |
| `sources` | MergeSource[] | - | 合併來源(合併工具產生,見下方說明) |
#### MergeSource 結構(合併來源)
當使用合併工具合併多個聊天記錄檔案時,`sources` 欄位會記錄原始檔案的來源資訊:
| 欄位 | 類型 | 必填 | 說明 |
| -------------- | ------ | ---- | -------- |
| `filename` | string | ✅ | 原檔名 |
| `platform` | string | - | 原平台 |
| `messageCount` | number | ✅ | 訊息數量 |
### 成員 (members)
| 欄位 | 類型 | 必填 | 說明 |
| --------------- | ------------ | ---- | --------------------------- |
| `platformId` | string | ✅ | 使用者唯一標識 |
| `accountName` | string | ✅ | 帳號名稱 |
| `groupNickname` | string | - | 群暱稱(僅群聊) |
| `aliases` | string[] | - | 使用者自訂別名 |
| `avatar` | string | - | 使用者頭像(Data URL 格式) |
| `roles` | MemberRole[] | - | 成員角色(可多個) |
#### 角色 (roles)
成員可以擁有一個或多個角色,用於標示群主、管理員等身份:
| 欄位 | 類型 | 必填 | 說明 |
| ------ | ------ | ---- | ------------------------------------ |
| `id` | string | ✅ | 角色標識:`owner` / `admin` / 自訂ID |
| `name` | string | - | 角色顯示名稱(自訂角色需要) |
**標準角色 ID**
| ID | 說明 |
| ------- | ----------- |
| `owner` | 群主/建立者 |
| `admin` | 管理員 |
**角色範例:**
```json
// 群主
"roles": [{ "id": "owner" }]
// 管理員
"roles": [{ "id": "admin" }]
// 多角色
"roles": [
{ "id": "owner" },
{ "id": "tech-team", "name": "技術組" },
{ "id": "vip", "name": "VIP會員" }
]
```
### 訊息 (messages)
| 欄位 | 類型 | 必填 | 說明 |
| ------------------- | -------------- | ---- | --------------------------------- |
| `sender` | string | ✅ | 發送者的 `platformId` |
| `accountName` | string | ✅ | 發送時的帳號名稱 |
| `groupNickname` | string | - | 發送時的群暱稱 |
| `timestamp` | number | ✅ | 秒級 Unix 時間戳 |
| `type` | number | ✅ | 訊息類型(見下方對照表) |
| `content` | string \| null | ✅ | 訊息內容(非文字訊息可為 `null` |
| `platformMessageId` | string | - | 訊息的平台原始 ID |
| `replyToMessageId` | string | - | 回覆的目標訊息 ID |
#### 訊息 ID 與回覆關係說明
**`platformMessageId`**(訊息的平台原始 ID):
- 儲存訊息在原始平台上的唯一標識(如 Discord 的 snowflake ID、QQ 的訊息 ID
- 用於在查詢時關聯 `replyToMessageId`,以顯示被回覆訊息的內容
- 如果平台不提供訊息 ID,可省略此欄位
**`replyToMessageId`**(回覆的目標訊息 ID):
- 儲存被回覆訊息的**平台原始 ID**
- 透過與其他訊息的 `platformMessageId` 關聯,可查詢被回覆訊息的內容和發送者
- 僅當訊息是回覆類型時才有意義
- 如果平台不支援或資料不包含回覆關係,可省略此欄位
---
## 訊息類型對照表
::: tip 提示
若您的聊天記錄中有其他特殊類型需要支援,請提交 issue 說明情況,我們會評估是否加入標準訊息類型中。
:::
### 基礎訊息類型 (0-19)
| 值 | 名稱 | 說明 |
| --- | -------- | ----------- |
| 0 | TEXT | 文字訊息 |
| 1 | IMAGE | 圖片 |
| 2 | VOICE | 語音 |
| 3 | VIDEO | 影片 |
| 4 | FILE | 檔案 |
| 5 | EMOJI | 表情包/貼紙 |
| 7 | LINK | 連結/卡片 |
| 8 | LOCATION | 位置 |
### 互動訊息類型 (20-39)
| 值 | 名稱 | 說明 |
| --- | ---------- | ---------------------- |
| 20 | RED_PACKET | 紅包 |
| 21 | TRANSFER | 轉帳 |
| 22 | POKE | 拍一拍/戳一戳 |
| 23 | CALL | 語音/視訊通話 |
| 24 | SHARE | 分享(音樂、小程序等) |
| 25 | REPLY | 引用回覆 |
| 26 | FORWARD | 轉傳訊息 |
| 27 | CONTACT | 名片訊息 |
### 系統訊息類型 (80+)
| 值 | 名稱 | 說明 |
| --- | ------ | ------------------------------ |
| 80 | SYSTEM | 系統訊息(入群/退群/群公告等) |
| 81 | RECALL | 撤回訊息 |
| 99 | OTHER | 其他/未知 |
## 頭像格式說明
頭像欄位 `avatar``groupAvatar` 支援兩種格式:
### 1. Data URL
內嵌式格式,圖片資料直接編碼在檔案中,離線可用:
```
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...
```
支援的圖片 MIME 類型:
- `image/jpeg` - JPEG 格式(推薦,體積較小)
- `image/png` - PNG 格式
- `image/gif` - GIF 格式
- `image/webp` - WebP 格式
### 2. 網路 URL
外連格式,圖片儲存在網路伺服器,體積更小但需網路存取:
```
https://example.com/avatars/user123.jpg
```
::: tip 建議
- 如果需要離線使用或長期存檔,推薦使用 Data URL 格式
- 匯出 Data URL 時建議將頭像壓縮為 100×100 像素以內,以減小檔案體積
- 如果頭像來自可靠的長期有效的 CDN,可使用網路 URL 以減小檔案體積 :::
## 完整範例
### 群聊範例(含可選欄位)
```json
{
"chatlab": {
"version": "0.0.2",
"exportedAt": 1703001600,
"generator": "My Converter Tool",
"description": "2024年技術交流群聊天記錄備份"
},
"meta": {
"name": "技術交流群",
"platform": "wechat",
"type": "group",
"groupId": "38988428513",
"groupAvatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"ownerId": "abc123"
},
"members": [
{
"platformId": "abc123",
"accountName": "張三",
"groupNickname": "群主-張三",
"avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"roles": [{ "id": "owner" }]
},
{
"platformId": "def456",
"accountName": "李四",
"groupNickname": "管理員",
"avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"roles": [{ "id": "admin" }]
}
],
"messages": [
{
"platformMessageId": "msg_001",
"sender": "abc123",
"accountName": "張三",
"groupNickname": "群主-張三",
"timestamp": 1703001600,
"type": 0,
"content": "大家好!歡迎加入技術交流群~"
},
{
"platformMessageId": "msg_002",
"sender": "def456",
"accountName": "李四",
"groupNickname": "管理員",
"timestamp": 1703001610,
"type": 25,
"content": "收到!",
"replyToMessageId": "msg_001"
}
]
}
```
### 私聊範例
```json
{
"chatlab": {
"version": "0.0.2",
"exportedAt": 1703001600
},
"meta": {
"name": "與小明的對話",
"platform": "qq",
"type": "private"
},
"members": [
{
"platformId": "123456789",
"accountName": "我",
"avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
},
{
"platformId": "987654321",
"accountName": "小明",
"avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
}
],
"messages": [
{
"sender": "123456789",
"accountName": "我",
"timestamp": 1703001600,
"type": 0,
"content": "在嗎?"
}
]
}
```
## JSONL 流式格式
JSONLJSON Lines)格式適用於**超大規模聊天記錄**(>100 萬條),可避免記憶體溢位問題。
### 格式特點
- 每行一個 JSON 物件
- 透過 `_type` 欄位區分行類型:`header` / `member` / `message`
- 記憶體佔用恆定(約 100MB),支援 GB 級檔案
- 支援串流寫入,可邊匯出邊追加
### 行類型說明
| `_type` | 說明 | 是否必需 |
| --------- | -------------------------------- | --------------- |
| `header` | 檔案頭,包含 `chatlab``meta` | ✅ 必須在第一行 |
| `member` | 成員資訊 | - 可選 |
| `message` | 訊息記錄 | ✅ 至少一條 |
### 完整範例
```jsonl
{"_type":"header","chatlab":{"version":"0.0.2","exportedAt":1703001600},"meta":{"name":"技術交流群","platform":"qq","type":"group"}}
{"_type":"member","platformId":"123456","accountName":"張三","groupNickname":"群主","roles":[{"id":"owner"}]}
{"_type":"member","platformId":"789012","accountName":"李四"}
{"_type":"message","platformMessageId":"msg_001","sender":"123456","accountName":"張三","groupNickname":"群主","timestamp":1703001600,"type":0,"content":"大家好!"}
{"_type":"message","sender":"789012","accountName":"李四","timestamp":1703001610,"type":0,"content":"你好!"}
{"_type":"message","sender":"123456","accountName":"張三","groupNickname":"群主","timestamp":1703001620,"type":1,"content":"[圖片]"}
```
### 解析規則
1. **第一行必須是 header**:包含 `chatlab` 版本和 `meta` 元資訊
2. **成員行在訊息之前**:可選,如果省略,成員資訊會從訊息中自動收集
3. **訊息按時間順序排列**:建議按 `timestamp` 升冪排列
4. **每行獨立完整**:單行解析錯誤可跳過繼續處理
5. **支援註解行**:以 `#` 開頭的行會被跳過(可用於新增備註)
::: warning 注意
- 每行必須是**有效的 JSON**(不能跨行)
- 行之間用換行符 `\n` 分隔
:::
## 版本歷史
| 版本 | 日期 | 變更 |
| ----- | ---------- | ------------------------------------------------------------------------------ |
| 0.0.1 | 2025-12-22 | 初始版本 |
| 0.0.2 | 2026-01-09 | 新增 roles、ownerId、platformMessageId、replyToMessageId 欄位;新增 JSONL 格式 |