// 微信绑定 modal(ClawBot 扫码,DESIGN §8.7):扫码绑定 + 自检发送 + 解绑。 // 左侧 rail「微信」按钮触发。后端:POST /v1/wechat/bind/qrcode、GET /v1/wechat/bind/status、 // GET /v1/wechat/bind、DELETE /v1/wechat/bind、POST /v1/wechat/test。 import { $ } from "./dom.js"; import { api } from "./api.js"; let _polling = false; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); function setState(cls, msg) { const el = $("wx-state"); el.className = "wx-status " + cls; el.textContent = msg; } async function refresh() { try { const b = await api("GET", "/v1/wechat/bind"); if (b.bound) { const push = b.can_push ? "可主动推送" : "需在微信里发条消息以开启主动推送"; setState("ok", "已绑定" + (b.user_im_id ? "" : "(待首次开口)") + " · " + push); $("wx-test").disabled = false; $("wx-unbind").disabled = false; } else { setState("wait", "尚未绑定。点「绑定」生成二维码,用手机微信扫。"); $("wx-test").disabled = true; $("wx-unbind").disabled = true; } } catch (e) { setState("err", "查询失败: " + e.message + "(确认已上 migration 0012 + 开 ZCBOT_WECHAT_BOT_ENABLED)"); $("wx-test").disabled = true; $("wx-unbind").disabled = true; } } function openWechatModal() { $("wechat-modal").classList.add("show"); $("wx-qrbox").hidden = true; refresh(); } export function closeWechatModal() { _polling = false; $("wechat-modal").classList.remove("show"); } async function bindFlow() { if (_polling) return; _polling = true; $("wx-bind").disabled = true; try { while (_polling) { // 二维码过期自动换新 const q = await api("POST", "/v1/wechat/bind/qrcode"); $("wx-qrimg").src = q.qr_png; $("wx-qrbox").hidden = false; setState("wait", "等待扫码…(二维码约 1 分钟过期,会自动换新)"); let expired = false; while (_polling && !expired) { let s; try { s = await api("GET", "/v1/wechat/bind/status?qrcode_id=" + encodeURIComponent(q.qrcode_id)); } catch (e) { await sleep(2000); continue; } if (s.status === "confirmed") { _polling = false; $("wx-qrbox").hidden = true; setState("ok", "绑定成功!去微信「微信 ClawBot」发句话试试。"); await refresh(); return; } if (s.status === "expired") { expired = true; break; } await sleep(1000); } } } catch (e) { setState("err", "绑定出错: " + e.message); } finally { _polling = false; $("wx-bind").disabled = false; } } // ───── 顶层绑定 ───── $("hd-wechat").onclick = openWechatModal; $("wx-close").onclick = closeWechatModal; $("wechat-modal").addEventListener("click", (e) => { if (e.target.id === "wechat-modal") closeWechatModal(); // 点遮罩关闭 }); $("wx-bind").onclick = bindFlow; $("wx-unbind").onclick = async () => { _polling = false; if (!confirm("确定解绑微信?")) return; try { await api("DELETE", "/v1/wechat/bind"); $("wx-qrbox").hidden = true; await refresh(); } catch (e) { setState("err", "解绑失败: " + e.message); } }; $("wx-test").onclick = async () => { $("wx-test").disabled = true; try { const r = await api("POST", "/v1/wechat/test"); if (r.ok) setState("ok", "测试消息已发送,去微信查收。"); else setState("err", "推送未送达(" + r.reason + ")。多半是超 24h 没在微信互动:发条消息再试。"); } catch (e) { setState("err", "测试失败: " + e.message); } finally { $("wx-test").disabled = false; } };