diff --git a/internal/database/migrations.go b/internal/database/migrations.go index 0e8e7372..6791d817 100644 --- a/internal/database/migrations.go +++ b/internal/database/migrations.go @@ -977,4 +977,9 @@ var migrations = []func(tx *sql.Tx, driver string) error{ _, err = tx.Exec(sql) return err }, + func(tx *sql.Tx, _ string) (err error) { + sql := `ALTER TABLE integrations ADD COLUMN ntfy_internal_links bool default 'f';` + _, err = tx.Exec(sql) + return err + }, } diff --git a/internal/integration/integration.go b/internal/integration/integration.go index e363af9e..ebca70af 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -506,6 +506,7 @@ func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *mode userIntegrations.NtfyUsername, userIntegrations.NtfyPassword, userIntegrations.NtfyIconURL, + userIntegrations.NtfyInternalLinks, feed.NtfyPriority, ) diff --git a/internal/integration/ntfy/ntfy.go b/internal/integration/ntfy/ntfy.go index 04fd978a..92f906f0 100644 --- a/internal/integration/ntfy/ntfy.go +++ b/internal/integration/ntfy/ntfy.go @@ -9,8 +9,10 @@ import ( "fmt" "log/slog" "net/http" + "net/url" "time" + "miniflux.app/v2/internal/config" "miniflux.app/v2/internal/model" "miniflux.app/v2/internal/version" ) @@ -22,14 +24,15 @@ const ( type Client struct { ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL string + ntfyInternalLinks bool ntfyPriority int } -func NewClient(ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL string, ntfyPriority int) *Client { +func NewClient(ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL string, ntfyInternalLinks bool, ntfyPriority int) *Client { if ntfyURL == "" { ntfyURL = defaultNtfyURL } - return &Client{ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL, ntfyPriority} + return &Client{ntfyURL, ntfyTopic, ntfyApiToken, ntfyUsername, ntfyPassword, ntfyIconURL, ntfyInternalLinks, ntfyPriority} } func (c *Client) SendMessages(feed *model.Feed, entries model.Entries) error { @@ -46,12 +49,21 @@ func (c *Client) SendMessages(feed *model.Feed, entries model.Entries) error { ntfyMessage.Icon = c.ntfyIconURL } + if c.ntfyInternalLinks { + url, err := url.Parse(config.Opts.BaseURL()) + if err != nil { + slog.Error("Unable to parse base URL", slog.Any("error", err)) + } else { + ntfyMessage.Click = fmt.Sprintf("%s%s%d", url, "/unread/entry/", entry.ID) + } + } + 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), + slog.String("entry_url", ntfyMessage.Click), ) if err := c.makeRequest(ntfyMessage); err != nil { diff --git a/internal/locale/translations/de_DE.json b/internal/locale/translations/de_DE.json index 2bce3778..1dac9f8a 100644 --- a/internal/locale/translations/de_DE.json +++ b/internal/locale/translations/de_DE.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy-Benutzername (optional)", "form.integration.ntfy_password": "Ntfy-Passwort (optional)", "form.integration.ntfy_icon_url": "Ntfy-Symbol-URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Einträge zu Discord pushen", "form.integration.discord_webhook_link": "Discord-Webhook-URL", "form.api_key.label.description": "API-Schlüsselbezeichnung", diff --git a/internal/locale/translations/el_EL.json b/internal/locale/translations/el_EL.json index 4e522e77..efb60e77 100644 --- a/internal/locale/translations/el_EL.json +++ b/internal/locale/translations/el_EL.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "Ετικέτα κλειδιού API", diff --git a/internal/locale/translations/en_US.json b/internal/locale/translations/en_US.json index 4faa30eb..5376cc0b 100644 --- a/internal/locale/translations/en_US.json +++ b/internal/locale/translations/en_US.json @@ -511,6 +511,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.cubox_activate": "Save entries to Cubox", "form.integration.cubox_api_link": "Cubox API link", "form.integration.discord_activate": "Push entries to Discord", diff --git a/internal/locale/translations/es_ES.json b/internal/locale/translations/es_ES.json index 39cfad2d..f89506a3 100644 --- a/internal/locale/translations/es_ES.json +++ b/internal/locale/translations/es_ES.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Nombre de usuario de Ntfy (opcional)", "form.integration.ntfy_password": "Contraseña de Ntfy (opcional)", "form.integration.ntfy_icon_url": "URL del icono de Ntfy (opcional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Enviar artículos a Discord", "form.integration.discord_webhook_link": "URL de la Webhook de Discord", "form.api_key.label.description": "Etiqueta de clave API", diff --git a/internal/locale/translations/fi_FI.json b/internal/locale/translations/fi_FI.json index 157e4240..7626a33e 100644 --- a/internal/locale/translations/fi_FI.json +++ b/internal/locale/translations/fi_FI.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "API Key Label", diff --git a/internal/locale/translations/fr_FR.json b/internal/locale/translations/fr_FR.json index c3f50d60..34e0bf7e 100644 --- a/internal/locale/translations/fr_FR.json +++ b/internal/locale/translations/fr_FR.json @@ -513,6 +513,7 @@ "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.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Envoyer les articles vers Discord", "form.integration.discord_webhook_link": "URL du Webhook Discord", "form.api_key.label.description": "Libellé de la clé d'API", diff --git a/internal/locale/translations/hi_IN.json b/internal/locale/translations/hi_IN.json index f4cadcd6..ad2c3789 100644 --- a/internal/locale/translations/hi_IN.json +++ b/internal/locale/translations/hi_IN.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "एपीआई कुंजी लेबल", diff --git a/internal/locale/translations/id_ID.json b/internal/locale/translations/id_ID.json index 5434ec94..ef4c19d4 100644 --- a/internal/locale/translations/id_ID.json +++ b/internal/locale/translations/id_ID.json @@ -503,6 +503,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "Label Kunci API", diff --git a/internal/locale/translations/it_IT.json b/internal/locale/translations/it_IT.json index 757449e1..447fd4e4 100644 --- a/internal/locale/translations/it_IT.json +++ b/internal/locale/translations/it_IT.json @@ -514,6 +514,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.submit.loading": "Caricamento in corso...", diff --git a/internal/locale/translations/ja_JP.json b/internal/locale/translations/ja_JP.json index 8053cbf6..30ed0a15 100644 --- a/internal/locale/translations/ja_JP.json +++ b/internal/locale/translations/ja_JP.json @@ -503,6 +503,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "API キーラベル", diff --git a/internal/locale/translations/nl_NL.json b/internal/locale/translations/nl_NL.json index a97ad227..6da0548d 100644 --- a/internal/locale/translations/nl_NL.json +++ b/internal/locale/translations/nl_NL.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy gebruikersnaam (optioneel)", "form.integration.ntfy_password": "Ntfy wachtwoord (optioneel)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optioneel)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Artikelen opslaan in Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "API-sleutel omschrijving", diff --git a/internal/locale/translations/pl_PL.json b/internal/locale/translations/pl_PL.json index b6aaae87..fc9cd95f 100644 --- a/internal/locale/translations/pl_PL.json +++ b/internal/locale/translations/pl_PL.json @@ -523,6 +523,7 @@ "form.integration.ntfy_username": "Login do ntfy (opcjonalny)", "form.integration.ntfy_password": "Hasło do ntfy (opcjonalne)", "form.integration.ntfy_icon_url": "Adres URL ikony ntfy (opcjonalny)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Przesyłaj wpisy do Discord", "form.integration.discord_webhook_link": "Adres URL Webhook Discord", "form.api_key.label.description": "Etykieta klucza API", diff --git a/internal/locale/translations/pt_BR.json b/internal/locale/translations/pt_BR.json index a7a3596b..e8a71b5a 100644 --- a/internal/locale/translations/pt_BR.json +++ b/internal/locale/translations/pt_BR.json @@ -513,6 +513,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "Etiqueta da chave de API", diff --git a/internal/locale/translations/ru_RU.json b/internal/locale/translations/ru_RU.json index e9256862..2bd6d0d1 100644 --- a/internal/locale/translations/ru_RU.json +++ b/internal/locale/translations/ru_RU.json @@ -523,6 +523,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Отправить статьи в Discord", "form.integration.discord_webhook_link": "Ссылка на Discord Webhook", "form.api_key.label.description": "Описание API-ключа", diff --git a/internal/locale/translations/tr_TR.json b/internal/locale/translations/tr_TR.json index eac7ee9e..4d31b4fb 100644 --- a/internal/locale/translations/tr_TR.json +++ b/internal/locale/translations/tr_TR.json @@ -279,6 +279,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (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", diff --git a/internal/locale/translations/uk_UA.json b/internal/locale/translations/uk_UA.json index a82aa7d1..ca448591 100644 --- a/internal/locale/translations/uk_UA.json +++ b/internal/locale/translations/uk_UA.json @@ -523,6 +523,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "Push entries to Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "Назва ключа API", diff --git a/internal/locale/translations/zh_CN.json b/internal/locale/translations/zh_CN.json index ccf3daab..08e4f80c 100644 --- a/internal/locale/translations/zh_CN.json +++ b/internal/locale/translations/zh_CN.json @@ -503,6 +503,7 @@ "form.integration.ntfy_username": "Ntfy用户名(可选)", "form.integration.ntfy_password": "Ntfy密码(可选)", "form.integration.ntfy_icon_url": "Ntfy图标URL(可选)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "将新文章推送到 Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "API密钥标签", diff --git a/internal/locale/translations/zh_TW.json b/internal/locale/translations/zh_TW.json index fb48f80b..9d2fe7d7 100644 --- a/internal/locale/translations/zh_TW.json +++ b/internal/locale/translations/zh_TW.json @@ -503,6 +503,7 @@ "form.integration.ntfy_username": "Ntfy Username (optional)", "form.integration.ntfy_password": "Ntfy Password (optional)", "form.integration.ntfy_icon_url": "Ntfy Icon URL (optional)", + "form.integration.ntfy_internal_links": "Use internal links on click (optional)", "form.integration.discord_activate": "推送文章到 Discord", "form.integration.discord_webhook_link": "Discord Webhook link", "form.api_key.label.description": "API金鑰標籤", diff --git a/internal/model/integration.go b/internal/model/integration.go index d8734b6e..0a4e466a 100644 --- a/internal/model/integration.go +++ b/internal/model/integration.go @@ -104,6 +104,7 @@ type Integration struct { NtfyUsername string NtfyPassword string NtfyIconURL string + NtfyInternalLinks bool CuboxEnabled bool CuboxAPILink string DiscordEnabled bool diff --git a/internal/storage/integration.go b/internal/storage/integration.go index 8502b1ca..32da349d 100644 --- a/internal/storage/integration.go +++ b/internal/storage/integration.go @@ -208,6 +208,7 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { ntfy_username, ntfy_password, ntfy_icon_url, + ntfy_internal_links, cubox_enabled, cubox_api_link, discord_enabled, @@ -318,6 +319,7 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { &integration.NtfyUsername, &integration.NtfyPassword, &integration.NtfyIconURL, + &integration.NtfyInternalLinks, &integration.CuboxEnabled, &integration.CuboxAPILink, &integration.DiscordEnabled, @@ -437,12 +439,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { ntfy_username=$96, ntfy_password=$97, ntfy_icon_url=$98, - cubox_enabled=$99, - cubox_api_link=$100, - discord_enabled=$101, - discord_webhook_link=$102 + ntfy_internal_links=$99, + cubox_enabled=$100, + cubox_api_link=$101, + discord_enabled=$102, + discord_webhook_link=$103 WHERE - user_id=$103 + user_id=$104 ` _, err := s.db.Exec( query, @@ -544,6 +547,7 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.NtfyUsername, integration.NtfyPassword, integration.NtfyIconURL, + integration.NtfyInternalLinks, integration.CuboxEnabled, integration.CuboxAPILink, integration.DiscordEnabled, diff --git a/internal/template/templates/views/integrations.html b/internal/template/templates/views/integrations.html index 17d6ce2d..878e20a7 100644 --- a/internal/template/templates/views/integrations.html +++ b/internal/template/templates/views/integrations.html @@ -316,6 +316,10 @@ + +
diff --git a/internal/ui/form/integration.go b/internal/ui/form/integration.go index 3049e520..a3a4e0b2 100644 --- a/internal/ui/form/integration.go +++ b/internal/ui/form/integration.go @@ -110,6 +110,7 @@ type IntegrationForm struct { NtfyUsername string NtfyPassword string NtfyIconURL string + NtfyInternalLinks bool CuboxEnabled bool CuboxAPILink string DiscordEnabled bool @@ -213,6 +214,7 @@ func (i IntegrationForm) Merge(integration *model.Integration) { integration.NtfyUsername = i.NtfyUsername integration.NtfyPassword = i.NtfyPassword integration.NtfyIconURL = i.NtfyIconURL + integration.NtfyInternalLinks = i.NtfyInternalLinks integration.CuboxEnabled = i.CuboxEnabled integration.CuboxAPILink = i.CuboxAPILink integration.DiscordEnabled = i.DiscordEnabled @@ -319,6 +321,7 @@ func NewIntegrationForm(r *http.Request) *IntegrationForm { NtfyUsername: r.FormValue("ntfy_username"), NtfyPassword: r.FormValue("ntfy_password"), NtfyIconURL: r.FormValue("ntfy_icon_url"), + NtfyInternalLinks: r.FormValue("ntfy_internal_links") == "1", CuboxEnabled: r.FormValue("cubox_enabled") == "1", CuboxAPILink: r.FormValue("cubox_api_link"), DiscordEnabled: r.FormValue("discord_enabled") == "1", diff --git a/internal/ui/integration_show.go b/internal/ui/integration_show.go index a6e0ece3..2ad50539 100644 --- a/internal/ui/integration_show.go +++ b/internal/ui/integration_show.go @@ -124,6 +124,7 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) { NtfyUsername: integration.NtfyUsername, NtfyPassword: integration.NtfyPassword, NtfyIconURL: integration.NtfyIconURL, + NtfyInternalLinks: integration.NtfyInternalLinks, CuboxEnabled: integration.CuboxEnabled, CuboxAPILink: integration.CuboxAPILink, DiscordEnabled: integration.DiscordEnabled,