




















@@ -17,11 +17,14 @@ type WhatsAppAccountStatus = {
1717connected?: unknown;
1818running?: unknown;
1919reconnectAttempts?: unknown;
20+lastDisconnect?: unknown;
2021lastInboundAt?: unknown;
2122lastError?: unknown;
2223healthState?: unknown;
2324};
242526+const RECENT_DISCONNECT_WARNING_WINDOW_MS = 15 * 60 * 1000;
27+2528function readWhatsAppAccountStatus(value: ChannelAccountSnapshot): WhatsAppAccountStatus | null {
2629if (!isRecord(value)) {
2730return null;
@@ -34,12 +37,34 @@ function readWhatsAppAccountStatus(value: ChannelAccountSnapshot): WhatsAppAccou
3437connected: value.connected,
3538running: value.running,
3639reconnectAttempts: value.reconnectAttempts,
40+lastDisconnect: value.lastDisconnect,
3741lastInboundAt: value.lastInboundAt,
3842lastError: value.lastError,
3943healthState: value.healthState,
4044};
4145}
424647+function readLastDisconnect(value: unknown): { at: number | null; error?: string } | null {
48+if (typeof value === "string") {
49+const error = asString(value);
50+return error ? { at: null, error } : null;
51+}
52+if (!isRecord(value)) {
53+return null;
54+}
55+return {
56+at: typeof value.at === "number" ? value.at : null,
57+error: asString(value.error),
58+};
59+}
60+61+function isRecentDisconnect(disconnect: { at: number | null } | null, now = Date.now()): boolean {
62+if (disconnect?.at == null) {
63+return false;
64+}
65+return now - disconnect.at <= RECENT_DISCONNECT_WARNING_WINDOW_MS;
66+}
67+4368export function collectWhatsAppStatusIssues(
4469accounts: ChannelAccountSnapshot[],
4570): ChannelStatusIssue[] {
@@ -55,7 +80,8 @@ export function collectWhatsAppStatusIssues(
5580typeof account.reconnectAttempts === "number" ? account.reconnectAttempts : null;
5681const lastInboundAt =
5782typeof account.lastInboundAt === "number" ? account.lastInboundAt : null;
58-const lastError = asString(account.lastError);
83+const lastDisconnect = readLastDisconnect(account.lastDisconnect);
84+const lastError = asString(account.lastError) ?? lastDisconnect?.error;
5985const healthState = asString(account.healthState);
60866187if (statusState === "unstable") {
@@ -127,6 +153,24 @@ export function collectWhatsAppStatusIssues(
127153return;
128154}
129155156+if (
157+linked &&
158+running &&
159+connected &&
160+reconnectAttempts != null &&
161+reconnectAttempts > 0 &&
162+isRecentDisconnect(lastDisconnect)
163+) {
164+issues.push({
165+channel: "whatsapp",
166+ accountId,
167+kind: "runtime",
168+message: `Linked but recently reconnected (reconnectAttempts=${reconnectAttempts})${lastError ? `: ${lastError}` : "."}`,
169+fix: `Watch: ${formatCliCommand("openclaw logs --follow")} and run ${formatCliCommand("openclaw channels status --probe")} if disconnects continue. If it keeps flapping, restart the gateway or relink via channels login.`,
170+});
171+return;
172+}
173+130174if (running && !connected) {
131175issues.push({
132176channel: "whatsapp",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。