Files
royalroadupdates/internal/pocketbase/client.go

81 lines
1.5 KiB
Go

package pocketbase
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
)
// Client handles interactions with the PocketBase API.
type Client struct {
endpoint *url.URL
http *http.Client
}
// New creates a new PocketBase client.
func New(endpoint string) *Client {
u, err := url.Parse(endpoint)
if err != nil || u == nil {
return &Client{
endpoint: &url.URL{},
http: &http.Client{Timeout: 30 * time.Second},
}
}
return &Client{
endpoint: u,
http: &http.Client{
Timeout: 30 * time.Second,
},
}
}
type record struct {
URL string `json:"url"`
}
type recordsResponse struct {
Items []record `json:"items"`
}
// GetBookmarkURLs retrieves URLs from the collection.
func (c *Client) GetBookmarkURLs(ctx context.Context) ([]string, error) {
// Clone the endpoint URL to avoid mutation on repeated calls.
u := *c.endpoint
q := u.Query()
q.Set("perPage", "200")
q.Set("fields", "url")
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
var recs recordsResponse
if err := json.NewDecoder(resp.Body).Decode(&recs); err != nil {
return nil, err
}
var urls []string
for _, r := range recs.Items {
if r.URL != "" {
urls = append(urls, r.URL)
}
}
return urls, nil
}