# 交付通知未送达诊断(2026-07-09 职业卫生+舜珙血压计) ## 现象 Doro说"有几份合同没收到交付通知"。任务交付目录有文件,tracker状态=delivered。 ## 根因 今日凌晨01:27-02:15企微WebSocket连接中断(errcode 846609: aibot websocket not subscribed)。 Workflow的final_review步骤内部调用`_send_wecom(extra, 'doro', msg)`发送通知,但此时WS已断,通知静默失败。 ## 时间线 - 01:27:23 — 首次846609错误 - 01:28:01 — 职业卫生合同thread end(final_review完成,通知发送失败) - 01:30:41 — WebSocket closed (attempt 6) - 02:12:29 — 舜珙血压计thread end(final_review完成,通知发送失败) - 02:15:50 — WebSocket closed (attempt 7) - 02:18:30 — Doro发"hi",WS恢复 ## 诊断命令 ```bash # 1. 找tracker中delivered状态的合同 python3 -c "import json; t=json.load(open('~/.hermes/data/contract-tracker.json')); [print(c['delivered_filename']) for c in t['contracts'] if c.get('status')=='delivered']" # 2. 查gateway.log确认WS断连时段 grep '846609\|WebSocket error\|WebSocket closed' ~/.hermes/logs/gateway.log | grep '2026-07-09' # 3. 确认thread完成了final_review uwf step list # 看是否有final_revi步骤且有时长 # 4. 确认文件在任务交付目录 sudo docker exec nextcloud-nextcloud-1 stat "/var/www/html/data/doro/files/Doro合同审查任务/任务交付/【修】XXX.docx" ``` ## 补发方法 ```bash python3 ~/.hermes/scripts/wecom_dm.py --to doro --text "合同审查完成通知(补发): 1️⃣ 合同名称 顾问单位: XXX 修订: N处插入、M处删除 主要修订: ... (此通知因XX时段企微WebSocket连接中断未能实时送达,现补发)" ``` ## 修订内容提取方法(用于补发摘要) ```python import zipfile from lxml import etree W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' with zipfile.ZipFile(path) as z: xml = z.read('word/document.xml') root = etree.fromstring(xml) # Count WB modifications wb_ins = [ins for ins in root.findall(f'.//{{{W}}}ins') if ins.get(f'{{{W}}}author') == 'WB'] wb_del = [d for d in root.findall(f'.//{{{W}}}del') if d.get(f'{{{W}}}author') == 'WB'] print(f"WB修订: {len(wb_ins)} ins, {len(wb_del)} del") # Get INS text summaries for ins in wb_ins[:10]: texts = [t.text for t in ins.iter(f'{{{W}}}t') if t.text] text = ''.join(texts).strip() if text and len(text) > 2: print(f" + {text[:80]}") ``` ## 预防措施 - auto_notify_watchdog cron每5分钟检查WS连接 - gateway WS重连机制(attempt 6-8自动重连) - 但final_review内的`_send_wecom`调用没有重试机制——WS断了就直接失败 - **待改进**:final_review的通知步骤应增加重试逻辑或失败后写入pending_notifications队列