-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathnovu.go
124 lines (96 loc) · 2.47 KB
/
novu.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package lib
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
"github.com/pkg/errors"
)
const (
NovuURL = "https://api.novu.co"
NovuVersion = "v1"
)
type Config struct {
BackendURL *url.URL
HttpClient *http.Client
}
type APIClient struct {
apiKey string
config *Config
common service
// Api Service
SubscriberApi *SubscriberService
EventApi *EventService
TopicsApi *TopicService
IntegrationsApi *IntegrationService
}
type service struct {
client *APIClient
}
func NewAPIClient(apiKey string, cfg *Config) *APIClient {
cfg.BackendURL = buildBackendURL(cfg)
if cfg.HttpClient == nil {
cfg.HttpClient = &http.Client{Timeout: 20 * time.Second}
}
c := &APIClient{apiKey: apiKey}
c.config = cfg
c.common.client = c
// API Services
c.EventApi = (*EventService)(&c.common)
c.SubscriberApi = (*SubscriberService)(&c.common)
c.TopicsApi = (*TopicService)(&c.common)
c.IntegrationsApi = (*IntegrationService)(&c.common)
return c
}
func (c APIClient) sendRequest(req *http.Request, resp interface{}) (*http.Response, error) {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("ApiKey %s", c.apiKey))
res, err := c.config.HttpClient.Do(req)
if err != nil {
return res, errors.Wrap(err, "failed to execute request")
}
body, _ := io.ReadAll(res.Body)
defer res.Body.Close()
if res.StatusCode >= http.StatusMultipleChoices {
return res, errors.Errorf(
`request was not successful, status code %d, %s`, res.StatusCode,
string(body),
)
}
if string(body) == "" {
resp = map[string]string{}
return res, nil
}
err = c.decode(&resp, body)
if err != nil {
return res, errors.Wrap(err, "unable to unmarshal response body")
}
return res, nil
}
func (c APIClient) mergeStruct(target, patch interface{}) (interface{}, error) {
var m map[string]interface{}
targetPayload, _ := json.Marshal(target)
patchPayload, _ := json.Marshal(patch)
_ = json.Unmarshal(targetPayload, &m)
_ = json.Unmarshal(patchPayload, &m)
return m, nil
}
func (c APIClient) decode(v interface{}, b []byte) (err error) {
if err = json.Unmarshal(b, v); err != nil {
return err
}
return nil
}
func buildBackendURL(cfg *Config) *url.URL {
if cfg.BackendURL == nil {
rawURL := fmt.Sprintf("%s/%s", NovuURL, NovuVersion)
return MustParseURL(rawURL)
}
if strings.Contains(cfg.BackendURL.String(), "novu.co/v") {
return cfg.BackendURL
}
return cfg.BackendURL.JoinPath(NovuVersion)
}