readwise.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. // Readwise Reader API documentation: https://readwise.io/reader_api
  4. package readwise // import "miniflux.app/integration/readwise"
  5. import (
  6. "fmt"
  7. "net/url"
  8. "miniflux.app/http/client"
  9. )
  10. // Document structure of a Readwise Reader document
  11. // This initial version accepts only the one required field, the URL
  12. type Document struct {
  13. Url string `json:"url"`
  14. }
  15. // Client represents a Readwise Reader client.
  16. type Client struct {
  17. apiKey string
  18. }
  19. // NewClient returns a new Readwise Reader client.
  20. func NewClient(apiKey string) *Client {
  21. return &Client{apiKey: apiKey}
  22. }
  23. // AddEntry sends an entry to Readwise Reader.
  24. func (c *Client) AddEntry(link string) error {
  25. if c.apiKey == "" {
  26. return fmt.Errorf("readwise: missing credentials")
  27. }
  28. doc := &Document{
  29. Url: link,
  30. }
  31. apiURL, err := getAPIEndpoint("https://readwise.io/api/v3/save/")
  32. if err != nil {
  33. return err
  34. }
  35. clt := client.New(apiURL)
  36. clt.WithAuthorization("Token " + c.apiKey)
  37. response, err := clt.PostJSON(doc)
  38. if err != nil {
  39. return fmt.Errorf("readwise: unable to send entry: %v", err)
  40. }
  41. if response.HasServerFailure() {
  42. return fmt.Errorf("readwise: unable to send entry, status=%d", response.StatusCode)
  43. }
  44. return nil
  45. }
  46. func getAPIEndpoint(pathURL string) (string, error) {
  47. u, err := url.Parse(pathURL)
  48. if err != nil {
  49. return "", fmt.Errorf("readwise: invalid API endpoint: %v", err)
  50. }
  51. return u.String(), nil
  52. }