-
Notifications
You must be signed in to change notification settings - Fork 5
/
pushy.go
169 lines (153 loc) · 5.7 KB
/
pushy.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Package pushy can be used to communicate with pushy service easily,
// saving time which would require to figure out the data type, endpoint, http method and shape of request to make
package pushy
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
// Create is a helper method to initialize a simple Pushy struct
// &Pushy{APIToken: "token", APIEndpoint: "https://api.pushy.me"}
// can be used
func Create(APIToken string, APIEndpoint string) *Pushy {
return &Pushy{
APIToken: APIToken,
APIEndpoint: APIEndpoint,
}
}
// GetDefaultAPIEndpoint returns the default api endpoint where they're hosted.
func GetDefaultAPIEndpoint() string {
return "https://api.pushy.me"
}
// GetDefaultHTTPClient returns a httpClient with configured timeout
func GetDefaultHTTPClient(timeout time.Duration) IHTTPClient {
client := http.Client{
Timeout: timeout,
}
return IHTTPClient(&client)
}
// SetHTTPClient sets a http client, it's useful when you're using sandboxed env like appengine
// this is required to do, pushy won't automatically use the default http client.
func (p *Pushy) SetHTTPClient(client IHTTPClient) {
p.httpClient = client
}
// GetHTTPClient returns the client which is being used with pushy
func (p *Pushy) GetHTTPClient() IHTTPClient {
return p.httpClient
}
// DeviceInfo returns information about a particular device
func (p Pushy) DeviceInfo(deviceID string) (*DeviceInfo, *Error, error) {
url := fmt.Sprintf("%s/devices/%s?api_key=%s", p.APIEndpoint, deviceID, p.APIToken)
var errResponse *Error
var info *DeviceInfo
err := get(p.httpClient, url, &info, &errResponse)
return info, errResponse, err
}
// DevicePresence returns data about presence of a data
func (p *Pushy) DevicePresence(deviceID ...string) (*DevicePresenceResponse, *Error, error) {
url := fmt.Sprintf("%s/devices/presence?api_key=%s", p.APIEndpoint, p.APIToken)
var devicePresenceResponse *DevicePresenceResponse
var pushyErr *Error
err := post(p.httpClient, url, DevicePresenceRequest{Tokens: deviceID}, &devicePresenceResponse, &pushyErr)
return devicePresenceResponse, pushyErr, err
}
// NotificationStatus returns status of a particular notification
func (p *Pushy) NotificationStatus(pushID string) (*NotificationStatus, *Error, error) {
url := fmt.Sprintf("%s/pushes/%s?api_key=%s", p.APIEndpoint, pushID, p.APIToken)
var errResponse *Error
var status *NotificationStatus
err := get(p.httpClient, url, &status, &errResponse)
return status, errResponse, err
}
// DeleteNotification deletes a created notification
func (p *Pushy) DeleteNotification(pushID string) (*SimpleSuccess, *Error, error) {
url := fmt.Sprintf("%s/pushes/%s?api_key=%s", p.APIEndpoint, pushID, p.APIToken)
var success *SimpleSuccess
var pushyErr *Error
err := del(p.httpClient, url, &success, &pushyErr)
return success, pushyErr, err
}
// SubscribeToTopic subscribes a particular device to topics (when you want to do from backend)
func (p *Pushy) SubscribeToTopic(deviceID string, topics ...string) (*SimpleSuccess, *Error, error) {
url := fmt.Sprintf("%s/devices/subscribe?api_key=%s", p.APIEndpoint, p.APIToken)
request := DeviceSubscriptionRequest{
Token: deviceID,
Topics: topics,
}
var success *SimpleSuccess
var pushyErr *Error
err := post(p.httpClient, url, request, &success, &pushyErr)
return success, pushyErr, err
}
// UnsubscribeFromTopic un subscribes a particular device from topics (when you want to do from backend)
func (p *Pushy) UnsubscribeFromTopic(token string, topics ...string) (*SimpleSuccess, *Error, error) {
url := fmt.Sprintf("%s/devices/unsubscribe?api_key=%s", p.APIEndpoint, p.APIToken)
request := DeviceSubscriptionRequest{
Token: token,
Topics: topics,
}
var success *SimpleSuccess
var pushyErr *Error
err := post(p.httpClient, url, request, &success, &pushyErr)
return success, pushyErr, err
}
// NotifyDevice sends notification data to devices
func (p *Pushy) NotifyDevice(request SendNotificationRequest) (*NotificationResponse, *Error, error) {
url := fmt.Sprintf("%s/push?api_key=%s", p.APIEndpoint, p.APIToken)
var success *NotificationResponse
var pushyErr *Error
err := post(p.httpClient, url, request, &success, &pushyErr)
return success, pushyErr, err
}
func get(client IHTTPClient, url string, positiveResponse interface{}, errResponse interface{}) error {
response, err := client.Get(url)
if err != nil {
positiveResponse = nil
errResponse = nil
return err
}
defer response.Body.Close()
body := response.Body
if response.StatusCode >= 400 {
positiveResponse = nil
json.NewDecoder(body).Decode(&errResponse)
return fmt.Errorf("%d %s", response.StatusCode, response.Status)
}
// decode positiveResponse
errResponse = nil
return json.NewDecoder(body).Decode(positiveResponse)
}
func post(client IHTTPClient, url string, body interface{}, posRes interface{}, errRes interface{}) error {
buffer := new(bytes.Buffer)
json.NewEncoder(buffer).Encode(body)
response, err := client.Post(url, "application/json", buffer)
if err != nil {
return err
}
defer response.Body.Close()
b := response.Body
if response.StatusCode >= 400 {
json.NewDecoder(b).Decode(&errRes)
return fmt.Errorf("%d %s", response.StatusCode, response.Status)
}
return json.NewDecoder(b).Decode(posRes)
}
func del(client IHTTPClient, url string, posRes interface{}, errRes interface{}) error {
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return err // I don't think there's anything which can result in this error.
}
response, err := client.Do(req)
if err != nil {
return err
}
defer response.Body.Close()
b := response.Body
if response.StatusCode >= 400 {
json.NewDecoder(b).Decode(&errRes)
return fmt.Errorf("%d %s", response.StatusCode, response.Status)
}
return json.NewDecoder(b).Decode(posRes)
}