Openstatus
www.openstatus.dev
1package tinybird
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "fmt"
8 "net/http"
9 "net/url"
10 "os"
11
12 "github.com/rs/zerolog/log"
13)
14
15func getBaseURL() string {
16 // Use local Tinybird container if available (Docker/self-hosted)
17 // https://www.tinybird.co/docs/api-reference
18 if tinybirdURL := os.Getenv("TINYBIRD_URL"); tinybirdURL != "" {
19 return tinybirdURL + "/v0/events"
20 }
21 return "https://api.tinybird.co/v0/events"
22}
23
24type Client interface {
25 SendEvent(ctx context.Context, event any, dataSourceName string) error
26}
27
28type client struct {
29 httpClient *http.Client
30 apiKey string
31 baseURL string
32}
33
34func NewClient(httpClient *http.Client, apiKey string) Client {
35 return client{
36 httpClient: httpClient,
37 apiKey: apiKey,
38 baseURL: getBaseURL(),
39 }
40}
41
42func (c client) SendEvent(ctx context.Context, event any, dataSourceName string) error {
43 requestURL, err := url.Parse(c.baseURL)
44 if err != nil {
45 log.Ctx(ctx).Error().Err(err).Msg("unable to parse url")
46 return fmt.Errorf("unable to parse url: %w", err)
47 }
48
49 q := requestURL.Query()
50 q.Add("name", dataSourceName)
51 requestURL.RawQuery = q.Encode()
52
53 var payload bytes.Buffer
54 if err := json.NewEncoder(&payload).Encode(event); err != nil {
55 log.Ctx(ctx).Error().Err(err).Msg("unable to encode payload")
56 return fmt.Errorf("unable to encode payload: %w", err)
57 }
58
59 req, err := http.NewRequestWithContext(ctx, http.MethodPost, requestURL.String(), bytes.NewReader(payload.Bytes()))
60 if err != nil {
61 log.Ctx(ctx).Error().Err(err).Msg("unable to create request")
62 return fmt.Errorf("unable to create request: %w", err)
63 }
64 req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiKey))
65
66 resp, err := c.httpClient.Do(req)
67 if err != nil {
68 log.Ctx(ctx).Error().Err(err).Msg("unable to send request")
69 return fmt.Errorf("unable to send request: %w", err)
70 }
71 defer resp.Body.Close()
72
73 if resp.StatusCode != http.StatusAccepted {
74 log.Ctx(ctx).Error().Str("status", resp.Status).Msg("unexpected status code")
75 return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
76 }
77
78 return nil
79}