Wire CP-78xx probe discovery, relay phone-probe commands, and a chat follow-up message so store desk phones get registration, switch, and provisioning detail alongside DECT and WAN diagnostics. Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
2.4 KiB
JavaScript
75 lines
2.4 KiB
JavaScript
// scripts/lib/botPhoneApi.js
|
|
//
|
|
// Route phone probes through the running bot's HTTP API when the CLI
|
|
// process has no attached relay WebSocket (normal for local scripts).
|
|
|
|
export function botApiBase() {
|
|
return (process.env.PROBE_PHONE_API_BASE
|
|
|| process.env.BOT_API_BASE
|
|
|| `http://localhost:${process.env.SERVER_PORT || 1800}`).replace(/\/$/, '');
|
|
}
|
|
|
|
export function localRelayConnected(getDectRelayHub) {
|
|
try {
|
|
return getDectRelayHub().isConnected();
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function botApiFetch(path) {
|
|
const token = process.env.HTTP_API_TOKEN;
|
|
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
|
const url = `${botApiBase()}${path}`;
|
|
let res;
|
|
try {
|
|
res = await fetch(url, { headers });
|
|
} catch (err) {
|
|
const hint = 'Start the bot (node index.js) so the relay WebSocket is attached, or set PROBE_PHONE_API_BASE to a running instance.';
|
|
const e = new Error(`Cannot reach bot API at ${url} — ${err.message}. ${hint}`);
|
|
e.code = 'BOT_API_UNREACHABLE';
|
|
e.cause = err;
|
|
throw e;
|
|
}
|
|
const body = await res.json().catch(() => ({}));
|
|
if (!res.ok) {
|
|
const err = new Error(body?.message || `bot API ${res.status} ${path}`);
|
|
err.code = body?.code || 'BOT_API_ERROR';
|
|
err.body = body;
|
|
throw err;
|
|
}
|
|
return body;
|
|
}
|
|
|
|
export function mapApiPhoneToProbeResult(target, phoneRow) {
|
|
return {
|
|
phone: target,
|
|
ok: !!phoneRow?.ok,
|
|
probes: phoneRow?.probes || null,
|
|
statusJson: phoneRow?.statusJson || null,
|
|
statusXml: phoneRow?.statusXml || null,
|
|
parsed: phoneRow?.parsed || null,
|
|
verdict: phoneRow?.verdict || null,
|
|
summary: phoneRow?.summary || null,
|
|
cfgParsed: phoneRow?.cfgParsed || null,
|
|
byteLength: phoneRow?.byteLength || null,
|
|
elapsedMs: phoneRow?.elapsedMs || null,
|
|
error: phoneRow?.error || null,
|
|
};
|
|
}
|
|
|
|
export async function probeTargetsViaBotApi(targets) {
|
|
const results = [];
|
|
let relay = { connected: false };
|
|
for (const t of targets) {
|
|
const data = await botApiFetch(`/api/phone/probe-direct/${encodeURIComponent(t.ip)}`);
|
|
relay = data.relay || relay;
|
|
results.push(mapApiPhoneToProbeResult(t, data.phones?.[0]));
|
|
}
|
|
return { results, relay };
|
|
}
|
|
|
|
export async function captureStoreViaBotApi(store, { ip } = {}) {
|
|
const qs = ip ? `?ip=${encodeURIComponent(ip)}` : '';
|
|
return botApiFetch(`/api/phone/probe/${store}${qs}`);
|
|
}
|