diff options
Diffstat (limited to 'internal/integration')
-rw-r--r-- | internal/integration/betula/betula.go | 57 | ||||
-rw-r--r-- | internal/integration/integration.go | 25 |
2 files changed, 82 insertions, 0 deletions
diff --git a/internal/integration/betula/betula.go b/internal/integration/betula/betula.go new file mode 100644 index 00000000..30dea95c --- /dev/null +++ b/internal/integration/betula/betula.go @@ -0,0 +1,57 @@ +package betula + +import ( + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "miniflux.app/v2/internal/urllib" + "miniflux.app/v2/internal/version" +) + +const defaultClientTimeout = 10 * time.Second + +type Client struct { + url string + token string +} + +func NewClient(url, token string) *Client { + return &Client{url: url, token: token} +} + +func (c *Client) CreateBookmark(entryURL, entryTitle string, tags []string) error { + apiEndpoint, err := urllib.JoinBaseURLAndPath(c.url, "/save-link") + if err != nil { + return fmt.Errorf("betula: unable to generate save-link endpoint: %v", err) + } + + values := url.Values{} + values.Add("url", entryURL) + values.Add("title", entryTitle) + values.Add("tags", strings.Join(tags, ",")) + + request, err := http.NewRequest(http.MethodPost, apiEndpoint+"?"+values.Encode(), nil) + if err != nil { + return fmt.Errorf("betula: unable to create request: %v", err) + } + + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set("User-Agent", "Miniflux/"+version.Version) + request.AddCookie(&http.Cookie{Name: "betula-token", Value: c.token}) + + httpClient := &http.Client{Timeout: defaultClientTimeout} + response, err := httpClient.Do(request) + if err != nil { + return fmt.Errorf("betula: unable to send request: %v", err) + } + defer response.Body.Close() + + if response.StatusCode >= 400 { + return fmt.Errorf("betula: unable to create bookmark: url=%s status=%d", apiEndpoint, response.StatusCode) + } + + return nil +} diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 64447bc9..ad596ec0 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -8,6 +8,7 @@ import ( "miniflux.app/v2/internal/config" "miniflux.app/v2/internal/integration/apprise" + "miniflux.app/v2/internal/integration/betula" "miniflux.app/v2/internal/integration/espial" "miniflux.app/v2/internal/integration/instapaper" "miniflux.app/v2/internal/integration/linkace" @@ -32,6 +33,30 @@ import ( // SendEntry sends the entry to third-party providers when the user click on "Save". func SendEntry(entry *model.Entry, userIntegrations *model.Integration) { + 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), + ) + } + } + if userIntegrations.PinboardEnabled { slog.Debug("Sending entry to Pinboard", slog.Int64("user_id", userIntegrations.UserID), |