Repository navigation
Expand file tree
/
Copy pathclient.go
More file actions
122 lines (101 loc) · 2.8 KB
/
Copy pathclient.go
File metadata and controls
122 lines (101 loc) · 2.8 KB
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
// Package groupme defines a client capable of executing API commands for the GroupMe chat service
package groupme
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
)
// GroupMeAPIBase - Endpoints are added on to this to get the full URI.
// Overridable for testing
const GroupMeAPIBase = "https://api.groupme.com/v3"
// Client communicates with the GroupMe API to perform actions
// on the basic types, i.e. Listing, Creating, Destroying
type Client struct {
httpClient *http.Client
endpointBase string
authorizationToken string
}
// NewClient creates a new GroupMe API Client
func NewClient(authToken string) *Client {
return &Client{
// TODO: enable transport information passing in
httpClient: &http.Client{},
endpointBase: GroupMeAPIBase,
authorizationToken: authToken,
}
}
// Close safely shuts down the Client
func (c *Client) Close() error {
c.httpClient.CloseIdleConnections()
return nil
}
// String returns a json formatted string
func (c Client) String() string {
return marshal(&c)
}
/*/// Handle parsing of nested interface type response ///*/
type jsonResponse struct {
Response response `json:"response"`
Meta `json:"meta"`
}
func newJSONResponse(i interface{}) *jsonResponse {
return &jsonResponse{Response: response{i}}
}
type response struct {
i interface{}
}
func (r response) UnmarshalJSON(bs []byte) error {
return json.NewDecoder(bytes.NewBuffer(bs)).Decode(r.i)
}
const errorStatusCodeMin = 300
func (c Client) do(ctx context.Context, req *http.Request, i interface{}) error {
req = req.WithContext(ctx)
if req.Method == "POST" {
req.Header.Set("Content-Type", "application/json")
}
getResp, err := c.httpClient.Do(req)
if err != nil {
return err
}
defer getResp.Body.Close()
var readBytes []byte
// Check Status Code is 1XX or 2XX
if getResp.StatusCode >= errorStatusCodeMin {
readBytes, err = ioutil.ReadAll(getResp.Body)
if err != nil {
// We couldn't read the output. Oh well; generate the appropriate error type anyway.
return &Meta{
Code: HTTPStatusCode(getResp.StatusCode),
}
}
resp := newJSONResponse(nil)
if err = json.Unmarshal(readBytes, &resp); err != nil {
// We couldn't parse the output. Oh well; generate the appropriate error type anyway.
return &Meta{
Code: HTTPStatusCode(getResp.StatusCode),
}
}
return &resp.Meta
}
if i == nil {
return nil
}
readBytes, err = ioutil.ReadAll(getResp.Body)
if err != nil {
return err
}
resp := newJSONResponse(i)
if err := json.Unmarshal(readBytes, &resp); err != nil {
return err
}
return nil
}
func (c Client) doWithAuthToken(ctx context.Context, req *http.Request, i interface{}) error {
URL := req.URL
query := URL.Query()
query.Set("token", c.authorizationToken)
URL.RawQuery = query.Encode()
return c.do(ctx, req, i)
}