diff --git a/internal/database/migrations.go b/internal/database/migrations.go index fc2da261..a37db28a 100644 --- a/internal/database/migrations.go +++ b/internal/database/migrations.go @@ -994,4 +994,18 @@ var migrations = []func(tx *sql.Tx, driver string) error{ _, err = tx.Exec(`ALTER TABLE feeds ADD COLUMN webhook_url text default '';`) return err }, + func(tx *sql.Tx, _ string) (err error) { + sql := ` + ALTER TABLE integrations ADD COLUMN pushover_enabled bool default 'f'; + ALTER TABLE integrations ADD COLUMN pushover_user text default ''; + ALTER TABLE integrations ADD COLUMN pushover_token text default ''; + ALTER TABLE integrations ADD COLUMN pushover_device text default ''; + ALTER TABLE integrations ADD COLUMN pushover_prefix text default ''; + + ALTER TABLE feeds ADD COLUMN pushover_enabled bool default 'f'; + ALTER TABLE feeds ADD COLUMN pushover_priority int default '0'; + ` + _, err = tx.Exec(sql) + return err + }, } diff --git a/internal/integration/integration.go b/internal/integration/integration.go index cd9320ef..b1011f4d 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -23,6 +23,7 @@ import ( "miniflux.app/v2/internal/integration/omnivore" "miniflux.app/v2/internal/integration/pinboard" "miniflux.app/v2/internal/integration/pocket" + "miniflux.app/v2/internal/integration/pushover" "miniflux.app/v2/internal/integration/raindrop" "miniflux.app/v2/internal/integration/readeck" "miniflux.app/v2/internal/integration/readwise" @@ -577,6 +578,26 @@ func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *mode } } + if userIntegrations.PushoverEnabled && feed.PushoverEnabled { + slog.Debug("Sending new entries to Pushover", + slog.Int64("user_id", userIntegrations.UserID), + slog.Int("nb_entries", len(entries)), + slog.Int64("feed_id", feed.ID), + ) + + client := pushover.New( + userIntegrations.PushoverUser, + userIntegrations.PushoverToken, + feed.PushoverPriority, + userIntegrations.PushoverDevice, + userIntegrations.PushoverPrefix, + ) + + if err := client.SendMessages(feed, entries); err != nil { + slog.Warn("Unable to send new entries to Pushover", slog.Any("error", err)) + } + } + // Integrations that only support sending individual entries if userIntegrations.TelegramBotEnabled { for _, entry := range entries { diff --git a/internal/integration/pushover/pushover.go b/internal/integration/pushover/pushover.go new file mode 100644 index 00000000..133e4348 --- /dev/null +++ b/internal/integration/pushover/pushover.go @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package pushover // import "miniflux.app/v2/internal/integration/pushover" +import ( + "bytes" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "strings" + "time" + + "miniflux.app/v2/internal/model" + "miniflux.app/v2/internal/version" +) + +const ( + defaultClientTimeout = 10 * time.Second + defaultPushoverURL = "https://api.pushover.net" +) + +type Client struct { + prefix string + + token string + user string + device string + + priority int +} + +type Message struct { + Token string `json:"token"` + User string `json:"user"` + + Title string `json:"title"` + Message string `json:"message"` + Priority int `json:"priority"` + + URL string `json:"url"` + URLTitle string `json:"url_title"` + Device string `json:"device,omitempty"` +} + +type ErrorResponse struct { + User string `json:"user"` + Errors []string `json:"errors"` + Status int `json:"status"` + Request string `json:"request"` +} + +func New(user, token string, priority int, device, urlPrefix string) *Client { + if urlPrefix == "" { + urlPrefix = defaultPushoverURL + } + if priority < -2 { + priority = -2 + } + if priority > 2 { + priority = 2 + } + + return &Client{ + user: user, + token: token, + device: device, + prefix: urlPrefix, + priority: priority, + } +} + +func (c *Client) SendMessages(feed *model.Feed, entries model.Entries) error { + if c.token == "" || c.user == "" { + return fmt.Errorf("pushover token and user are required") + } + for _, entry := range entries { + msg := &Message{ + User: c.user, + Token: c.token, + Device: c.device, + + Message: entry.Title, + Title: feed.Title, + Priority: c.priority, + URL: entry.URL, + } + + slog.Debug("Sending Pushover message", + slog.Int("priority", msg.Priority), + slog.String("message", msg.Message), + slog.String("entry_url", msg.URL), + ) + + if err := c.makeRequest(msg); err != nil { + return fmt.Errorf("c.makeRequest: %w", err) + } + } + + return nil +} + +func (c *Client) makeRequest(payload *Message) error { + jsonData, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("json.Marshal: %w", err) + } + url := c.prefix + "/1/messages.json" + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonData)) + if err != nil { + return fmt.Errorf("http.NewRequest: %w", err) + } + + req.Header.Add("Content-Type", "application/json") + req.Header.Set("User-Agent", "Miniflux/"+version.Version) + + httpClient := &http.Client{Timeout: defaultClientTimeout} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("httpClient.Do: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= http.StatusBadRequest { + errorMessage := resp.Status + + var errResp ErrorResponse + if err := json.NewDecoder(resp.Body).Decode(&errResp); err != nil { + if len(errResp.Errors) > 0 { + errorMessage = strings.Join(errResp.Errors, ",") + } + } + + return fmt.Errorf("pushover API error (%d): %s", resp.StatusCode, errorMessage) + } + + return nil +} diff --git a/internal/locale/translations/de_DE.json b/internal/locale/translations/de_DE.json index cf66c408..28a959eb 100644 --- a/internal/locale/translations/de_DE.json +++ b/internal/locale/translations/de_DE.json @@ -357,6 +357,13 @@ "form.feed.label.ntfy_default_priority": "Normale Ntfy-Priorität", "form.feed.label.ntfy_low_priority": "Niedrige Ntfy-Priorität", "form.feed.label.ntfy_min_priority": "Niedrigste Ntfy-Priorität", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Einträge in Cubox speichern", "form.integration.cubox_api_link": "Cubox-API-Link", "form.feed.fieldset.general": "Allgemein", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord-Webhook-URL", "form.integration.slack_activate": "Einträge zu Slack pushen", "form.integration.slack_webhook_link": "Slack-Webhook-URL", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 f1a096da..a6214d8a 100644 --- a/internal/locale/translations/el_EL.json +++ b/internal/locale/translations/el_EL.json @@ -361,6 +361,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.category.label.title": "Τίτλος", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 b97a95cf..4e6f9eeb 100644 --- a/internal/locale/translations/en_US.json +++ b/internal/locale/translations/en_US.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.feed.fieldset.general": "General", "form.feed.fieldset.rules": "Rules", "form.feed.fieldset.network_settings": "Network Settings", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 d2f45451..d28e8aef 100644 --- a/internal/locale/translations/es_ES.json +++ b/internal/locale/translations/es_ES.json @@ -357,6 +357,13 @@ "form.feed.label.ntfy_default_priority": "Prioridad predeterminada a Ntfy", "form.feed.label.ntfy_low_priority": "Prioridad baja a Ntfy", "form.feed.label.ntfy_min_priority": "Prioridad mínima a Ntfy", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "URL de la Webhook de Discord", "form.integration.slack_activate": "Enviar artículos a Slack", "form.integration.slack_webhook_link": "URL de la Webhook de Slack", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 6ed596c4..0844e3c6 100644 --- a/internal/locale/translations/fi_FI.json +++ b/internal/locale/translations/fi_FI.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 2383768d..0942d4ee 100644 --- a/internal/locale/translations/fr_FR.json +++ b/internal/locale/translations/fr_FR.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "Général", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "URL du Webhook Discord", "form.integration.slack_activate": "Envoyer les articles vers Slack", "form.integration.slack_webhook_link": "URL du Webhook Slack", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (optional)", "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 1e4c2756..e5dc39fd 100644 --- a/internal/locale/translations/hi_IN.json +++ b/internal/locale/translations/hi_IN.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 5ace4a1a..efa6a52a 100644 --- a/internal/locale/translations/id_ID.json +++ b/internal/locale/translations/id_ID.json @@ -347,6 +347,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -509,6 +516,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 d36c6b9a..31932b50 100644 --- a/internal/locale/translations/it_IT.json +++ b/internal/locale/translations/it_IT.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -519,6 +526,11 @@ "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Push entries to Slack", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (optional)", "form.integration.slack_webhook_link": "Slack Webhook link", "form.submit.loading": "Caricamento in corso...", "form.submit.saving": "Salvataggio in corso...", diff --git a/internal/locale/translations/ja_JP.json b/internal/locale/translations/ja_JP.json index 09768e50..cdbc2299 100644 --- a/internal/locale/translations/ja_JP.json +++ b/internal/locale/translations/ja_JP.json @@ -347,6 +347,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -508,6 +515,11 @@ "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Slack entries to Discord", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (optional)", "form.integration.slack_webhook_link": "Slack Webhook link", "form.api_key.label.description": "API キーラベル", "form.submit.loading": "読み込み中…", diff --git a/internal/locale/translations/nl_NL.json b/internal/locale/translations/nl_NL.json index 3a4eab52..997152cb 100644 --- a/internal/locale/translations/nl_NL.json +++ b/internal/locale/translations/nl_NL.json @@ -357,6 +357,13 @@ "form.feed.label.ntfy_default_priority": "Ntfy standaard prioriteit", "form.feed.label.ntfy_low_priority": "Ntfy lage prioriteit", "form.feed.label.ntfy_min_priority": "Ntfy minimale prioriteit", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "Algemeen", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Artikelen opslaan in Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (optional)", "form.api_key.label.description": "API-sleutel omschrijving", "form.submit.loading": "Laden...", "form.submit.saving": "Opslaan...", diff --git a/internal/locale/translations/pl_PL.json b/internal/locale/translations/pl_PL.json index ad93a137..68ab973b 100644 --- a/internal/locale/translations/pl_PL.json +++ b/internal/locale/translations/pl_PL.json @@ -367,6 +367,13 @@ "form.feed.label.ntfy_default_priority": "Domyślny priorytet ntfy", "form.feed.label.ntfy_low_priority": "Niski priorytet ntfy", "form.feed.label.ntfy_min_priority": "Minimalny priorytet ntfy", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Zapisuj wpisy w Cubox", "form.integration.cubox_api_link": "Łącze API Cubox", "form.feed.fieldset.general": "Ogólne", @@ -529,6 +536,11 @@ "form.integration.discord_webhook_link": "Adres URL webhooka Discord", "form.integration.slack_activate": "Przesyłaj wpisy do Slack", "form.integration.slack_webhook_link": "Adres URL webhooka Slack", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 5a45b04a..bc581934 100644 --- a/internal/locale/translations/pt_BR.json +++ b/internal/locale/translations/pt_BR.json @@ -357,6 +357,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -519,6 +526,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Slack entries to Discord", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 a911de4e..3867cfc1 100644 --- a/internal/locale/translations/ru_RU.json +++ b/internal/locale/translations/ru_RU.json @@ -367,6 +367,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.feed.fieldset.general": "General", @@ -529,6 +536,11 @@ "form.integration.discord_webhook_link": "Ссылка на Discord Webhook", "form.integration.slack_activate": "Отправить статьи в Slack", "form.integration.slack_webhook_link": "Ссылка на Slack Webhook", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 77ac41a6..fe71cde1 100644 --- a/internal/locale/translations/tr_TR.json +++ b/internal/locale/translations/tr_TR.json @@ -288,12 +288,24 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.integration.discord_activate": "Makaleleri Discord'a gönder", "form.integration.discord_webhook_link": "Discord hizmet Webhook'lerinin virgülle ayrılmış listesi", "form.integration.slack_activate": "Makaleleri Slack'a gönder", "form.integration.slack_webhook_link": "Slack hizmet Webhook'lerinin virgülle ayrılmış listesi", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (optional)", "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 ceda3ecd..421074b8 100644 --- a/internal/locale/translations/uk_UA.json +++ b/internal/locale/translations/uk_UA.json @@ -367,6 +367,13 @@ "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.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.category.label.title": "Назва", @@ -529,6 +536,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "Slack entries to Discord", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 cf66df9c..df7bbf6b 100644 --- a/internal/locale/translations/zh_CN.json +++ b/internal/locale/translations/zh_CN.json @@ -347,6 +347,13 @@ "form.feed.label.ntfy_default_priority": "Ntfy默认优先级", "form.feed.label.ntfy_low_priority": "Ntfy低优先级", "form.feed.label.ntfy_min_priority": "Ntfy最低优先级", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "保存文章到 Cubox", "form.integration.cubox_api_link": "Cubox API 链接", "form.feed.fieldset.general": "通用", @@ -509,6 +516,11 @@ "form.integration.discord_webhook_link": "Discord Webhook link", "form.integration.slack_activate": "将新文章推送到 Slack", "form.integration.slack_webhook_link": "Slack Webhook link", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 562b906f..4bcef5a7 100644 --- a/internal/locale/translations/zh_TW.json +++ b/internal/locale/translations/zh_TW.json @@ -347,6 +347,13 @@ "form.feed.label.ntfy_default_priority": "Ntfy 預設優先順序", "form.feed.label.ntfy_low_priority": "Ntfy 低優先順序", "form.feed.label.ntfy_min_priority": "Ntfy 最低優先順序", + "form.feed.label.pushover_activate": "Push entries to pushover.net", + "form.feed.label.pushover_priority": "Pushover message priority", + "form.feed.label.pushover_max_priority": "Pushover max priority", + "form.feed.label.pushover_high_priority": "Pushover high priority", + "form.feed.label.pushover_default_priority": "Pushover default priority", + "form.feed.label.pushover_low_priority": "Pushover low priority", + "form.feed.label.pushover_min_priority": "Pushover min priority", "form.integration.cubox_activate": "儲存文章到 Cubox", "form.integration.cubox_api_link": "Cubox API 連結", "form.feed.fieldset.general": "通用", @@ -509,6 +516,11 @@ "form.integration.discord_webhook_link": "Discord Webhook 連結", "form.integration.slack_activate": "推送文章到 Slack", "form.integration.slack_webhook_link": "Slack Webhook 連結", + "form.integration.pushover_activate": "Push entries to pushover", + "form.integration.pushover_token": "Pushover token", + "form.integration.pushover_user": "Pushover user", + "form.integration.pushover_device": "Pushover device (optional)", + "form.integration.pushover_prefix": "Pushover prefix (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 3f55e464..f5d0f424 100644 --- a/internal/model/feed.go +++ b/internal/model/feed.go @@ -56,6 +56,8 @@ type Feed struct { WebhookURL string `json:"webhook_url"` NtfyEnabled bool `json:"ntfy_enabled"` NtfyPriority int `json:"ntfy_priority"` + PushoverEnabled bool `json:"pushover_enabled,omitempty"` + PushoverPriority int `json:"pushover_priority,omitempty"` // Non-persisted attributes Category *Category `json:"category,omitempty"` diff --git a/internal/model/integration.go b/internal/model/integration.go index ccb33f85..8f7a59e8 100644 --- a/internal/model/integration.go +++ b/internal/model/integration.go @@ -111,4 +111,9 @@ type Integration struct { DiscordWebhookLink string SlackEnabled bool SlackWebhookLink string + PushoverEnabled bool + PushoverUser string + PushoverToken string + PushoverDevice string + PushoverPrefix string } diff --git a/internal/storage/feed.go b/internal/storage/feed.go index 4131e7c5..4480e177 100644 --- a/internal/storage/feed.go +++ b/internal/storage/feed.go @@ -360,9 +360,11 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) { disable_http2=$29, description=$30, ntfy_enabled=$31, - ntfy_priority=$32 + ntfy_priority=$32, + pushover_enabled=$33, + pushover_priority=$34 WHERE - id=$33 AND user_id=$34 + id=$35 AND user_id=$36 ` _, err = s.db.Exec(query, feed.FeedURL, @@ -397,6 +399,8 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) { feed.Description, feed.NtfyEnabled, feed.NtfyPriority, + feed.PushoverEnabled, + feed.PushoverPriority, feed.ID, feed.UserID, ) diff --git a/internal/storage/feed_query_builder.go b/internal/storage/feed_query_builder.go index 436920e5..e7982031 100644 --- a/internal/storage/feed_query_builder.go +++ b/internal/storage/feed_query_builder.go @@ -168,7 +168,9 @@ func (f *FeedQueryBuilder) GetFeeds() (model.Feeds, error) { f.webhook_url, f.disable_http2, f.ntfy_enabled, - f.ntfy_priority + f.ntfy_priority, + f.pushover_enabled, + f.pushover_priority FROM feeds f LEFT JOIN @@ -240,6 +242,8 @@ func (f *FeedQueryBuilder) GetFeeds() (model.Feeds, error) { &feed.DisableHTTP2, &feed.NtfyEnabled, &feed.NtfyPriority, + &feed.PushoverEnabled, + &feed.PushoverPriority, ) if err != nil { diff --git a/internal/storage/integration.go b/internal/storage/integration.go index 0b9ee6c4..786a3c12 100644 --- a/internal/storage/integration.go +++ b/internal/storage/integration.go @@ -214,7 +214,12 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { discord_enabled, discord_webhook_link, slack_enabled, - slack_webhook_link + slack_webhook_link, + pushover_enabled, + pushover_user, + pushover_token, + pushover_device, + pushover_prefix FROM integrations WHERE @@ -328,6 +333,11 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { &integration.DiscordWebhookLink, &integration.SlackEnabled, &integration.SlackWebhookLink, + &integration.PushoverEnabled, + &integration.PushoverUser, + &integration.PushoverToken, + &integration.PushoverDevice, + &integration.PushoverPrefix, ) switch { case err == sql.ErrNoRows: @@ -449,9 +459,14 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { discord_enabled=$102, discord_webhook_link=$103, slack_enabled=$104, - slack_webhook_link=$105 + slack_webhook_link=$105, + pushover_enabled=$106, + pushover_user=$107, + pushover_token=$108, + pushover_device=$109, + pushover_prefix=$110 WHERE - user_id=$106 + user_id=$111 ` _, err := s.db.Exec( query, @@ -560,6 +575,11 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.DiscordWebhookLink, integration.SlackEnabled, integration.SlackWebhookLink, + integration.PushoverEnabled, + integration.PushoverUser, + integration.PushoverToken, + integration.PushoverDevice, + integration.PushoverPrefix, integration.UserID, ) diff --git a/internal/template/templates/views/edit_feed.html b/internal/template/templates/views/edit_feed.html index 7928975f..c9179e3e 100644 --- a/internal/template/templates/views/edit_feed.html +++ b/internal/template/templates/views/edit_feed.html @@ -209,6 +209,27 @@ +
+ Pushover + +
+ +   + + {{ icon "external-link" }} + +
+ +
+
Webhook
diff --git a/internal/template/templates/views/integrations.html b/internal/template/templates/views/integrations.html index 2f760039..7eeb0a12 100644 --- a/internal/template/templates/views/integrations.html +++ b/internal/template/templates/views/integrations.html @@ -412,6 +412,31 @@
+
+ Pushover +
+ + + + + + + + + + + + + + +
+ +
+
+
+
Raindrop
diff --git a/internal/ui/feed_edit.go b/internal/ui/feed_edit.go index a6962600..9fd33976 100644 --- a/internal/ui/feed_edit.go +++ b/internal/ui/feed_edit.go @@ -67,6 +67,8 @@ func (h *handler) showEditFeedPage(w http.ResponseWriter, r *http.Request) { DisableHTTP2: feed.DisableHTTP2, NtfyEnabled: feed.NtfyEnabled, NtfyPriority: feed.NtfyPriority, + PushoverEnabled: feed.PushoverEnabled, + PushoverPriority: feed.PushoverPriority, } sess := session.New(h.store, request.SessionID(r)) diff --git a/internal/ui/form/feed.go b/internal/ui/form/feed.go index 8212e910..93c2c058 100644 --- a/internal/ui/form/feed.go +++ b/internal/ui/form/feed.go @@ -39,6 +39,8 @@ type FeedForm struct { DisableHTTP2 bool NtfyEnabled bool NtfyPriority int + PushoverEnabled bool + PushoverPriority int } // Merge updates the fields of the given feed. @@ -71,6 +73,8 @@ func (f FeedForm) Merge(feed *model.Feed) *model.Feed { feed.DisableHTTP2 = f.DisableHTTP2 feed.NtfyEnabled = f.NtfyEnabled feed.NtfyPriority = f.NtfyPriority + feed.PushoverEnabled = f.PushoverEnabled + feed.PushoverPriority = f.PushoverPriority return feed } @@ -84,6 +88,12 @@ func NewFeedForm(r *http.Request) *FeedForm { if err != nil { ntfyPriority = 0 } + + pushoverPriority, err := strconv.Atoi(r.FormValue("pushover_priority")) + if err != nil { + pushoverPriority = 0 + } + return &FeedForm{ FeedURL: r.FormValue("feed_url"), SiteURL: r.FormValue("site_url"), @@ -111,5 +121,7 @@ func NewFeedForm(r *http.Request) *FeedForm { DisableHTTP2: r.FormValue("disable_http2") == "1", NtfyEnabled: r.FormValue("ntfy_enabled") == "1", NtfyPriority: ntfyPriority, + PushoverEnabled: r.FormValue("pushover_enabled") == "1", + PushoverPriority: pushoverPriority, } } diff --git a/internal/ui/form/integration.go b/internal/ui/form/integration.go index 25b0b3e7..5a8ef9f1 100644 --- a/internal/ui/form/integration.go +++ b/internal/ui/form/integration.go @@ -117,6 +117,11 @@ type IntegrationForm struct { DiscordWebhookLink string SlackEnabled bool SlackWebhookLink string + PushoverEnabled bool + PushoverUser string + PushoverToken string + PushoverDevice string + PushoverPrefix string } // Merge copy form values to the model. @@ -223,6 +228,11 @@ func (i IntegrationForm) Merge(integration *model.Integration) { integration.DiscordWebhookLink = i.DiscordWebhookLink integration.SlackEnabled = i.SlackEnabled integration.SlackWebhookLink = i.SlackWebhookLink + integration.PushoverEnabled = i.PushoverEnabled + integration.PushoverUser = i.PushoverUser + integration.PushoverToken = i.PushoverToken + integration.PushoverDevice = i.PushoverDevice + integration.PushoverPrefix = i.PushoverPrefix } // NewIntegrationForm returns a new IntegrationForm. @@ -332,6 +342,11 @@ func NewIntegrationForm(r *http.Request) *IntegrationForm { DiscordWebhookLink: r.FormValue("discord_webhook_link"), SlackEnabled: r.FormValue("slack_enabled") == "1", SlackWebhookLink: r.FormValue("slack_webhook_link"), + PushoverEnabled: r.FormValue("pushover_enabled") == "1", + PushoverUser: r.FormValue("pushover_user"), + PushoverToken: r.FormValue("pushover_token"), + PushoverDevice: r.FormValue("pushover_device"), + PushoverPrefix: r.FormValue("pushover_prefix"), } } diff --git a/internal/ui/integration_show.go b/internal/ui/integration_show.go index 6e17bcee..05fc7ca5 100644 --- a/internal/ui/integration_show.go +++ b/internal/ui/integration_show.go @@ -131,6 +131,11 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) { DiscordWebhookLink: integration.DiscordWebhookLink, SlackEnabled: integration.SlackEnabled, SlackWebhookLink: integration.SlackWebhookLink, + PushoverEnabled: integration.PushoverEnabled, + PushoverUser: integration.PushoverUser, + PushoverToken: integration.PushoverToken, + PushoverDevice: integration.PushoverDevice, + PushoverPrefix: integration.PushoverPrefix, } sess := session.New(h.store, request.SessionID(r))