2023-06-19 14:42:47 -07:00
|
|
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2017-12-02 21:12:03 -08:00
|
|
|
|
2023-08-10 19:46:45 -07:00
|
|
|
package integration // import "miniflux.app/v2/internal/integration"
|
2017-12-02 21:12:03 -08:00
|
|
|
|
|
|
|
import (
|
2023-09-24 16:32:09 -07:00
|
|
|
"log/slog"
|
|
|
|
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/apprise"
|
2024-07-04 22:59:47 +03:00
|
|
|
"miniflux.app/v2/internal/integration/betula"
|
2024-10-18 13:18:17 +08:00
|
|
|
"miniflux.app/v2/internal/integration/cubox"
|
2025-01-12 21:18:57 +01:00
|
|
|
"miniflux.app/v2/internal/integration/discord"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/espial"
|
|
|
|
"miniflux.app/v2/internal/integration/instapaper"
|
2025-06-04 08:37:11 -04:00
|
|
|
"miniflux.app/v2/internal/integration/karakeep"
|
2024-01-23 18:12:31 +01:00
|
|
|
"miniflux.app/v2/internal/integration/linkace"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/linkding"
|
2024-02-12 02:12:37 +01:00
|
|
|
"miniflux.app/v2/internal/integration/linkwarden"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/matrixbot"
|
|
|
|
"miniflux.app/v2/internal/integration/notion"
|
2024-07-13 16:52:30 -07:00
|
|
|
"miniflux.app/v2/internal/integration/ntfy"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/nunuxkeeper"
|
2023-12-04 23:05:04 -05:00
|
|
|
"miniflux.app/v2/internal/integration/omnivore"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/pinboard"
|
2025-02-12 13:05:28 -05:00
|
|
|
"miniflux.app/v2/internal/integration/pushover"
|
2024-04-27 20:35:56 -07:00
|
|
|
"miniflux.app/v2/internal/integration/raindrop"
|
2024-02-22 03:57:34 +00:00
|
|
|
"miniflux.app/v2/internal/integration/readeck"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/readwise"
|
2023-08-13 14:30:57 -07:00
|
|
|
"miniflux.app/v2/internal/integration/shaarli"
|
2023-08-13 12:48:29 -07:00
|
|
|
"miniflux.app/v2/internal/integration/shiori"
|
2025-01-27 00:20:00 +01:00
|
|
|
"miniflux.app/v2/internal/integration/slack"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/integration/telegrambot"
|
|
|
|
"miniflux.app/v2/internal/integration/wallabag"
|
2023-09-08 22:45:17 -07:00
|
|
|
"miniflux.app/v2/internal/integration/webhook"
|
2023-08-10 19:46:45 -07:00
|
|
|
"miniflux.app/v2/internal/model"
|
2017-12-02 21:12:03 -08:00
|
|
|
)
|
|
|
|
|
2021-09-07 20:28:41 -07:00
|
|
|
// SendEntry sends the entry to third-party providers when the user click on "Save".
|
2023-09-24 16:32:09 -07:00
|
|
|
func SendEntry(entry *model.Entry, userIntegrations *model.Integration) {
|
2024-07-04 22:59:47 +03:00
|
|
|
if userIntegrations.BetulaEnabled {
|
|
|
|
slog.Debug("Sending entry to Betula",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := betula.NewClient(userIntegrations.BetulaURL, userIntegrations.BetulaToken)
|
|
|
|
err := client.CreateBookmark(
|
|
|
|
entry.URL,
|
|
|
|
entry.Title,
|
|
|
|
entry.Tags,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
slog.Error("Unable to send entry to Betula",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.PinboardEnabled {
|
|
|
|
slog.Debug("Sending entry to Pinboard",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2021-09-07 20:28:41 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
client := pinboard.NewClient(userIntegrations.PinboardToken)
|
2023-08-13 21:58:45 -07:00
|
|
|
err := client.CreateBookmark(
|
2017-12-18 20:52:46 -08:00
|
|
|
entry.URL,
|
|
|
|
entry.Title,
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.PinboardTags,
|
|
|
|
userIntegrations.PinboardMarkAsUnread,
|
2017-12-18 20:52:46 -08:00
|
|
|
)
|
|
|
|
|
2017-12-02 21:12:03 -08:00
|
|
|
if err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Pinboard",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2017-12-02 21:12:03 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.InstapaperEnabled {
|
|
|
|
slog.Debug("Sending entry to Instapaper",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2021-09-07 20:28:41 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
client := instapaper.NewClient(userIntegrations.InstapaperUsername, userIntegrations.InstapaperPassword)
|
2017-12-18 20:52:46 -08:00
|
|
|
if err := client.AddURL(entry.URL, entry.Title); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Instapaper",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2017-12-18 20:52:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.WallabagEnabled {
|
|
|
|
slog.Debug("Sending entry to Wallabag",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2021-09-07 20:28:41 -07:00
|
|
|
|
2017-12-18 20:52:46 -08:00
|
|
|
client := wallabag.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.WallabagURL,
|
|
|
|
userIntegrations.WallabagClientID,
|
|
|
|
userIntegrations.WallabagClientSecret,
|
|
|
|
userIntegrations.WallabagUsername,
|
|
|
|
userIntegrations.WallabagPassword,
|
|
|
|
userIntegrations.WallabagOnlyURL,
|
2017-12-18 20:52:46 -08:00
|
|
|
)
|
|
|
|
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.CreateEntry(entry.URL, entry.Title, entry.Content); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Wallabag",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2017-12-02 21:12:03 -08:00
|
|
|
}
|
|
|
|
}
|
2018-02-25 19:49:08 +00:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.NotionEnabled {
|
|
|
|
slog.Debug("Sending entry to Notion",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2023-07-08 00:20:14 +02:00
|
|
|
|
|
|
|
client := notion.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.NotionToken,
|
|
|
|
userIntegrations.NotionPageID,
|
2023-07-08 00:20:14 +02:00
|
|
|
)
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.UpdateDocument(entry.URL, entry.Title); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Notion",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-07-08 00:20:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.NunuxKeeperEnabled {
|
|
|
|
slog.Debug("Sending entry to NunuxKeeper",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2021-09-07 20:28:41 -07:00
|
|
|
|
2018-02-25 19:49:08 +00:00
|
|
|
client := nunuxkeeper.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.NunuxKeeperURL,
|
|
|
|
userIntegrations.NunuxKeeperAPIKey,
|
2018-02-25 19:49:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if err := client.AddEntry(entry.URL, entry.Title, entry.Content); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to NunuxKeeper",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2018-02-25 19:49:08 +00:00
|
|
|
}
|
|
|
|
}
|
2018-05-20 13:31:56 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.EspialEnabled {
|
|
|
|
slog.Debug("Sending entry to Espial",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2022-04-21 05:44:47 +03:00
|
|
|
|
|
|
|
client := espial.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.EspialURL,
|
|
|
|
userIntegrations.EspialAPIKey,
|
2022-04-21 05:44:47 +03:00
|
|
|
)
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if err := client.CreateLink(entry.URL, entry.Title, userIntegrations.EspialTags); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Espial",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2022-04-21 05:44:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-23 18:12:31 +01:00
|
|
|
if userIntegrations.LinkAceEnabled {
|
|
|
|
slog.Debug("Sending entry to LinkAce",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := linkace.NewClient(
|
|
|
|
userIntegrations.LinkAceURL,
|
|
|
|
userIntegrations.LinkAceAPIKey,
|
|
|
|
userIntegrations.LinkAceTags,
|
|
|
|
userIntegrations.LinkAcePrivate,
|
|
|
|
userIntegrations.LinkAceCheckDisabled,
|
|
|
|
)
|
|
|
|
if err := client.AddURL(entry.URL, entry.Title); err != nil {
|
|
|
|
slog.Error("Unable to send entry to LinkAce",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.LinkdingEnabled {
|
|
|
|
slog.Debug("Sending entry to Linkding",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2022-05-23 23:53:06 +08:00
|
|
|
|
|
|
|
client := linkding.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.LinkdingURL,
|
|
|
|
userIntegrations.LinkdingAPIKey,
|
|
|
|
userIntegrations.LinkdingTags,
|
|
|
|
userIntegrations.LinkdingMarkAsUnread,
|
2022-05-23 23:53:06 +08:00
|
|
|
)
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.CreateBookmark(entry.URL, entry.Title); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Linkding",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2022-05-23 23:53:06 +08:00
|
|
|
}
|
|
|
|
}
|
2023-07-27 23:51:44 -04:00
|
|
|
|
2024-02-12 02:12:37 +01:00
|
|
|
if userIntegrations.LinkwardenEnabled {
|
|
|
|
slog.Debug("Sending entry to linkwarden",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := linkwarden.NewClient(
|
|
|
|
userIntegrations.LinkwardenURL,
|
|
|
|
userIntegrations.LinkwardenAPIKey,
|
|
|
|
)
|
|
|
|
if err := client.CreateBookmark(entry.URL, entry.Title); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Linkwarden",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-22 03:57:34 +00:00
|
|
|
if userIntegrations.ReadeckEnabled {
|
|
|
|
slog.Debug("Sending entry to Readeck",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := readeck.NewClient(
|
|
|
|
userIntegrations.ReadeckURL,
|
|
|
|
userIntegrations.ReadeckAPIKey,
|
|
|
|
userIntegrations.ReadeckLabels,
|
|
|
|
userIntegrations.ReadeckOnlyURL,
|
|
|
|
)
|
|
|
|
if err := client.CreateBookmark(entry.URL, entry.Title, entry.Content); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Readeck",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.ReadwiseEnabled {
|
|
|
|
slog.Debug("Sending entry to Readwise",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2023-07-27 23:51:44 -04:00
|
|
|
|
|
|
|
client := readwise.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.ReadwiseAPIKey,
|
2023-07-27 23:51:44 -04:00
|
|
|
)
|
|
|
|
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.CreateDocument(entry.URL); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Readwise",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-07-27 23:51:44 -04:00
|
|
|
}
|
|
|
|
}
|
2023-08-13 12:48:29 -07:00
|
|
|
|
2024-10-18 13:18:17 +08:00
|
|
|
if userIntegrations.CuboxEnabled {
|
|
|
|
slog.Debug("Sending entry to Cubox",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := cubox.NewClient(userIntegrations.CuboxAPILink)
|
|
|
|
|
|
|
|
if err := client.SaveLink(entry.URL); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Cubox",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.ShioriEnabled {
|
|
|
|
slog.Debug("Sending entry to Shiori",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2023-08-13 12:48:29 -07:00
|
|
|
|
|
|
|
client := shiori.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.ShioriURL,
|
|
|
|
userIntegrations.ShioriUsername,
|
|
|
|
userIntegrations.ShioriPassword,
|
2023-08-13 12:48:29 -07:00
|
|
|
)
|
|
|
|
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.CreateBookmark(entry.URL, entry.Title); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Shiori",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-08-13 12:48:29 -07:00
|
|
|
}
|
|
|
|
}
|
2023-08-13 14:30:57 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.ShaarliEnabled {
|
|
|
|
slog.Debug("Sending entry to Shaarli",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2023-08-13 14:30:57 -07:00
|
|
|
|
|
|
|
client := shaarli.NewClient(
|
2023-09-24 16:32:09 -07:00
|
|
|
userIntegrations.ShaarliURL,
|
|
|
|
userIntegrations.ShaarliAPISecret,
|
2023-08-13 14:30:57 -07:00
|
|
|
)
|
|
|
|
|
2023-08-13 21:58:45 -07:00
|
|
|
if err := client.CreateLink(entry.URL, entry.Title); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Shaarli",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-08-13 14:30:57 -07:00
|
|
|
}
|
|
|
|
}
|
2023-09-10 17:47:05 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
if userIntegrations.WebhookEnabled {
|
|
|
|
slog.Debug("Sending entry to Webhook",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.String("webhook_url", userIntegrations.WebhookURL),
|
|
|
|
)
|
2023-09-10 17:47:05 -07:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
webhookClient := webhook.NewClient(userIntegrations.WebhookURL, userIntegrations.WebhookSecret)
|
2023-09-10 17:47:05 -07:00
|
|
|
if err := webhookClient.SendSaveEntryWebhookEvent(entry); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Webhook",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.String("webhook_url", userIntegrations.WebhookURL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-09-10 17:47:05 -07:00
|
|
|
}
|
|
|
|
}
|
2024-04-27 20:35:56 -07:00
|
|
|
|
2023-12-04 23:05:04 -05:00
|
|
|
if userIntegrations.OmnivoreEnabled {
|
|
|
|
slog.Debug("Sending entry to Omnivore",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := omnivore.NewClient(userIntegrations.OmnivoreAPIKey, userIntegrations.OmnivoreURL)
|
|
|
|
if err := client.SaveUrl(entry.URL); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Omnivore",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2024-04-27 20:35:56 -07:00
|
|
|
|
2025-06-04 08:37:11 -04:00
|
|
|
if userIntegrations.KarakeepEnabled {
|
|
|
|
slog.Debug("Sending entry to Karakeep",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := karakeep.NewClient(userIntegrations.KarakeepAPIKey, userIntegrations.KarakeepURL)
|
2025-06-08 17:42:23 -07:00
|
|
|
if err := client.SaveURL(entry.URL); err != nil {
|
2025-06-04 08:37:11 -04:00
|
|
|
slog.Error("Unable to send entry to Karakeep",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-27 20:35:56 -07:00
|
|
|
if userIntegrations.RaindropEnabled {
|
|
|
|
slog.Debug("Sending entry to Raindrop",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := raindrop.NewClient(userIntegrations.RaindropToken, userIntegrations.RaindropCollectionID, userIntegrations.RaindropTags)
|
|
|
|
if err := client.CreateRaindrop(entry.URL, entry.Title); err != nil {
|
|
|
|
slog.Error("Unable to send entry to Raindrop",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2017-12-02 21:12:03 -08:00
|
|
|
}
|
2021-09-08 11:04:22 +08:00
|
|
|
|
2023-09-08 22:45:17 -07:00
|
|
|
// PushEntries pushes a list of entries to activated third-party providers during feed refreshes.
|
|
|
|
func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *model.Integration) {
|
|
|
|
if userIntegrations.MatrixBotEnabled {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Debug("Sending new entries to Matrix",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
|
|
|
)
|
2022-10-14 17:18:44 +02:00
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
err := matrixbot.PushEntries(
|
|
|
|
feed,
|
|
|
|
entries,
|
|
|
|
userIntegrations.MatrixBotURL,
|
|
|
|
userIntegrations.MatrixBotUser,
|
|
|
|
userIntegrations.MatrixBotPassword,
|
|
|
|
userIntegrations.MatrixBotChatID,
|
|
|
|
)
|
2022-10-14 17:18:44 +02:00
|
|
|
if err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send new entries to Matrix",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2022-10-14 17:18:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-08 22:45:17 -07:00
|
|
|
if userIntegrations.WebhookEnabled {
|
2025-02-01 01:33:11 +01:00
|
|
|
var webhookURL string
|
|
|
|
if feed.WebhookURL != "" {
|
|
|
|
webhookURL = feed.WebhookURL
|
|
|
|
} else {
|
|
|
|
webhookURL = userIntegrations.WebhookURL
|
|
|
|
}
|
|
|
|
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Debug("Sending new entries to Webhook",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
2025-02-01 01:33:11 +01:00
|
|
|
slog.String("webhook_url", webhookURL),
|
2023-09-24 16:32:09 -07:00
|
|
|
)
|
2021-09-07 20:28:41 -07:00
|
|
|
|
2025-02-01 01:33:11 +01:00
|
|
|
webhookClient := webhook.NewClient(webhookURL, userIntegrations.WebhookSecret)
|
2023-09-10 17:47:05 -07:00
|
|
|
if err := webhookClient.SendNewEntriesWebhookEvent(feed, entries); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Debug("Unable to send new entries to Webhook",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
2025-02-01 01:33:11 +01:00
|
|
|
slog.String("webhook_url", webhookURL),
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2021-09-08 11:04:22 +08:00
|
|
|
}
|
|
|
|
}
|
2023-08-13 21:58:45 -07:00
|
|
|
|
2024-07-13 16:52:30 -07:00
|
|
|
if userIntegrations.NtfyEnabled && feed.NtfyEnabled {
|
2025-02-24 01:41:51 +00:00
|
|
|
ntfyTopic := feed.NtfyTopic
|
|
|
|
if ntfyTopic == "" {
|
|
|
|
ntfyTopic = userIntegrations.NtfyTopic
|
|
|
|
}
|
2024-07-13 16:52:30 -07:00
|
|
|
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),
|
2025-02-24 01:41:51 +00:00
|
|
|
slog.String("topic", ntfyTopic),
|
2024-07-13 16:52:30 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
client := ntfy.NewClient(
|
|
|
|
userIntegrations.NtfyURL,
|
2025-02-24 01:41:51 +00:00
|
|
|
ntfyTopic,
|
2024-07-13 16:52:30 -07:00
|
|
|
userIntegrations.NtfyAPIToken,
|
|
|
|
userIntegrations.NtfyUsername,
|
|
|
|
userIntegrations.NtfyPassword,
|
|
|
|
userIntegrations.NtfyIconURL,
|
2025-01-13 09:58:24 +01:00
|
|
|
userIntegrations.NtfyInternalLinks,
|
2024-07-13 16:52:30 -07:00
|
|
|
feed.NtfyPriority,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := client.SendMessages(feed, entries); err != nil {
|
|
|
|
slog.Warn("Unable to send new entries to Ntfy", slog.Any("error", err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-04 01:02:10 +08:00
|
|
|
if userIntegrations.AppriseEnabled {
|
|
|
|
slog.Debug("Sending new entries to Apprise",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
|
|
|
)
|
|
|
|
|
|
|
|
appriseServiceURLs := userIntegrations.AppriseServicesURL
|
|
|
|
if feed.AppriseServiceURLs != "" {
|
|
|
|
appriseServiceURLs = feed.AppriseServiceURLs
|
|
|
|
}
|
|
|
|
|
|
|
|
client := apprise.NewClient(
|
|
|
|
appriseServiceURLs,
|
|
|
|
userIntegrations.AppriseURL,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := client.SendNotification(feed, entries); err != nil {
|
|
|
|
slog.Warn("Unable to send new entries to Apprise", slog.Any("error", err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-12 21:18:57 +01:00
|
|
|
if userIntegrations.DiscordEnabled {
|
|
|
|
slog.Debug("Sending new entries to Discord",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := discord.NewClient(
|
|
|
|
userIntegrations.DiscordWebhookLink,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := client.SendDiscordMsg(feed, entries); err != nil {
|
|
|
|
slog.Warn("Unable to send new entries to Discord", slog.Any("error", err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-27 00:20:00 +01:00
|
|
|
if userIntegrations.SlackEnabled {
|
|
|
|
slog.Debug("Sending new entries to Slack",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int("nb_entries", len(entries)),
|
|
|
|
slog.Int64("feed_id", feed.ID),
|
|
|
|
)
|
|
|
|
|
|
|
|
client := slack.NewClient(
|
|
|
|
userIntegrations.SlackWebhookLink,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := client.SendSlackMsg(feed, entries); err != nil {
|
|
|
|
slog.Warn("Unable to send new entries to Slack", slog.Any("error", err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-12 13:05:28 -05:00
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-08 22:45:17 -07:00
|
|
|
// Integrations that only support sending individual entries
|
2024-12-04 01:02:10 +08:00
|
|
|
if userIntegrations.TelegramBotEnabled {
|
2023-09-08 22:45:17 -07:00
|
|
|
for _, entry := range entries {
|
|
|
|
if userIntegrations.TelegramBotEnabled {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Debug("Sending a new entry to Telegram",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
)
|
2023-09-10 11:22:32 -07:00
|
|
|
|
|
|
|
if err := telegrambot.PushEntry(
|
|
|
|
feed,
|
|
|
|
entry,
|
|
|
|
userIntegrations.TelegramBotToken,
|
|
|
|
userIntegrations.TelegramBotChatID,
|
|
|
|
userIntegrations.TelegramBotTopicID,
|
|
|
|
userIntegrations.TelegramBotDisableWebPagePreview,
|
|
|
|
userIntegrations.TelegramBotDisableNotification,
|
2023-09-28 03:02:22 +00:00
|
|
|
userIntegrations.TelegramBotDisableButtons,
|
2023-09-10 11:22:32 -07:00
|
|
|
); err != nil {
|
2023-09-24 16:32:09 -07:00
|
|
|
slog.Error("Unable to send entry to Telegram",
|
|
|
|
slog.Int64("user_id", userIntegrations.UserID),
|
|
|
|
slog.Int64("entry_id", entry.ID),
|
|
|
|
slog.String("entry_url", entry.URL),
|
|
|
|
slog.Any("error", err),
|
|
|
|
)
|
2023-09-08 22:45:17 -07:00
|
|
|
}
|
|
|
|
}
|
2023-08-01 05:55:17 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-08 11:04:22 +08:00
|
|
|
}
|