89 lines
6.6 KiB
Markdown
89 lines
6.6 KiB
Markdown
# 2026-08-19 工作日志
|
||
|
||
## 企业微信聊天记录导出(完成)
|
||
|
||
**成果**:成功导出 2 个已登录账号的全部聊天记录,共 **2792 条消息、88 个会话**。
|
||
|
||
**输出文件**(`wxwork_export/` 目录):
|
||
- `企业微信聊天记录.csv` / `.xlsx` — 全部消息(账号、会话、时间、发送者、消息类型、内容等 12 列)
|
||
- `会话汇总.csv` / `.xlsx` — 88 个会话的消息数与时间范围
|
||
- `聊天记录_1688856770803435.csv`(2756 条)、`聊天记录_1688855555743233.csv`(36 条)
|
||
- `decrypted/` — 解密后的 SQLite 数据库
|
||
|
||
**技术要点**:
|
||
- 企业微信 5.x 用 wxSQLite3 AES-128-CBC 加密(每页 4096B 独立加密,密钥派生 `MD5(raw_key + page_no(LE) + "sAlT")`)
|
||
- 16 字节原始密钥从 `WXWork.exe` 进程内存提取(内存中 `sAlT` 结构:`[key(16B)] + [page_no(4B LE)] + "sAlT"`)
|
||
- 已提取 2 个密钥存于 `wxwork_keys.json`:账号 1688856770803435(`db7288a3...`)、1688855555743233(`d18e7f9a...`)
|
||
- 表名:`message_table`(非 message)、`conversation_table`(非 session)、`user_table`(非 userinfo)
|
||
- 消息内容为 protobuf 编码,需递归解析 length-delimited 字段
|
||
|
||
**本轮修复的问题**:
|
||
1. `SyntaxWarning: invalid escape sequence '\-'` — 正则字符串中 `''` 提前终止字符串,改为中文引号 `“”‘’`
|
||
2. 5 条短文本消息(如"在不")被 `extra_content` 二进制替换 — 兜底条件从 `len(content)<3` 改为 `content.strip()` 为空
|
||
3. `?` 前缀残留(protobuf 内部 tag/length 字节 0x3F/0x7A 混入文本)— parse_content 中增加模式 A(`T 残留 T` 去重保留后半)和模式 B(前导 ASCII 残留清理,支持后跟中文标点)
|
||
|
||
**最终质量**:二进制残留 0、?前缀 0、空内容 0、控制字符 0。
|
||
|
||
**未完成/限制**:
|
||
- 8 个历史用户目录未解密(旧账号未登录,密钥不在内存)——需用户登录后重新提取密钥
|
||
- 部分 `S:` 群聊无名称显示为"群聊 S:xxxx"
|
||
- 脚本需用 venv python 运行(`pycryptodome`、`openpyxl` 装在 `~/.workbuddy/binaries/python/envs/default/`)
|
||
|
||
## 桌面应用打包(完成)
|
||
|
||
将导出能力打包为 Windows 桌面应用 **`dist/企业微信导出助手.exe`**(19MB 单文件,PyInstaller onefile + windowed + 自定义图标)。
|
||
|
||
**GUI 功能**(`wxwork_gui.py`):
|
||
- 一键导出全部聊天记录(CSV + Excel,含进度与日志面板)
|
||
- "重新提取密钥"按钮:扫描企微进程内存提取所有已登录账号密钥并保存到 exe 旁 `wxwork_keys.json`
|
||
- 每日定时自动导出(时间可设,应用运行期间到点自动触发)
|
||
- 输出目录可自定义(默认 exe 旁 `wxwork_export/`)、完成后一键打开文件夹
|
||
- 配置持久化到 `wxwork_gui_config.json`
|
||
|
||
**技术要点**:
|
||
- managed Python 3.13 无 tkinter → 改用系统 Python 3.11 建 venv:`C:\Users\pc\.workbuddy\binaries\python\envs\gui311`(继承 tkinter,装 pycryptodome/openpyxl/pyinstaller/pillow)
|
||
- PyInstaller 打包命令:`pyinstaller --onefile --windowed --name 企业微信导出助手 --icon app_icon.ico wxwork_gui.py`
|
||
- 路径兼容 onefile:`APP_DIR = sys.executable` 所在目录(frozen 模式),密钥/配置/输出目录都在 exe 旁
|
||
- 验证:exe 启动进程存活 ✅;打包环境完整导出(2792 消息 + xlsx 校验 2793 行)✅
|
||
- 交付:dist/ 含 exe + wxwork_keys.json(2 个已提取密钥)+ app_icon.png
|
||
|
||
## 按天/范围导出改造(完成)
|
||
|
||
用户需求:聊天记录可按"天数"导出(如只导今天)。
|
||
|
||
**核心脚本 `wxwork_export_final.py` v2.1**:
|
||
- `export_messages(dbs, out_dir, date_from=None, date_to=None)` — 日期范围过滤(含两端)
|
||
- CLI:`--days N`(最近 N 天含今天)、`--date YYYY-MM-DD`、`--all`;默认 `--days 1`
|
||
- 输出:单天 `按天/YYYY-MM-DD_聊天记录.csv`,多天 `按天/YYYY-MM-DD_至_YYYY-MM-DD_聊天记录.csv`,全量在根目录(原结构不变)
|
||
- 解密缓存:`decrypted/` 下已有解密文件时跳过(二次运行 1 秒,首次 1-2 分钟),`decrypt_with_keys(db_base, out_dir, keys_map, use_cache=True)`
|
||
- 实测:`--days 1` 今天 0 条正常提示;`--days 2` 正确导出 08-19 的 17 条
|
||
|
||
**GUI `wxwork_gui.py`**:
|
||
- 设置卡片新增「导出范围」下拉:只导今天/最近3天/7天/30天/全部历史(`DAYS_OPTIONS=[1,3,7,30,0]`)
|
||
- 导出按钮文字动态化(`_export_btn_text()`):"立即导出今天的聊天记录" / "最近 N 天" / "全部聊天记录"
|
||
- `do_export(keys, out_dir, log, days=N)` 计算 date_from/date_to 传给 export_messages;Excel 生成跟随实际 CSV 路径(按天模式在 按天/ 目录生成 xlsx);空范围返回 None 并提示"该时间范围内没有新消息"
|
||
- 定时自动导出也按所选范围执行;days 持久化到 config
|
||
- 清理 `_auto_loop` 死代码(`or True: pass`)
|
||
|
||
**打包**:重新 PyInstaller 打包 `dist/企业微信导出助手.exe`(19MB),启动验证 ✅,三种模式(days=2/1/0)打包环境实测通过
|
||
|
||
## 数据库导出 (CRM 绑定版, 完成)
|
||
|
||
用户需求:导出数据入库建表、只导出聊天记录、能否取 unionid 做 CRM 绑定。
|
||
|
||
**关键发现(unionid)**:
|
||
- `user_table.unionid` 字段存在且有数据:主账号 386 联系人中 332 个有 unionid(微信外部联系人,`ozynqs...` 开头);内部成员无 unionid 但 `account` 字段是企微 userid
|
||
- `message_table.sender_id` = `user_table.id` 可关联:2794 条消息中 1746 条(62%)能拿到 unionid
|
||
- 无 unionid 的消息主要是应用消息(489)/朋友圈(227)/图文链接(133) 等非人工对话
|
||
|
||
**新脚本 `wxwork_export_db.py`**(复用 wxwork_export_final.py 的 decrypt/parse 逻辑):
|
||
- 只导出聊天记录:消息表带 `sender_unionid/sender_userid/sender_mobile` 关联列(CRM 绑定键)
|
||
- 产出 `crm_import/`:`crm_wecom.db`(SQLite 三表:chat_messages/chat_users/chat_conversations,每次重建)、`聊天记录_仅消息.csv`(干净消息 CSV)、`create_tables_mysql.sql`、`create_tables_sqlite.sql`
|
||
- CLI:`--all` / `--days N` / `--date`;chat_users 总是全量(390 联系人,333 带 unionid)
|
||
- 实测:全量 2794 条 / 带 unionid 1746 条(62%);CRM 查询示例:高兴亮 669 条、李思佳 111 条
|
||
|
||
**解析增强(wxwork_export_final.py parse_content)**:
|
||
- 模式 C:单数字残留前缀剥离(`^[0-9](?=[\u4e00-\u9fff])(?![\u4e00-\u9fff]{0,2}(?:量词表))`),保护 "3月13日" 等合法文本
|
||
- 子串去重:meaningful 中互为子串的短文本跳过(`len(t)>=3`),消除 `A | 子串A` 冗余
|
||
- 修复效果:拼接冗余 596 → 0 条;`3关于系统...` 残留清理为干净文本
|