mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-09 12:10:46 +08:00
Add optional IM sink for key alarms (0.1.17).
Settings choose DSH session and/or WhatsApp via botId+targetId; onAlarm soft-calls ctx.dshIm.send when im is installed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e8b7d7331f
commit
83c3796fbb
12 changed files with 482 additions and 23 deletions
55
lib/index.js
55
lib/index.js
|
|
@ -250,6 +250,30 @@ function startAlarmPushClient(options) {
|
|||
};
|
||||
}
|
||||
|
||||
// src/netx/alarm-im.ts
|
||||
async function deliverAlarmToIm(ctx, payload, options) {
|
||||
if (!options.enabled)
|
||||
return;
|
||||
const botId = options.botId.trim();
|
||||
const targetId = options.targetId.trim();
|
||||
if (!botId || !targetId) {
|
||||
ctx.logger.warn("netxops alarm-im: enabled but imBotId/imTargetId empty — skip IM delivery (create a target in IM 投递设置 and paste botId+targetId)");
|
||||
return;
|
||||
}
|
||||
const im = (typeof ctx.get === "function" ? ctx.get("dshIm") : undefined) ?? ctx.dshIm;
|
||||
if (!im || typeof im.send !== "function") {
|
||||
ctx.logger.warn("netxops alarm-im: ctx.dshIm unavailable — install/enable dsh-im-ops to deliver alarms to WhatsApp/IM");
|
||||
return;
|
||||
}
|
||||
const text = formatAlarmPrompt(payload, options.lang);
|
||||
try {
|
||||
await im.send(botId, targetId, text);
|
||||
ctx.logger.info("netxops alarm-im: sent to botId=%s targetId=%s", botId, targetId);
|
||||
} catch (error) {
|
||||
ctx.logger.warn("netxops alarm-im: send failed: %s", error);
|
||||
}
|
||||
}
|
||||
|
||||
// src/netx/alarm-session.ts
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
|
@ -400,7 +424,11 @@ var Config = z.object({
|
|||
tokenCredentialRef: z.string().role("credential-ref").default(DEFAULT_TOKEN_REF),
|
||||
toolCallTimeoutMs: z.number().step(1).min(1000).default(120000),
|
||||
installAgentPreset: z.boolean().default(true),
|
||||
alarmPushEnabled: z.boolean().default(false)
|
||||
alarmPushEnabled: z.boolean().default(false),
|
||||
alarmDeliverDsh: z.boolean().default(true),
|
||||
alarmDeliverIm: z.boolean().default(false),
|
||||
imBotId: z.string().default(""),
|
||||
imTargetId: z.string().default("")
|
||||
});
|
||||
function packageRoot() {
|
||||
return join2(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
|
@ -455,11 +483,11 @@ function apply(ctx, config = Config({})) {
|
|||
if (config.installAgentPreset) {
|
||||
ensureAgentPresetInstalled(ctx.logger);
|
||||
}
|
||||
const restartAlarmPush = (apiUrl, token, enabled, lang) => {
|
||||
const restartAlarmPush = (current, apiUrl, token) => {
|
||||
stopAlarmPush?.();
|
||||
stopAlarmPush = undefined;
|
||||
resetAlarmSession();
|
||||
if (!enabled) {
|
||||
if (!current.alarmPushEnabled) {
|
||||
resetAlarmPushStatus();
|
||||
return;
|
||||
}
|
||||
|
|
@ -474,11 +502,26 @@ function apply(ctx, config = Config({})) {
|
|||
});
|
||||
return;
|
||||
}
|
||||
const lang = current.lang;
|
||||
const deliverDsh = current.alarmDeliverDsh !== false;
|
||||
const deliverIm = current.alarmDeliverIm === true;
|
||||
const imBotId = current.imBotId ?? "";
|
||||
const imTargetId = current.imTargetId ?? "";
|
||||
stopAlarmPush = startAlarmPushClient({
|
||||
apiUrl,
|
||||
token,
|
||||
logger: ctx.logger,
|
||||
onAlarm: (payload) => deliverAlarmToSession(ctx, payload, lang)
|
||||
onAlarm: async (payload) => {
|
||||
if (deliverDsh) {
|
||||
await deliverAlarmToSession(ctx, payload, lang);
|
||||
}
|
||||
await deliverAlarmToIm(ctx, payload, {
|
||||
enabled: deliverIm,
|
||||
botId: imBotId,
|
||||
targetId: imTargetId,
|
||||
lang
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const publish = () => {
|
||||
|
|
@ -496,11 +539,11 @@ function apply(ctx, config = Config({})) {
|
|||
lang: current.lang,
|
||||
toolCallTimeoutMs: current.toolCallTimeoutMs
|
||||
});
|
||||
restartAlarmPush(apiUrl, token, current.alarmPushEnabled === true, current.lang);
|
||||
restartAlarmPush(current, apiUrl, token);
|
||||
if (!tokenConfigured) {
|
||||
ctx.logger.warn("netxops: published connection → %s tokenConfigured=false (set credential %s)", apiUrl, current.tokenCredentialRef);
|
||||
} else {
|
||||
ctx.logger.info("netxops: published connection → %s tokenConfigured=true alarmPush=%s", apiUrl, current.alarmPushEnabled === true);
|
||||
ctx.logger.info("netxops: published connection → %s tokenConfigured=true alarmPush=%s dsh=%s im=%s", apiUrl, current.alarmPushEnabled === true, current.alarmDeliverDsh !== false, current.alarmDeliverIm === true);
|
||||
}
|
||||
}).catch((error) => {
|
||||
ctx.logger.error("netxops: connection publish error: %s", error);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue