birthdaybot/client/client.go
2023-07-11 16:29:57 +02:00

91 lines
1.8 KiB
Go

package client
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"git.ctrlz.es/mgdelacroix/birthdaybot/model"
)
var (
ErrEmptyURL = errors.New("URL cannot be empty")
)
type Client struct {
url string
httpClient *http.Client
headers map[string]string
}
func New(opts ...Option) (*Client, error) {
client := &Client{
httpClient: &http.Client{},
}
for _, opt := range opts {
client = opt(client)
}
if client.url == "" {
return nil, ErrEmptyURL
}
return client, nil
}
func (c *Client) Do(ctx context.Context, method, path, data string, headers map[string]string) (*http.Response, error) {
url, err := url.JoinPath(c.url, path)
if err != nil {
return nil, fmt.Errorf("cannot build request url: %w", err)
}
req, err := http.NewRequestWithContext(ctx, method, url, strings.NewReader(data))
if err != nil {
return nil, fmt.Errorf("cannot create request: %w", err)
}
for k, v := range c.headers {
req.Header.Set(k, v)
}
for k, v := range headers {
req.Header.Set(k, v)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("cannot do request: %w", err)
}
return resp, nil
}
func (c *Client) Health(ctx context.Context) (bool, error) {
resp, err := c.Do(ctx, http.MethodGet, "/health", "", nil)
if err != nil {
return false, err
}
defer resp.Body.Close()
return resp.StatusCode == 200, nil
}
func (c *Client) NextBirthdays(ctx context.Context) ([]*model.Birthday, error) {
resp, err := c.Do(ctx, http.MethodGet, "/next_birthdays", "", nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var birthdays []*model.Birthday
if err := json.NewDecoder(resp.Body).Decode(&birthdays); err != nil {
return nil, fmt.Errorf("cannot decode birthdays: %w", err)
}
return birthdays, nil
}