diff --git a/internal/database/migrations.go b/internal/database/migrations.go index 0952a011..2ad4f1bf 100644 --- a/internal/database/migrations.go +++ b/internal/database/migrations.go @@ -921,4 +921,20 @@ var migrations = []func(tx *sql.Tx) error{ _, err = tx.Exec(sql) return err }, + func(tx *sql.Tx) (err error) { + sql := ` + ALTER TABLE integrations ADD COLUMN ntfy_enabled bool default 'f'; + ALTER TABLE integrations ADD COLUMN ntfy_url text default ''; + ALTER TABLE integrations ADD COLUMN ntfy_topic text default ''; + ALTER TABLE integrations ADD COLUMN ntfy_api_token text default ''; + ALTER TABLE integrations ADD COLUMN ntfy_username text default ''; + ALTER TABLE integrations ADD COLUMN ntfy_password text default ''; + ALTER TABLE integrations ADD COLUMN ntfy_icon_url text default ''; + + ALTER TABLE feeds ADD COLUMN ntfy_enabled bool default 'f'; + ALTER TABLE feeds ADD COLUMN ntfy_priority int default '3'; + ` + _, err = tx.Exec(sql) + return err + }, } diff --git a/internal/integration/integration.go b/internal/integration/integration.go index ad596ec0..04286776 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -16,6 +16,7 @@ import ( "miniflux.app/v2/internal/integration/linkwarden" "miniflux.app/v2/internal/integration/matrixbot" "miniflux.app/v2/internal/integration/notion" + "miniflux.app/v2/internal/integration/ntfy" "miniflux.app/v2/internal/integration/nunuxkeeper" "miniflux.app/v2/internal/integration/omnivore" "miniflux.app/v2/internal/integration/pinboard" @@ -470,6 +471,28 @@ func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *mode } } + if userIntegrations.NtfyEnabled && feed.NtfyEnabled { + slog.Debug("Sending new entries to Ntfy", + slog.Int64("user_id", userIntegrations.UserID), + slog.Int("nb_entries", len(entries)), + slog.Int64("feed_id", feed.ID), + ) + + client := ntfy.NewClient( + userIntegrations.NtfyURL, + userIntegrations.NtfyTopic, + userIntegrations.NtfyAPIToken, + userIntegrations.NtfyUsername, + userIntegrations.NtfyPassword, + userIntegrations.NtfyIconURL, + feed.NtfyPriority, + ) + + if err := client.SendMessages(feed, entries); err != nil { + slog.Warn("Unable to send new entries to Ntfy", slog.Any("error", err)) + } + } + // Integrations that only support sending individual entries if userIntegrations.TelegramBotEnabled || userIntegrations.AppriseEnabled { for _, entry := range entries { diff --git a/internal/integration/ntfy/ntfy.go b/internal/integration/ntfy/ntfy.go new file mode 100644 index 00000000..04fd978a --- /dev/null +++ b/internal/integration/ntfy/ntfy.go @@ -0,0 +1,120 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package ntfy // import "miniflux.app/v2/internal/integration/ntfy" + +import ( + "bytes" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "time" + + "miniflux.app/v2/internal/model" + "miniflux.app/v2/internal/version" +) + +const ( + defaultClientTimeout = 10 * time.Second + defaultNtfyURL = "https://ntfy.sh" +) + +type Client struct { + ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL string + ntfyPriority int +} + +func NewClient(ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL string, ntfyPriority int) *Client { + if ntfyURL == "" { + ntfyURL = defaultNtfyURL + } + return &Client{ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL, ntfyPriority} +} + +func (c *Client) SendMessages(feed *model.Feed, entries model.Entries) error { + for _, entry := range entries { + ntfyMessage := &ntfyMessage{ + Topic: c.ntfyTopic, + Message: entry.Title, + Title: feed.Title, + Priority: c.ntfyPriority, + Click: entry.URL, + } + + if c.ntfyIconURL != "" { + ntfyMessage.Icon = c.ntfyIconURL + } + + slog.Debug("Sending Ntfy message", + slog.String("url", c.ntfyURL), + slog.String("topic", c.ntfyTopic), + slog.Int("priority", ntfyMessage.Priority), + slog.String("message", ntfyMessage.Message), + slog.String("entry_url", entry.URL), + ) + + if err := c.makeRequest(ntfyMessage); err != nil { + return err + } + } + + return nil +} + +func (c *Client) makeRequest(payload any) error { + requestBody, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("ntfy: unable to encode request body: %v", err) + } + + request, err := http.NewRequest(http.MethodPost, c.ntfyURL, bytes.NewReader(requestBody)) + if err != nil { + return fmt.Errorf("ntfy: unable to create request: %v", err) + } + + request.Header.Set("Content-Type", "application/json") + request.Header.Set("User-Agent", "Miniflux/"+version.Version) + + // See https://docs.ntfy.sh/publish/#access-tokens + if c.ntfyApiToken != "" { + request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.ntfyApiToken)) + } + + // See https://docs.ntfy.sh/publish/#username-password + if c.ntfyUsername != "" && c.ntfyPassword != "" { + request.SetBasicAuth(c.ntfyUsername, c.ntfyPassword) + } + + httpClient := &http.Client{Timeout: defaultClientTimeout} + response, err := httpClient.Do(request) + if err != nil { + return fmt.Errorf("ntfy: unable to send request: %v", err) + } + defer response.Body.Close() + + if response.StatusCode >= 400 { + return fmt.Errorf("ntfy: incorrect response status code %d for url %s", response.StatusCode, c.ntfyURL) + } + + return nil +} + +// See https://docs.ntfy.sh/publish/#publish-as-json +type ntfyMessage struct { + Topic string `json:"topic"` + Message string `json:"message"` + Title string `json:"title"` + Tags []string `json:"tags,omitempty"` + Priority int `json:"priority,omitempty"` + Icon string `json:"icon,omitempty"` // https://docs.ntfy.sh/publish/#icons + Click string `json:"click,omitempty"` + Actions []ntfyAction `json:"actions,omitempty"` +} + +// See https://docs.ntfy.sh/publish/#action-buttons +type ntfyAction struct { + Action string `json:"action"` + Label string `json:"label"` + URL string `json:"url"` +} diff --git a/internal/locale/translations/de_DE.json b/internal/locale/translations/de_DE.json index 71ff2034..3a4cf362 100644 --- a/internal/locale/translations/de_DE.json +++ b/internal/locale/translations/de_DE.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Dieses Abonnement nicht aktualisieren", "form.feed.label.no_media_player": "Kein Media-Player (Audio/Video)", "form.feed.label.hide_globally": "Einträge in der globalen Ungelesen-Liste ausblenden", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "Allgemein", "form.feed.fieldset.rules": "Regeln", "form.feed.fieldset.network_settings": "Netzwerkeinstellungen", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Geheimnis", "form.integration.rssbridge_activate": "Beim Hinzufügen von Abonnements RSS-Bridge prüfen.", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API-Schlüsselbezeichnung", "form.submit.loading": "Lade...", "form.submit.saving": "Speichern...", diff --git a/internal/locale/translations/el_EL.json b/internal/locale/translations/el_EL.json index 17ea225d..d16ce7eb 100644 --- a/internal/locale/translations/el_EL.json +++ b/internal/locale/translations/el_EL.json @@ -351,6 +351,13 @@ "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", "form.feed.fieldset.integration": "Third-Party Services", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.category.label.title": "Τίτλος", "form.category.hide_globally": "Απόκρυψη καταχωρήσεων σε γενική λίστα μη αναγνωσμένων", "form.user.label.username": "Χρήστης", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Ετικέτα κλειδιού API", "form.submit.loading": "Φόρτωση...", "form.submit.saving": "Αποθήκευση...", diff --git a/internal/locale/translations/en_US.json b/internal/locale/translations/en_US.json index e20aab23..3ef5448e 100644 --- a/internal/locale/translations/en_US.json +++ b/internal/locale/translations/en_US.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Do not refresh this feed", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Hide entries in global unread list", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API Key Label", "form.submit.loading": "Loading…", "form.submit.saving": "Saving…", diff --git a/internal/locale/translations/es_ES.json b/internal/locale/translations/es_ES.json index 4a0c3c67..52386798 100644 --- a/internal/locale/translations/es_ES.json +++ b/internal/locale/translations/es_ES.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "No actualice este feed", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Ocultar artículos en la lista global de no leídos", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Etiqueta de clave API", "form.submit.loading": "Cargando...", "form.submit.saving": "Guardando...", diff --git a/internal/locale/translations/fi_FI.json b/internal/locale/translations/fi_FI.json index 96f86d43..4ff3316c 100644 --- a/internal/locale/translations/fi_FI.json +++ b/internal/locale/translations/fi_FI.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Älä päivitä tätä syötettä", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Piilota artikkelit lukemattomien listassa", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API Key Label", "form.submit.loading": "Ladataan...", "form.submit.saving": "Tallennetaan...", diff --git a/internal/locale/translations/fr_FR.json b/internal/locale/translations/fr_FR.json index 3de3cf60..39fe2c05 100644 --- a/internal/locale/translations/fr_FR.json +++ b/internal/locale/translations/fr_FR.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Ne pas actualiser ce flux", "form.feed.label.no_media_player": "Pas de lecteur multimedia (audio/vidéo)", "form.feed.label.hide_globally": "Masquer les entrées dans la liste globale non lue", + "form.feed.label.ntfy_activate": "Activer les notifications", + "form.feed.label.ntfy_priority": "Priorité de notification", + "form.feed.label.ntfy_max_priority": "Priorité maximale de notification", + "form.feed.label.ntfy_high_priority": "Priorité élevée de notification", + "form.feed.label.ntfy_default_priority": "Priorité par défaut de notification", + "form.feed.label.ntfy_low_priority": "Priorité basse de notification", + "form.feed.label.ntfy_min_priority": "Priorité minimale de notification", "form.feed.fieldset.general": "Général", "form.feed.fieldset.rules": "Règles", "form.feed.fieldset.network_settings": "Paramètres réseau", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Secret du webhook", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Envoyer les entrées vers ntfy", + "form.integration.ntfy_topic": "Sujet Ntfy", + "form.integration.ntfy_url": "URL de Ntfy (optionnel, ntfy.sh par défaut)", + "form.integration.ntfy_api_token": "Jeton d'API Ntfy (optionnel)", + "form.integration.ntfy_username": "Nom d'utilisateur Ntfy (optionnel)", + "form.integration.ntfy_password": "Mot de passe Ntfy (facultatif)", + "form.integration.ntfy_icon_url": "URL de l'icône Ntfy (facultatif)", "form.api_key.label.description": "Libellé de la clé d'API", "form.submit.loading": "Chargement...", "form.submit.saving": "Sauvegarde en cours...", diff --git a/internal/locale/translations/hi_IN.json b/internal/locale/translations/hi_IN.json index c03679f5..5b501fa8 100644 --- a/internal/locale/translations/hi_IN.json +++ b/internal/locale/translations/hi_IN.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "इस फ़ीड को रीफ़्रेश न करें", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "वैश्विक अपठित सूची में प्रविष्टियां छिपाएं", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "एपीआई कुंजी लेबल", "form.submit.loading": "लोड हो रहा है...", "form.submit.saving": "सहेजा जा रहा है...", diff --git a/internal/locale/translations/id_ID.json b/internal/locale/translations/id_ID.json index 4795cd53..9cb3b8a1 100644 --- a/internal/locale/translations/id_ID.json +++ b/internal/locale/translations/id_ID.json @@ -337,6 +337,13 @@ "form.feed.label.disabled": "Jangan perbarui umpan ini", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Sembunyikan entri di daftar belum dibaca global", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -478,6 +485,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Label Kunci API", "form.submit.loading": "Memuat...", "form.submit.saving": "Menyimpan...", diff --git a/internal/locale/translations/it_IT.json b/internal/locale/translations/it_IT.json index 685b35ea..907b9a54 100644 --- a/internal/locale/translations/it_IT.json +++ b/internal/locale/translations/it_IT.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Non aggiornare questo feed", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Nascondere le voci nella lista globale dei non letti", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -489,6 +496,13 @@ "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", "form.api_key.label.description": "Etichetta chiave API", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.submit.loading": "Caricamento in corso...", "form.submit.saving": "Salvataggio in corso...", "time_elapsed.not_yet": "non ancora", diff --git a/internal/locale/translations/ja_JP.json b/internal/locale/translations/ja_JP.json index d2d32b99..8a606813 100644 --- a/internal/locale/translations/ja_JP.json +++ b/internal/locale/translations/ja_JP.json @@ -337,6 +337,13 @@ "form.feed.label.disabled": "このフィードを更新しない", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "未読一覧に記事を表示しない", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -478,6 +485,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API キーラベル", "form.submit.loading": "読み込み中…", "form.submit.saving": "保存中…", diff --git a/internal/locale/translations/nl_NL.json b/internal/locale/translations/nl_NL.json index a07cf97d..227f3760 100644 --- a/internal/locale/translations/nl_NL.json +++ b/internal/locale/translations/nl_NL.json @@ -347,6 +347,13 @@ "form.feed.label.disabled": "Vernieuw deze feed niet", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Verberg items in de globale ongelezen lijst", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API-sleutellabel", "form.submit.loading": "Laden...", "form.submit.saving": "Opslaag...", diff --git a/internal/locale/translations/pl_PL.json b/internal/locale/translations/pl_PL.json index 9ab385b9..809be253 100644 --- a/internal/locale/translations/pl_PL.json +++ b/internal/locale/translations/pl_PL.json @@ -357,6 +357,13 @@ "form.feed.label.disabled": "Nie odświeżaj tego kanału", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Ukryj wpisy na globalnej liście nieprzeczytanych", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -498,6 +505,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Etykieta klucza API", "form.submit.loading": "Ładowanie...", "form.submit.saving": "Zapisywanie...", diff --git a/internal/locale/translations/pt_BR.json b/internal/locale/translations/pt_BR.json index 2c779e96..4fa22917 100644 --- a/internal/locale/translations/pt_BR.json +++ b/internal/locale/translations/pt_BR.json @@ -347,6 +347,13 @@ "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.fetch_via_proxy": "Buscar via proxy", "form.feed.label.hide_globally": "Ocultar entradas na lista global não lida", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -488,6 +495,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Etiqueta da chave de API", "form.submit.loading": "Carregando...", "form.submit.saving": "Salvando...", diff --git a/internal/locale/translations/ru_RU.json b/internal/locale/translations/ru_RU.json index e8035c56..685e96d8 100644 --- a/internal/locale/translations/ru_RU.json +++ b/internal/locale/translations/ru_RU.json @@ -357,6 +357,13 @@ "form.feed.label.disabled": "Не обновлять эту подписку", "form.feed.label.no_media_player": "Отключить медиаплеер (аудио и видео)", "form.feed.label.hide_globally": "Скрыть записи в глобальном списке непрочитанных", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -498,6 +505,13 @@ "form.integration.webhook_secret": "Секретный ключ для вебхуков", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Описание API-ключа", "form.submit.loading": "Загрузка…", "form.submit.saving": "Сохранение…", diff --git a/internal/locale/translations/tr_TR.json b/internal/locale/translations/tr_TR.json index 57bce048..1da1f652 100644 --- a/internal/locale/translations/tr_TR.json +++ b/internal/locale/translations/tr_TR.json @@ -272,6 +272,20 @@ "form.integration.webhook_activate": "Webhook'u etkinleştir", "form.integration.webhook_secret": "Webhook Secret", "form.integration.webhook_url": "Webhook URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.prefs.fieldset.application_settings": "Uygulama Ayarları", "form.prefs.fieldset.authentication_settings": "Kimlik Doğrulama Ayarları", "form.prefs.fieldset.reader_settings": "Okuyucu Ayarları", diff --git a/internal/locale/translations/uk_UA.json b/internal/locale/translations/uk_UA.json index 89d705a3..200736d8 100644 --- a/internal/locale/translations/uk_UA.json +++ b/internal/locale/translations/uk_UA.json @@ -357,6 +357,13 @@ "form.feed.label.disabled": "Не оновлювати цю стрічку", "form.feed.label.no_media_player": "No media player (audio/video)", "form.feed.label.hide_globally": "Приховати записи в глобальному списку непрочитаного", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.category.label.title": "Назва", "form.category.hide_globally": "Приховати записи в глобальному списку непрочитаного", "form.feed.fieldset.general": "General", @@ -498,6 +505,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "Check RSS-Bridge when adding subscriptions", "form.integration.rssbridge_url": "RSS-Bridge server URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "Назва ключа API", "form.submit.loading": "Завантаження...", "form.submit.saving": "Зберігаю...", diff --git a/internal/locale/translations/zh_CN.json b/internal/locale/translations/zh_CN.json index 6c9feb79..57ab61ed 100644 --- a/internal/locale/translations/zh_CN.json +++ b/internal/locale/translations/zh_CN.json @@ -337,6 +337,13 @@ "form.feed.label.disabled": "请勿刷新此源", "form.feed.label.no_media_player": "没有媒体播放器(音频/视频)", "form.feed.label.hide_globally": "隐藏全局未读列表中的文章", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "通用", "form.feed.fieldset.rules": "规则", "form.feed.fieldset.network_settings": "网络设置", @@ -478,6 +485,13 @@ "form.integration.webhook_secret": "Webhook 密钥", "form.integration.rssbridge_activate": "添加订阅时检查 RSS-Bridge", "form.integration.rssbridge_url": "RSS-Bridge 服务器 URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API密钥标签", "form.submit.loading": "载入中…", "form.submit.saving": "保存中…", diff --git a/internal/locale/translations/zh_TW.json b/internal/locale/translations/zh_TW.json index d67af7a2..4d479c1d 100644 --- a/internal/locale/translations/zh_TW.json +++ b/internal/locale/translations/zh_TW.json @@ -337,6 +337,13 @@ "form.feed.label.disabled": "請勿更新此 Feed", "form.feed.label.no_media_player": "沒有媒體播放器(音訊/視訊)", "form.feed.label.hide_globally": "隱藏全域性未讀列表中的文章", + "form.feed.label.ntfy_activate": "Push entries to ntfy", + "form.feed.label.ntfy_priority": "Ntfy priority", + "form.feed.label.ntfy_max_priority": "Ntfy max priority", + "form.feed.label.ntfy_high_priority": "Ntfy high priority", + "form.feed.label.ntfy_default_priority": "Ntfy default priority", + "form.feed.label.ntfy_low_priority": "Ntfy low priority", + "form.feed.label.ntfy_min_priority": "Ntfy min priority", "form.feed.fieldset.general": "通用", "form.feed.fieldset.rules": "規則", "form.feed.fieldset.network_settings": "網路設定", @@ -478,6 +485,13 @@ "form.integration.webhook_secret": "Webhook Secret", "form.integration.rssbridge_activate": "新增訂閱時檢查 RSS-Bridge", "form.integration.rssbridge_url": "RSS-Bridge 伺服器的 URL", + "form.integration.ntfy_activate": "Push entries to ntfy", + "form.integration.ntfy_topic": "Ntfy topic", + "form.integration.ntfy_url": "Ntfy URL (optional, default is ntfy.sh)", + "form.integration.ntfy_api_token": "Ntfy API Token (optional)", + "form.integration.ntfy_username": "Ntfy Username (optional)", + "form.integration.ntfy_password": "Ntfy Password (optional)", + "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", "form.api_key.label.description": "API金鑰標籤", "form.submit.loading": "載入中…", "form.submit.saving": "儲存中…", diff --git a/internal/model/feed.go b/internal/model/feed.go index 7b89dca0..91c582bd 100644 --- a/internal/model/feed.go +++ b/internal/model/feed.go @@ -51,8 +51,10 @@ type Feed struct { AllowSelfSignedCertificates bool `json:"allow_self_signed_certificates"` FetchViaProxy bool `json:"fetch_via_proxy"` HideGlobally bool `json:"hide_globally"` - AppriseServiceURLs string `json:"apprise_service_urls"` DisableHTTP2 bool `json:"disable_http2"` + AppriseServiceURLs string `json:"apprise_service_urls"` + NtfyEnabled bool `json:"ntfy_enabled"` + NtfyPriority int `json:"ntfy_priority"` // Non persisted attributes Category *Category `json:"category,omitempty"` diff --git a/internal/model/integration.go b/internal/model/integration.go index ff01538c..23fef60e 100644 --- a/internal/model/integration.go +++ b/internal/model/integration.go @@ -97,4 +97,11 @@ type Integration struct { RaindropToken string RaindropCollectionID string RaindropTags string + NtfyEnabled bool + NtfyTopic string + NtfyURL string + NtfyAPIToken string + NtfyUsername string + NtfyPassword string + NtfyIconURL string } diff --git a/internal/storage/feed.go b/internal/storage/feed.go index 36939d3d..decb4638 100644 --- a/internal/storage/feed.go +++ b/internal/storage/feed.go @@ -347,9 +347,11 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) { no_media_player=$26, apprise_service_urls=$27, disable_http2=$28, - description=$29 + description=$29, + ntfy_enabled=$30, + ntfy_priority=$31 WHERE - id=$30 AND user_id=$31 + id=$32 AND user_id=$33 ` _, err = s.db.Exec(query, feed.FeedURL, @@ -381,6 +383,8 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) { feed.AppriseServiceURLs, feed.DisableHTTP2, feed.Description, + feed.NtfyEnabled, + feed.NtfyPriority, feed.ID, feed.UserID, ) diff --git a/internal/storage/feed_query_builder.go b/internal/storage/feed_query_builder.go index 79a752d9..271c011a 100644 --- a/internal/storage/feed_query_builder.go +++ b/internal/storage/feed_query_builder.go @@ -165,7 +165,9 @@ func (f *FeedQueryBuilder) GetFeeds() (model.Feeds, error) { fi.icon_id, u.timezone, f.apprise_service_urls, - f.disable_http2 + f.disable_http2, + f.ntfy_enabled, + f.ntfy_priority FROM feeds f LEFT JOIN @@ -234,6 +236,8 @@ func (f *FeedQueryBuilder) GetFeeds() (model.Feeds, error) { &tz, &feed.AppriseServiceURLs, &feed.DisableHTTP2, + &feed.NtfyEnabled, + &feed.NtfyPriority, ) if err != nil { diff --git a/internal/storage/integration.go b/internal/storage/integration.go index 5bc20110..90c46326 100644 --- a/internal/storage/integration.go +++ b/internal/storage/integration.go @@ -200,7 +200,14 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { raindrop_tags, betula_enabled, betula_url, - betula_token + betula_token, + ntfy_enabled, + ntfy_topic, + ntfy_url, + ntfy_api_token, + ntfy_username, + ntfy_password, + ntfy_icon_url FROM integrations WHERE @@ -300,6 +307,13 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { &integration.BetulaEnabled, &integration.BetulaURL, &integration.BetulaToken, + &integration.NtfyEnabled, + &integration.NtfyTopic, + &integration.NtfyURL, + &integration.NtfyAPIToken, + &integration.NtfyUsername, + &integration.NtfyPassword, + &integration.NtfyIconURL, ) switch { case err == sql.ErrNoRows: @@ -407,9 +421,16 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { raindrop_tags=$88, betula_enabled=$89, betula_url=$90, - betula_token=$91 + betula_token=$91, + ntfy_enabled=$92, + ntfy_topic=$93, + ntfy_url=$94, + ntfy_api_token=$95, + ntfy_username=$96, + ntfy_password=$97, + ntfy_icon_url=$98 WHERE - user_id=$92 + user_id=$99 ` _, err := s.db.Exec( query, @@ -504,6 +525,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.BetulaEnabled, integration.BetulaURL, integration.BetulaToken, + integration.NtfyEnabled, + integration.NtfyTopic, + integration.NtfyURL, + integration.NtfyAPIToken, + integration.NtfyUsername, + integration.NtfyPassword, + integration.NtfyIconURL, integration.UserID, ) diff --git a/internal/template/templates/views/edit_feed.html b/internal/template/templates/views/edit_feed.html index cda7e251..3128e2a6 100644 --- a/internal/template/templates/views/edit_feed.html +++ b/internal/template/templates/views/edit_feed.html @@ -142,7 +142,7 @@ {{ t "form.feed.label.blocklist_rules" }}   - + {{ icon "external-link" }} @@ -153,7 +153,7 @@ {{ t "form.feed.label.keeplist_rules" }}   - + {{ icon "external-link" }} @@ -164,7 +164,7 @@ {{ t "form.feed.label.urlrewrite_rules" }}   - + {{ icon "external-link" }} @@ -178,13 +178,36 @@
{{ t "form.feed.fieldset.integration" }} -
- -   -
- +
+ Apprise +
+ +
+ +
+ +
+ Ntfy + +
+ +   + + {{ icon "external-link" }} + +
+ +
diff --git a/internal/template/templates/views/integrations.html b/internal/template/templates/views/integrations.html index 90586cbe..bd03f050 100644 --- a/internal/template/templates/views/integrations.html +++ b/internal/template/templates/views/integrations.html @@ -259,6 +259,37 @@
+
+ Ntfy +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
Nunux Keeper
diff --git a/internal/ui/feed_edit.go b/internal/ui/feed_edit.go index e91b93c7..21cf5dc2 100644 --- a/internal/ui/feed_edit.go +++ b/internal/ui/feed_edit.go @@ -64,6 +64,8 @@ func (h *handler) showEditFeedPage(w http.ResponseWriter, r *http.Request) { CategoryHidden: feed.Category.HideGlobally, AppriseServiceURLs: feed.AppriseServiceURLs, DisableHTTP2: feed.DisableHTTP2, + NtfyEnabled: feed.NtfyEnabled, + NtfyPriority: feed.NtfyPriority, } sess := session.New(h.store, request.SessionID(r)) diff --git a/internal/ui/form/feed.go b/internal/ui/form/feed.go index c5345e9d..b9b05bc4 100644 --- a/internal/ui/form/feed.go +++ b/internal/ui/form/feed.go @@ -36,6 +36,8 @@ type FeedForm struct { CategoryHidden bool // Category has "hide_globally" AppriseServiceURLs string DisableHTTP2 bool + NtfyEnabled bool + NtfyPriority int } // Merge updates the fields of the given feed. @@ -65,6 +67,8 @@ func (f FeedForm) Merge(feed *model.Feed) *model.Feed { feed.HideGlobally = f.HideGlobally feed.AppriseServiceURLs = f.AppriseServiceURLs feed.DisableHTTP2 = f.DisableHTTP2 + feed.NtfyEnabled = f.NtfyEnabled + feed.NtfyPriority = f.NtfyPriority return feed } @@ -74,6 +78,10 @@ func NewFeedForm(r *http.Request) *FeedForm { if err != nil { categoryID = 0 } + ntfyPriority, err := strconv.Atoi(r.FormValue("ntfy_priority")) + if err != nil { + ntfyPriority = 0 + } return &FeedForm{ FeedURL: r.FormValue("feed_url"), SiteURL: r.FormValue("site_url"), @@ -98,5 +106,7 @@ func NewFeedForm(r *http.Request) *FeedForm { HideGlobally: r.FormValue("hide_globally") == "1", AppriseServiceURLs: r.FormValue("apprise_service_urls"), DisableHTTP2: r.FormValue("disable_http2") == "1", + NtfyEnabled: r.FormValue("ntfy_enabled") == "1", + NtfyPriority: ntfyPriority, } } diff --git a/internal/ui/form/integration.go b/internal/ui/form/integration.go index 5a6ac271..a60e9100 100644 --- a/internal/ui/form/integration.go +++ b/internal/ui/form/integration.go @@ -103,6 +103,13 @@ type IntegrationForm struct { BetulaEnabled bool BetulaURL string BetulaToken string + NtfyEnabled bool + NtfyTopic string + NtfyURL string + NtfyAPIToken string + NtfyUsername string + NtfyPassword string + NtfyIconURL string } // Merge copy form values to the model. @@ -195,6 +202,13 @@ func (i IntegrationForm) Merge(integration *model.Integration) { integration.BetulaEnabled = i.BetulaEnabled integration.BetulaURL = i.BetulaURL integration.BetulaToken = i.BetulaToken + integration.NtfyEnabled = i.NtfyEnabled + integration.NtfyTopic = i.NtfyTopic + integration.NtfyURL = i.NtfyURL + integration.NtfyAPIToken = i.NtfyAPIToken + integration.NtfyUsername = i.NtfyUsername + integration.NtfyPassword = i.NtfyPassword + integration.NtfyIconURL = i.NtfyIconURL } // NewIntegrationForm returns a new IntegrationForm. @@ -290,6 +304,13 @@ func NewIntegrationForm(r *http.Request) *IntegrationForm { BetulaEnabled: r.FormValue("betula_enabled") == "1", BetulaURL: r.FormValue("betula_url"), BetulaToken: r.FormValue("betula_token"), + NtfyEnabled: r.FormValue("ntfy_enabled") == "1", + NtfyTopic: r.FormValue("ntfy_topic"), + NtfyURL: r.FormValue("ntfy_url"), + NtfyAPIToken: r.FormValue("ntfy_api_token"), + NtfyUsername: r.FormValue("ntfy_username"), + NtfyPassword: r.FormValue("ntfy_password"), + NtfyIconURL: r.FormValue("ntfy_icon_url"), } } diff --git a/internal/ui/integration_show.go b/internal/ui/integration_show.go index 0e93093f..8cc3bfe6 100644 --- a/internal/ui/integration_show.go +++ b/internal/ui/integration_show.go @@ -117,6 +117,13 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) { BetulaEnabled: integration.BetulaEnabled, BetulaURL: integration.BetulaURL, BetulaToken: integration.BetulaToken, + NtfyEnabled: integration.NtfyEnabled, + NtfyTopic: integration.NtfyTopic, + NtfyURL: integration.NtfyURL, + NtfyAPIToken: integration.NtfyAPIToken, + NtfyUsername: integration.NtfyUsername, + NtfyPassword: integration.NtfyPassword, + NtfyIconURL: integration.NtfyIconURL, } sess := session.New(h.store, request.SessionID(r))