mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-17 00:30:45 +08:00
Add WhatsApp session bind/unbind to Admin Runtime, and fix related Admin JS errors.
Expose sidecar status, start/stop, QR bind, and unbind so 405 session failures are visible instead of a stuck connecting state. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
1bdbfc3b85
commit
5c6833612f
16 changed files with 1123 additions and 72 deletions
61
runtime/operations/whatsapp_bridge/status.ts
Normal file
61
runtime/operations/whatsapp_bridge/status.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
export type BridgeStatus = {
|
||||
connection: "connecting" | "qr" | "open" | "close" | "logged_out" | "needs_rebind" | "stopped";
|
||||
me: string;
|
||||
phone: string;
|
||||
qr: string;
|
||||
qr_data_url: string;
|
||||
qr_png: string;
|
||||
last_disconnect_reason: string;
|
||||
last_disconnect_status: number | null;
|
||||
last_error: string;
|
||||
reconnect_attempt: number;
|
||||
login_only: boolean;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
const STATUS_FILE = "bridge_status.json";
|
||||
|
||||
function phoneFromMe(me: string): string {
|
||||
const head = String(me || "").split("@")[0]?.split(":")[0] || "";
|
||||
return head.replace(/\D/g, "");
|
||||
}
|
||||
|
||||
export function statusPath(stateDir: string): string {
|
||||
return path.join(stateDir, STATUS_FILE);
|
||||
}
|
||||
|
||||
export function writeBridgeStatus(stateDir: string, patch: Partial<BridgeStatus>): BridgeStatus {
|
||||
fs.mkdirSync(stateDir, { recursive: true });
|
||||
const p = statusPath(stateDir);
|
||||
let prev: Partial<BridgeStatus> = {};
|
||||
try {
|
||||
if (fs.existsSync(p)) {
|
||||
prev = JSON.parse(fs.readFileSync(p, "utf8")) as Partial<BridgeStatus>;
|
||||
}
|
||||
} catch {
|
||||
prev = {};
|
||||
}
|
||||
const me = String(patch.me ?? prev.me ?? "").trim();
|
||||
const next: BridgeStatus = {
|
||||
connection: (patch.connection || prev.connection || "connecting") as BridgeStatus["connection"],
|
||||
me,
|
||||
phone: String(patch.phone ?? prev.phone ?? phoneFromMe(me)).trim(),
|
||||
qr: String(patch.qr ?? prev.qr ?? ""),
|
||||
qr_data_url: String(patch.qr_data_url ?? prev.qr_data_url ?? ""),
|
||||
qr_png: String(patch.qr_png ?? prev.qr_png ?? ""),
|
||||
last_disconnect_reason: String(patch.last_disconnect_reason ?? prev.last_disconnect_reason ?? ""),
|
||||
last_disconnect_status:
|
||||
patch.last_disconnect_status === undefined
|
||||
? (typeof prev.last_disconnect_status === "number" ? prev.last_disconnect_status : null)
|
||||
: patch.last_disconnect_status,
|
||||
last_error: String(patch.last_error ?? prev.last_error ?? ""),
|
||||
reconnect_attempt: Number(patch.reconnect_attempt ?? prev.reconnect_attempt ?? 0) || 0,
|
||||
login_only: Boolean(patch.login_only ?? prev.login_only ?? false),
|
||||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
fs.writeFileSync(p, JSON.stringify(next, null, 2), "utf8");
|
||||
return next;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue