Add basic webhook option to workerConfig.notification as alternative to apprise

pull/143/head
Steven Crocker 2025-09-25 21:40:42 -05:00
parent 65408d4962
commit 9705d6cd91
2 changed files with 57 additions and 23 deletions

View File

@ -54,7 +54,15 @@ export type Notification = {
recipientUrl?: string recipientUrl?: string
timeZone?: string timeZone?: string
gracePeriod?: number gracePeriod?: number
skipNotificationIds?: string[] skipNotificationIds?: string[],
webhook?: Webhook
}
export type Webhook = {
url: string,
method?: 'POST' | 'GET',
headers?: { [key: string]: string | number },
timeout?: number
} }
export type Callbacks<TEnv = Env> = { export type Callbacks<TEnv = Env> = {

View File

@ -1,8 +1,8 @@
import { workerConfig, maintenances } from '../../uptime.config'
import { formatStatusChangeNotification, getWorkerLocation, notifyWithApprise } from './util'
import { MonitorState, MonitorTarget } from '../../types/config'
import { getStatus } from './monitor'
import { DurableObject } from 'cloudflare:workers' import { DurableObject } from 'cloudflare:workers'
import { MonitorState, MonitorTarget } from '../../types/config'
import { maintenances, workerConfig } from '../../uptime.config'
import { getStatus } from './monitor'
import { formatStatusChangeNotification, getWorkerLocation, notifyWithApprise } from './util'
export interface Env { export interface Env {
UPTIMEFLARE_STATE: KVNamespace UPTIMEFLARE_STATE: KVNamespace
@ -46,25 +46,51 @@ const Worker = {
return return
} }
if (workerConfig.notification?.appriseApiServer && workerConfig.notification?.recipientUrl) { if(workerConfig.notification?.webhook?.url) {
const notification = formatStatusChangeNotification( const controller = new AbortController()
monitor, const timeoutId = setTimeout(() => controller.abort(), workerConfig.notification.webhook.timeout ?? 30000) // 30 second default timeout
isUp, const headers = { 'Content-Type': 'application/json' }
timeIncidentStart, if(workerConfig.notification.webhook.headers) {
timeNow, Object.assign(headers, workerConfig.notification.webhook.headers)
reason, }
workerConfig.notification?.timeZone ?? 'Etc/GMT' try {
) await fetch(workerConfig.notification.webhook.url, {
await notifyWithApprise( method: workerConfig.notification.webhook.method ?? 'POST',
workerConfig.notification.appriseApiServer, headers,
workerConfig.notification.recipientUrl, body: JSON.stringify({
notification.title, event: 'status_change',
notification.body monitor,
) isUp,
timeIncidentStart,
timeNow,
reason,
}),
signal: controller.signal,
})
} finally {
clearTimeout(timeoutId)
}
} else { } else {
console.log( if (workerConfig.notification?.appriseApiServer && workerConfig.notification?.recipientUrl) {
`Apprise API server or recipient URL not set, skipping apprise notification for ${monitor.name}` const notification = formatStatusChangeNotification(
) monitor,
isUp,
timeIncidentStart,
timeNow,
reason,
workerConfig.notification?.timeZone ?? 'Etc/GMT'
)
await notifyWithApprise(
workerConfig.notification.appriseApiServer,
workerConfig.notification.recipientUrl,
notification.title,
notification.body
)
} else {
console.log(
`Apprise API server or recipient URL not set, skipping apprise notification for ${monitor.name}`
)
}
} }
} }