-
Notifications
You must be signed in to change notification settings - Fork 2
/
wildapricot.go
135 lines (114 loc) · 3.35 KB
/
wildapricot.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
125
126
127
128
129
130
131
132
133
134
135
package posthydra
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strings"
)
type WildApricotConfig struct {
Key string
AccountId int
}
// TokenAuthHeader encodes the API key on a WildApricotConfig to the
// Authorization header needed to gain an access token
func (c *WildApricotConfig) TokenAuthHeader() string {
raw := []byte(fmt.Sprintf("APIKEY:%s", c.Key))
encoded := base64.StdEncoding.EncodeToString(raw)
return fmt.Sprintf("Basic %s", encoded)
}
type WildApricotClient struct {
Config *WildApricotConfig
token string
}
func NewWildApricotClient(c *Config) *WildApricotClient {
return &WildApricotClient{Config: &c.WildApricot}
}
// AcquireToken must be called first to gain access to other API methods
func (w *WildApricotClient) AcquireToken() error {
c := new(http.Client)
var req *http.Request
var res *http.Response
var err error
scope := strings.NewReader("grant_type=client_credentials&scope=events")
req, err = http.NewRequest("POST", "https://oauth.wildapricot.org/auth/token", scope)
req.Header.Set("Authorization", w.Config.TokenAuthHeader())
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
res, err = c.Do(req)
if err != nil {
return err
}
if res.StatusCode != 200 {
return fmt.Errorf("Authentication request failed with status %s", res.Status)
}
js := make(map[string]interface{})
if err = json.NewDecoder(res.Body).Decode(&js); err != nil {
return err
}
if _, ok := js["access_token"]; !ok {
return fmt.Errorf("No access token in WildApricot response")
}
w.token = js["access_token"].(string)
return nil
}
// Read performs the work of fetching events from WildApricot's API
func (w *WildApricotClient) Read() ([]*Event, error) {
// Our return values
e := make([]*Event, 0)
var err error
// Our http objects
c := new(http.Client)
var req *http.Request
var res *http.Response
err = w.AcquireToken()
if err != nil {
return e, err
}
// With the newly acquired token in hand, make a request for Events
url := fmt.Sprintf("https://api.wildapricot.org/v2/Accounts/%d/events", w.Config.AccountId)
req, err = http.NewRequest("GET", url, nil)
if err != nil {
return e, err
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", w.token))
res, err = c.Do(req)
if err != nil {
return e, err
}
if res.StatusCode != 200 {
return e, fmt.Errorf("Events request failed with status %s", res.Status)
}
var waRes WildApricotResponse
if err = json.NewDecoder(res.Body).Decode(&waRes); err != nil {
return e, err
}
for _, event := range waRes.Events {
e = append(e, &Event{
Title: event.Name,
Start: event.StartDate,
End: event.EndDate,
URL: event.URL,
Location: event.Location,
})
}
return e, nil
}
// WildApricotResponse defines the response from the WildApricot Events API.
// Used for unmarshalling the response to JSON.
type WildApricotResponse struct {
Events []struct {
StartDate string
EndDate string
Location string
RegistrationEnabled bool
RegistrationsLimit int
PendingRegistrationsCount int
ConfirmedRegistrationsCount int
CheckedInAttendeesNumber int
Tags []string
AccessLevel string
ID int
URL string
Name string
}
}