diff --git a/application/public/upload/notification/gotify.png b/application/public/upload/notification/gotify.png new file mode 100644 index 0000000..105fc6c Binary files /dev/null and b/application/public/upload/notification/gotify.png differ diff --git a/application/src/components/settings/notification-settings/NotificationChannelDialog.tsx b/application/src/components/settings/notification-settings/NotificationChannelDialog.tsx index abee15a..0b1d3e1 100644 --- a/application/src/components/settings/notification-settings/NotificationChannelDialog.tsx +++ b/application/src/components/settings/notification-settings/NotificationChannelDialog.tsx @@ -36,7 +36,7 @@ interface NotificationChannelDialogProps { const baseSchema = z.object({ notify_name: z.string().min(1, "Name is required"), - notification_type: z.enum(["telegram", "discord", "slack", "signal", "google_chat", "email", "ntfy", "pushover", "notifiarr", "webhook"]), + notification_type: z.enum(["telegram", "discord", "slack", "signal", "google_chat", "email", "ntfy", "pushover", "notifiarr", "gotify", "webhook"]), enabled: z.boolean().default(true), service_id: z.string().default("global"), template_id: z.string().optional(), @@ -101,6 +101,12 @@ const webhookSchema = baseSchema.extend({ webhook_payload_template: z.string().optional(), }); +const gotifySchema = baseSchema.extend({ + notification_type: z.literal("gotify"), + api_token: z.string().min(1, "API token is required"), + server_url: z.string().url("Must be a valid server URL"), +}); + const formSchema = z.discriminatedUnion("notification_type", [ telegramSchema, discordSchema, @@ -111,6 +117,7 @@ const formSchema = z.discriminatedUnion("notification_type", [ ntfySchema, pushoverSchema, notifiarrSchema, + gotifySchema, webhookSchema, ]); @@ -172,6 +179,12 @@ const notificationTypeOptions = [ description: "Send notifications via Notifiarr", icon: "/upload/notification/notifiarr.png" }, + { + value: "gotify", + label: "Gotify", + description: "Send push notifications via Gotify", + icon: "/upload/notification/gotify.png" + }, { value: "webhook", label: "Webhook", @@ -671,6 +684,43 @@ export const NotificationChannelDialog = ({ /> )} + + {notificationType === "gotify" && ( + <> + ( + + API Token + + + + + Your Gotify application API token + + + + )} + /> + ( + + Server URL + + + + + The URL of your Gotify server + + + + )} + /> + + )} {notificationType === "webhook" && ( <> diff --git a/application/src/services/alertConfigService.ts b/application/src/services/alertConfigService.ts index 97329ae..c76a494 100644 --- a/application/src/services/alertConfigService.ts +++ b/application/src/services/alertConfigService.ts @@ -7,7 +7,7 @@ export interface AlertConfiguration { collectionId?: string; collectionName?: string; service_id: string; - notification_type: "telegram" | "discord" | "slack" | "signal" | "google_chat" | "email" | "ntfy" | "pushover" | "notifiarr" | "webhook"; + notification_type: "telegram" | "discord" | "slack" | "signal" | "google_chat" | "email" | "ntfy" | "pushover" | "notifiarr" | "gotify" | "webhook"; telegram_chat_id?: string; discord_webhook_url?: string; signal_number?: string; @@ -31,6 +31,7 @@ export interface AlertConfiguration { ntfy_endpoint?: string; api_token?: string; user_key?: string; + server_url?: string; webhook_url?: string; webhook_payload_template?: string; } @@ -95,6 +96,10 @@ export const alertConfigService = { } else if (config.notification_type === "notifiarr") { cleanConfig.api_token = config.api_token || ""; cleanConfig.channel_id = config.channel_id || ""; + + } else if (config.notification_type === "gotify") { + cleanConfig.api_token = config.api_token || ""; + cleanConfig.server_url = config.server_url || ""; } else if (config.notification_type === "webhook") { cleanConfig.webhook_url = config.webhook_url || "";