Files
kefu/2026-08-19-18-27-34/.workbuddy/memory/2026-08-19.md
T
2026-08-27 14:04:28 +08:00

6.6 KiB
Raw Blame History

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关于系统... 残留清理为干净文本