@@ -6,34 +6,103 @@ package karakeep // import "miniflux.app/v2/internal/integration/karakeep"
66import (
77 "bytes"
88 "encoding/json"
9+ "errors"
910 "fmt"
1011 "io"
1112 "net/http"
13+ "strings"
1214 "time"
1315
1416 "miniflux.app/v2/internal/version"
1517)
1618
1719const defaultClientTimeout = 10 * time .Second
1820
19- type errorResponse struct {
20- Code string `json:"code"`
21- Error string `json:"error"`
21+ type Client struct {
22+ wrapped * http.Client
23+ apiEndpoint string
24+ apiToken string
25+ tags string
26+ }
27+
28+ type tagItem struct {
29+ TagName string `json:"tagName"`
2230}
2331
2432type saveURLPayload struct {
2533 Type string `json:"type"`
2634 URL string `json:"url"`
2735}
2836
29- type Client struct {
30- wrapped * http.Client
31- apiEndpoint string
32- apiToken string
37+ type saveURLResponse struct {
38+ ID string `json:"id"`
3339}
3440
35- func NewClient (apiToken string , apiEndpoint string ) * Client {
36- return & Client {wrapped : & http.Client {Timeout : defaultClientTimeout }, apiEndpoint : apiEndpoint , apiToken : apiToken }
41+ type attachTagsPayload struct {
42+ Tags []tagItem `json:"tags"`
43+ }
44+
45+ type errorResponse struct {
46+ Code string `json:"code"`
47+ Error string `json:"error"`
48+ }
49+
50+ func NewClient (apiToken string , apiEndpoint string , tags string ) * Client {
51+ return & Client {wrapped : & http.Client {Timeout : defaultClientTimeout }, apiEndpoint : apiEndpoint , apiToken : apiToken , tags : tags }
52+ }
53+
54+ func (c * Client ) attachTags (entryID string ) error {
55+ if c .tags == "" {
56+ return nil
57+ }
58+
59+ tagItems := make ([]tagItem , 0 )
60+ for tag := range strings .SplitSeq (c .tags , "," ) {
61+ if trimmedTag := strings .TrimSpace (tag ); trimmedTag != "" {
62+ tagItems = append (tagItems , tagItem {TagName : trimmedTag })
63+ }
64+ }
65+
66+ if len (tagItems ) == 0 {
67+ return nil
68+ }
69+
70+ tagRequestBody , err := json .Marshal (& attachTagsPayload {
71+ Tags : tagItems ,
72+ })
73+ if err != nil {
74+ return fmt .Errorf ("karakeep: unable to encode tag request body: %v" , err )
75+ }
76+
77+ tagRequest , err := http .NewRequest (http .MethodPost , fmt .Sprintf ("%s/%s/tags" , c .apiEndpoint , entryID ), bytes .NewReader (tagRequestBody ))
78+ if err != nil {
79+ return fmt .Errorf ("karakeep: unable to create tag request: %v" , err )
80+ }
81+
82+ tagRequest .Header .Set ("Authorization" , "Bearer " + c .apiToken )
83+ tagRequest .Header .Set ("Content-Type" , "application/json" )
84+ tagRequest .Header .Set ("User-Agent" , "Miniflux/" + version .Version )
85+
86+ tagResponse , err := c .wrapped .Do (tagRequest )
87+ if err != nil {
88+ return fmt .Errorf ("karakeep: unable to send tag request: %v" , err )
89+ }
90+ defer tagResponse .Body .Close ()
91+
92+ if tagResponse .StatusCode != http .StatusOK && tagResponse .StatusCode != http .StatusCreated {
93+ tagResponseBody , err := io .ReadAll (tagResponse .Body )
94+ if err != nil {
95+ return fmt .Errorf ("karakeep: failed to parse tag response: %s" , err )
96+ }
97+
98+ var errResponse errorResponse
99+ if err := json .Unmarshal (tagResponseBody , & errResponse ); err != nil {
100+ return fmt .Errorf ("karakeep: unable to parse tag error response: status=%d body=%s" , tagResponse .StatusCode , string (tagResponseBody ))
101+ }
102+ return fmt .Errorf ("karakeep: failed to attach tags: status=%d errorcode=%s %s" , tagResponse .StatusCode , errResponse .Code , errResponse .Error )
103+ }
104+
105+ return nil
37106}
38107
39108func (c * Client ) SaveURL (entryURL string ) error {
@@ -77,5 +146,18 @@ func (c *Client) SaveURL(entryURL string) error {
77146 return fmt .Errorf ("karakeep: failed to save URL: status=%d errorcode=%s %s" , resp .StatusCode , errResponse .Code , errResponse .Error )
78147 }
79148
149+ var response saveURLResponse
150+ if err := json .Unmarshal (responseBody , & response ); err != nil {
151+ return fmt .Errorf ("karakeep: unable to parse response: %v" , err )
152+ }
153+
154+ if response .ID == "" {
155+ return errors .New ("karakeep: unable to get ID from response" )
156+ }
157+
158+ if err := c .attachTags (response .ID ); err != nil {
159+ return fmt .Errorf ("karakeep: unable to attach tags: %v" , err )
160+ }
161+
80162 return nil
81163}
0 commit comments