cron: separate webhook POST delivery from announce (#17901)

* cron: split webhook delivery from announce mode

* cron: validate webhook delivery target

* cron: remove legacy webhook fallback config

* fix: finalize cron webhook delivery prep (#17901) (thanks @advaitpaliwal)

---------

Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
This commit is contained in:
Advait Paliwal
2026-02-16 02:36:00 -08:00
committed by GitHub
parent d841c9b26b
commit bc67af6ad8
33 changed files with 698 additions and 236 deletions

View File

@@ -11,6 +11,7 @@ import type {
import type { CronServiceState } from "./state.js";
import { parseAbsoluteTimeMs } from "../parse.js";
import { computeNextRunAtMs } from "../schedule.js";
import { normalizeHttpWebhookUrl } from "../webhook-url.js";
import {
normalizeOptionalAgentId,
normalizeOptionalText,
@@ -41,8 +42,19 @@ export function assertSupportedJobSpec(job: Pick<CronJob, "sessionTarget" | "pay
}
function assertDeliverySupport(job: Pick<CronJob, "sessionTarget" | "delivery">) {
if (job.delivery && job.sessionTarget !== "isolated") {
throw new Error('cron delivery config is only supported for sessionTarget="isolated"');
if (!job.delivery) {
return;
}
if (job.delivery.mode === "webhook") {
const target = normalizeHttpWebhookUrl(job.delivery.to);
if (!target) {
throw new Error("cron webhook delivery requires delivery.to to be a valid http(s) URL");
}
job.delivery.to = target;
return;
}
if (job.sessionTarget !== "isolated") {
throw new Error('cron channel delivery config is only supported for sessionTarget="isolated"');
}
}
@@ -258,7 +270,6 @@ export function createJob(state: CronServiceState, input: CronJobCreate): CronJo
name: normalizeRequiredName(input.name),
description: normalizeOptionalText(input.description),
enabled,
notify: typeof input.notify === "boolean" ? input.notify : undefined,
deleteAfterRun,
createdAtMs: now,
updatedAtMs: now,
@@ -287,9 +298,6 @@ export function applyJobPatch(job: CronJob, patch: CronJobPatch) {
if (typeof patch.enabled === "boolean") {
job.enabled = patch.enabled;
}
if (typeof patch.notify === "boolean") {
job.notify = patch.notify;
}
if (typeof patch.deleteAfterRun === "boolean") {
job.deleteAfterRun = patch.deleteAfterRun;
}
@@ -319,7 +327,7 @@ export function applyJobPatch(job: CronJob, patch: CronJobPatch) {
if (patch.delivery) {
job.delivery = mergeCronDelivery(job.delivery, patch.delivery);
}
if (job.sessionTarget === "main" && job.delivery) {
if (job.sessionTarget === "main" && job.delivery?.mode !== "webhook") {
job.delivery = undefined;
}
if (patch.state) {