diff options
author | 2024-04-27 20:35:56 -0700 | |
---|---|---|
committer | 2024-05-02 16:23:00 -0700 | |
commit | ca62b0b36b5f5ecaf13e54f9b4c13c1f745cbfbb (patch) | |
tree | c347a2a565a147ef0924b4c2bfe811485b4874da /internal/integration | |
parent | 7d6a4243c1671bb0a978b32a4a5862f5f9d71da7 (diff) | |
download | v2-ca62b0b36b5f5ecaf13e54f9b4c13c1f745cbfbb.tar.gz v2-ca62b0b36b5f5ecaf13e54f9b4c13c1f745cbfbb.tar.zst v2-ca62b0b36b5f5ecaf13e54f9b4c13c1f745cbfbb.zip |
integration/raindrop: initial draft implementation
Diffstat (limited to 'internal/integration')
-rw-r--r-- | internal/integration/integration.go | 20 | ||||
-rw-r--r-- | internal/integration/raindrop/raindrop.go | 78 |
2 files changed, 98 insertions, 0 deletions
diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 710679ff..64447bc9 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -19,6 +19,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/raindrop" "miniflux.app/v2/internal/integration/readeck" "miniflux.app/v2/internal/integration/readwise" "miniflux.app/v2/internal/integration/shaarli" @@ -359,6 +360,7 @@ func SendEntry(entry *model.Entry, userIntegrations *model.Integration) { ) } } + if userIntegrations.OmnivoreEnabled { slog.Debug("Sending entry to Omnivore", slog.Int64("user_id", userIntegrations.UserID), @@ -376,6 +378,24 @@ func SendEntry(entry *model.Entry, userIntegrations *model.Integration) { ) } } + + 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), + ) + } + } } // PushEntries pushes a list of entries to activated third-party providers during feed refreshes. diff --git a/internal/integration/raindrop/raindrop.go b/internal/integration/raindrop/raindrop.go new file mode 100644 index 00000000..52506db1 --- /dev/null +++ b/internal/integration/raindrop/raindrop.go @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package raindrop // import "miniflux.app/v2/internal/integration/raindrop" + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "miniflux.app/v2/internal/version" +) + +const defaultClientTimeout = 10 * time.Second + +type Client struct { + token string + collectionID string + tags []string +} + +func NewClient(token, collectionID, tags string) *Client { + return &Client{token: token, collectionID: collectionID, tags: strings.Split(tags, ",")} +} + +// https://developer.raindrop.io/v1/raindrops/single#create-raindrop +func (c *Client) CreateRaindrop(entryURL, entryTitle string) error { + if c.token == "" { + return fmt.Errorf("raindrop: missing token") + } + + var request *http.Request + requestBodyJson, err := json.Marshal(&raindrop{ + Link: entryURL, + Title: entryTitle, + Collection: collection{Id: c.collectionID}, + Tags: c.tags, + }) + if err != nil { + return fmt.Errorf("raindrop: unable to encode request body: %v", err) + } + + request, err = http.NewRequest(http.MethodPost, "https://api.raindrop.io/rest/v1/raindrop", bytes.NewReader(requestBodyJson)) + if err != nil { + return fmt.Errorf("raindrop: unable to create request: %v", err) + } + request.Header.Set("Content-Type", "application/json") + + request.Header.Set("User-Agent", "Miniflux/"+version.Version) + request.Header.Set("Authorization", "Bearer "+c.token) + + httpClient := &http.Client{Timeout: defaultClientTimeout} + response, err := httpClient.Do(request) + if err != nil { + return fmt.Errorf("raindrop: unable to send request: %v", err) + } + defer response.Body.Close() + + if response.StatusCode >= 400 { + return fmt.Errorf("raindrop: unable to create bookmark: status=%d", response.StatusCode) + } + + return nil +} + +type raindrop struct { + Link string `json:"link"` + Title string `json:"title"` + Collection collection `json:"collection,omitempty"` + Tags []string `json:"tags"` +} + +type collection struct { + Id string `json:"$id"` +} |