mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 15:15:24 +00:00
feat: unify alerts into one plugin, channels, rules and inbox
This commit is contained in:
1 parent
fbe736bc20
commit
7c02daccf4
129 files changed
+20957
-2687
No files matched your search
@@ -67,22 +67,26 @@ async function runNotify(
|
||||
const title = renderTemplate(step.title ?? "", context.template);
|
||||
const body = renderTemplate(step.body ?? "", context.template);
|
||||
|
||||
if (step.channelIds.length === 0) {
|
||||
return fail("No notification channels selected");
|
||||
}
|
||||
const channelIds = step.channelIds ?? [];
|
||||
if (context.dryRun) {
|
||||
return ok(
|
||||
`Would notify ${step.channelIds.length} channel(s): ${title || body}`,
|
||||
channelIds.length > 0
|
||||
? `Would send an alert to the inbox and ${channelIds.length} channel(s): ${title || body}`
|
||||
: `Would send an alert to the inbox: ${title || body}`,
|
||||
);
|
||||
}
|
||||
|
||||
const trigger = context.template.trigger ?? {};
|
||||
let result;
|
||||
try {
|
||||
result = await runtime.ctx.notify.send(step.channelIds, {
|
||||
result = await runtime.ctx.notify.send({
|
||||
title: title || "Termix automation",
|
||||
body,
|
||||
severity: step.severity ?? "warning",
|
||||
category: "automations.notify",
|
||||
audience: { userId: context.userId },
|
||||
channelIds,
|
||||
link: { tab: "automations" },
|
||||
context: {
|
||||
hostId:
|
||||
context.template.host?.id ??
|
||||
@@ -102,12 +106,15 @@ async function runNotify(
|
||||
return fail(errorText(error));
|
||||
}
|
||||
|
||||
if (result.recipients === 0) {
|
||||
return fail("Alerts are turned off on this server");
|
||||
}
|
||||
const errors = result.failures.map((f) => `${f.name}: ${f.error}`);
|
||||
if (result.delivered === 0) {
|
||||
return fail(errors.join("; ") || "No enabled channels to notify");
|
||||
if (channelIds.length > 0 && result.delivered === 0 && errors.length > 0) {
|
||||
return fail(errors.join("; "));
|
||||
}
|
||||
return ok(
|
||||
`Notified ${result.delivered} channel(s)${errors.length ? `; ${errors.join("; ")}` : ""}`,
|
||||
`Sent an alert${result.delivered ? ` and notified ${result.delivered} channel(s)` : ""}${errors.length ? `; ${errors.join("; ")}` : ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -302,6 +302,27 @@ export class AutomationEngine {
|
||||
// An automation_failed handler that itself fails must not re-announce
|
||||
// its own failure, so the event is not emitted for runs that this event
|
||||
// already started.
|
||||
await this.ctx.notify
|
||||
.send({
|
||||
title: `Automation "${automation.name}" failed`,
|
||||
body: error ?? undefined,
|
||||
severity: "warning",
|
||||
category: "automations.run_failed",
|
||||
audience: { userId: automation.userId },
|
||||
link: { tab: "automations" },
|
||||
dedupeKey: `automations.run_failed:${automation.id}`,
|
||||
context: {
|
||||
sourceId: automation.id,
|
||||
sourceName: automation.name,
|
||||
triggerType: request.triggerType,
|
||||
},
|
||||
})
|
||||
.catch((notifyError: unknown) =>
|
||||
this.ctx.log.warn(
|
||||
`Could not send the failure alert for automation ${automation.id}: ${errorText(notifyError)}`,
|
||||
),
|
||||
);
|
||||
|
||||
if (request.triggerType !== "internal_event") {
|
||||
this.ctx.events.emit(TOPIC_AUTOMATION_FAILED, {
|
||||
userId: automation.userId,
|
||||
|
||||
@@ -99,7 +99,7 @@ export type AutomationRepository = Awaited<
|
||||
>;
|
||||
|
||||
/**
|
||||
* Automation storage. `ownedChannelIds` answers which of core's notification
|
||||
* Automation storage. `ownedChannelIds` answers which alert
|
||||
* channels the user owns, so a link can never point at another user's.
|
||||
*/
|
||||
export async function createAutomationRepository(
|
||||
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
* Adopted from core's automation tables, so column and index names are the
|
||||
* legacy ones and the rename carries every row across.
|
||||
*
|
||||
* The links between these tables, and a channel link to core's
|
||||
* notification_channels, are plain integers here: the SDK only references
|
||||
* users and ssh_data. The adoption migrations keep the legacy FOREIGN KEY
|
||||
* clauses by hand, so deleting an automation still cascades.
|
||||
* The links between these tables are plain integers here: the SDK only
|
||||
* references users and ssh_data. The adoption migrations keep the legacy
|
||||
* FOREIGN KEY clauses by hand, so deleting an automation still cascades. A
|
||||
* channel id points into the alerts plugin's table and has no foreign key.
|
||||
*/
|
||||
|
||||
export const automations = adoptLegacyTable(
|
||||
@@ -166,7 +166,7 @@ export const runSteps = adoptLegacyTable(
|
||||
),
|
||||
);
|
||||
|
||||
/** Which of core's notification channels an automation is linked to. */
|
||||
/** Which alert channels an automation is linked to. */
|
||||
export const channels = adoptLegacyTable(
|
||||
"automation_channels",
|
||||
defineTable(
|
||||
|
||||
Reference in new issue
Block a user