diff --git a/wechat_plain/scripts/auto-reply/README.md b/wechat_plain/scripts/auto-reply/README.md index 0807f47..b9f60bd 100644 --- a/wechat_plain/scripts/auto-reply/README.md +++ b/wechat_plain/scripts/auto-reply/README.md @@ -88,7 +88,7 @@ python wechat_reply_orchestrator.py --drain # 手动跑一轮编排 1. **原生引用气泡 / 群@昵称前缀**:现发纯文本;微信原生引用(A11y 长按→引用)是环节5 增强。 2. **日志轮转**:watcher/orchestrator log 24/7 会长(ponytail 已标)。 3. **lifelog 人物增强**(二期):回链 `com.lemon.lifelog` 的 Person 库让回复带人物记忆。 -4. **auto_send 开关搬进 viewer UI**:目前在 policy_config.json,可加到 /whitelist 页。 +4. ~~auto_send 开关搬进 viewer UI~~ ✅ **已做(2026-07-12)**:`/whitelist` 页顶部开关卡片,`GET/POST /api/auto_send` 读写 `policy_config.json`。 ## 相关文档 - `../../../md/wechat-auto-reply-requirements.md` — 需求 + 逐环节设计/状态 diff --git a/wechat_plain/scripts/auto-reply/viewer_templates/whitelist.html b/wechat_plain/scripts/auto-reply/viewer_templates/whitelist.html index 60e3523..384b09e 100644 --- a/wechat_plain/scripts/auto-reply/viewer_templates/whitelist.html +++ b/wechat_plain/scripts/auto-reply/viewer_templates/whitelist.html @@ -36,9 +36,37 @@ body{overflow-y:auto!important;height:auto!important;} .btn-confirm{background:#27ae60;color:white;border:none;border-radius:8px;padding:9px 20px;font-size:14px;cursor:pointer;} .btn-confirm:disabled{opacity:.5;cursor:not-allowed;} .loading{text-align:center;padding:30px;color:#999;} +/* 总开关卡片 */ +.as-card{background:white;border-radius:8px;padding:14px 16px;margin-bottom:14px;box-shadow:0 1px 2px rgba(0,0,0,0.05);} +.as-row{display:flex;align-items:center;gap:12px;} +.as-txt{flex:1;} +.as-title{font-weight:600;font-size:15px;color:#2c3e50;} +.as-state{font-size:12px;margin-top:2px;} +.as-state.on{color:#27ae60;font-weight:600;} +.as-state.off{color:#999;} +.switch{position:relative;display:inline-block;width:52px;height:30px;flex-shrink:0;} +.switch input{opacity:0;width:0;height:0;} +.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:30px;transition:.2s;} +.slider:before{content:"";position:absolute;height:24px;width:24px;left:3px;bottom:3px;background:white;border-radius:50%;transition:.2s;} +.switch input:checked+.slider{background:#27ae60;} +.switch input:checked+.slider:before{transform:translateX(22px);} +.switch input:disabled+.slider{opacity:.5;cursor:not-allowed;} +.as-warn{font-size:12px;color:#b9770e;background:#fef9e7;border-radius:6px;padding:8px 10px;margin-top:10px;line-height:1.5;}

⭐ 回复白名单

+ +
+
+
+
自动发送总开关
+
加载中…
+
+ +
+
开=白名单里的联系人/群直接自动发(钱/承诺/约时间/隐私等敏感词仍强制转人工,绝不误发)。关=一切都进「审批」等你手动点发。建议审核模式跑几天、草稿质量稳了再开。
+
+
白名单里的联系人 / 群,消息可被自动回复(仍受敏感词等安全规则拦截,命中转人工)。不在名单里的一律进「自动回复审批」等你手动发。
@@ -75,6 +103,30 @@ function load(){ } function del(id){fetch('/api/whitelist/'+id+'/delete',{method:'POST'}).then(function(r){return r.json()}).then(function(j){if(j.ok)load();else alert('失败');});} +function renderAuto(on){ + var st=document.getElementById('asState'),tg=document.getElementById('asToggle'); + tg.checked=!!on;tg.disabled=false; + st.textContent=on?'已开启 · 白名单自动发':'已关闭 · 全部人工审批'; + st.className='as-state '+(on?'on':'off'); +} +function loadAuto(){ + fetch('/api/auto_send').then(function(r){return r.json()}).then(function(j){ + if(j.ok)renderAuto(j.enabled); + else{document.getElementById('asState').textContent='读取失败';} + }).catch(function(){document.getElementById('asState').textContent='读取失败';}); +} +function toggleAuto(cb){ + var want=cb.checked;cb.disabled=true; + if(want&&!confirm('确定开启自动发送?白名单里的消息将无需你确认直接发出(敏感词仍会拦截转人工)。')){ + cb.checked=false;cb.disabled=false;return; + } + fetch('/api/auto_send',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({enabled:want})}) + .then(function(r){return r.json()}).then(function(j){ + if(j.ok)renderAuto(j.enabled); + else{alert('失败: '+(j.error||''));cb.checked=!want;cb.disabled=false;} + }).catch(function(){alert('网络失败');cb.checked=!want;cb.disabled=false;}); +} + function openPicker(){ selected={};updateCnt(); document.getElementById('q').value=''; @@ -120,5 +172,6 @@ function confirmAdd(){ }); } load(); +loadAuto(); {% endblock %} diff --git a/wechat_plain/scripts/auto-reply/wechat-viewer-changes.md b/wechat_plain/scripts/auto-reply/wechat-viewer-changes.md index cb02a4c..a08e42a 100644 --- a/wechat_plain/scripts/auto-reply/wechat-viewer-changes.md +++ b/wechat_plain/scripts/auto-reply/wechat-viewer-changes.md @@ -34,6 +34,14 @@ CREATE TABLE reply_queue ( -- 策略判定后落地 | `GET /api/contacts` | 弹窗默认列表:会话过的联系人+群(排除公众号),去重带昵称,最近排序 | | `GET /api/contacts/search?q=` | 按名字/wxid 搜全量 rcontact+群(`wechat_db.search_talker`) | | `POST /api/whitelist`(升级) | 支持批量 `{items:[{wxid,name,kind}]}`(弹窗多选) | +| `GET /api/auto_send` | 读自动发总开关(`policy_config.json` 的 `auto_send_enabled`) | +| `POST /api/auto_send` | 设总开关 `{enabled:bool}`;只翻转该字段保留其余 | + +**自动发总开关搬进 UI(2026-07-12)**:`/whitelist` 页顶部加开关卡片(读 `/api/auto_send`, +拨动 POST 回写)。开=白名单可自动发(敏感词仍强制转人工),关=全部进审批。开启时前端二次确认。 +`policy_config.json` 是 root 属主 644,viewer(termux 用户)可直接读、写时经 `_write_auto_send` +写 tmp 再 `su cp` 回(沿用本 app 的 `su` 模式,只改 `auto_send_enabled` 不动 block_keywords 等)。 +orchestrator 每轮 `load_config()` 读文件即时生效,无需重启。 **白名单选人弹窗(2026-07-10 升级)**:`/whitelist` 页「添加」不再手填 wxid,改为弹窗: 默认列出你会话过的联系人/群(带昵称),顶部搜索框可查全量通讯录/群,复选框**多选**,