-
Notifications
You must be signed in to change notification settings - Fork 4
/
webhook.go
76 lines (69 loc) · 1.7 KB
/
webhook.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
package limacharlie
import (
"bytes"
"compress/gzip"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"time"
)
type WebhookSender struct {
url string
secret string
client *http.Client
}
func (o *Organization) NewWebhookSender(hookName string, secretValue string) (*WebhookSender, error) {
urls, err := o.GetURLs()
if err != nil {
return nil, fmt.Errorf("failed resolving org URLs: %v", err)
}
hookURL, ok := urls["hooks"]
if !ok {
return nil, errors.New("hook URL not found in org URLs")
}
return &WebhookSender{
url: fmt.Sprintf("https://%s/%s/%s", hookURL, o.GetOID(), url.PathEscape(hookName)),
secret: secretValue,
client: &http.Client{
Timeout: 30 * time.Second,
},
}, nil
}
func (w *WebhookSender) Send(data interface{}) error {
// Send a JSON webhook to a LimaCharlie Webhook Cloud Sensor/Adapter, requires
// the `data` to be marshalable via the `json` package.
b := &bytes.Buffer{}
z := gzip.NewWriter(b)
e := json.NewEncoder(z)
if err := e.Encode(data); err != nil {
return err
}
if err := z.Close(); err != nil {
return err
}
r, err := http.NewRequest(http.MethodPost, w.url, b)
if err != nil {
return err
}
r.Header.Set("Content-Type", "application/json")
r.Header.Set("Content-Encoding", "gzip")
r.Header.Set("User-Agent", "lc-sdk-webhook")
r.Header.Set("lc-secret", w.secret)
resp, err := w.client.Do(r)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
tmpErrString := [128]byte{}
resp.Body.Read(tmpErrString[:])
return fmt.Errorf("http status code %d: %s", resp.StatusCode, string(tmpErrString[:]))
}
return nil
}
func (w *WebhookSender) Close() error {
w.client.CloseIdleConnections()
return nil
}