/
nma.go
173 lines (143 loc) · 3.67 KB
/
nma.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
170
171
172
173
// Package nma is a NotifyMyAndroid client for go.
//
// See https://www.notifymyandroid.com/api.jsp for API details.
package nma
import (
"encoding/xml"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/dustin/httputil"
)
const (
apiServer = "https://www.notifymyandroid.com"
verifyPath = "/publicapi/verify"
notifyPath = "/publicapi/notify"
verifyURL = apiServer + verifyPath
notifyURL = apiServer + notifyPath
)
// PriorityLevel defines the priority of a notification.
type PriorityLevel int
// Priority levels
const (
VeryLow PriorityLevel = -2
Moderate = -1
Normal = 0
High = 1
Emergency = 2
)
// ContentType specifies the content type of a message.
type ContentType string
// Available content types
const (
ContentTypeHTML ContentType = "text/html"
ContentTypeText = "text/plain"
)
// A Notification contains all the information to deliver.
type Notification struct {
Application string
Description string
Event string
Priority PriorityLevel
URL string
ContentType ContentType
}
// NMA is the entry point for all API calls.
type NMA struct {
apiKey []string
developerKey string
client *http.Client
}
// New gets a new NMA object with the given apiKey
func New(apiKey string) *NMA {
return NewWithClient(apiKey, http.DefaultClient)
}
// NewWithClient gets a new NMA object with the given apiKey and
// http.Client
func NewWithClient(apiKey string, client *http.Client) *NMA {
return &NMA{apiKey: []string{apiKey}, client: client}
}
// AddKey adds an API key to the list to try.
func (nma *NMA) AddKey(apiKey string) {
nma.apiKey = append(nma.apiKey, apiKey)
}
// SetDeveloperKey sets the Developer key for the NMA object
func (nma *NMA) SetDeveloperKey(devKey string) {
nma.developerKey = devKey
}
type response struct {
Err *struct {
Code int `xml:"code,attr"`
Resettimer int `xml:"resettimer,attr"`
Message string `xml:",chardata"`
} `xml:"error"`
Succ *struct {
Code int `xml:"code,attr"`
Remaining int `xml:"remaining,attr"`
Resettimer int `xml:"resettimer,attr"`
} `xml:"success"`
}
func (e *response) Error() string {
return e.Err.Message
}
func decodeResponse(r io.Reader) (xres response, err error) {
if err = xml.NewDecoder(r).Decode(&xres); err != nil {
return response{}, err
}
if xres.Err != nil {
err = &xres
}
return
}
func (nma *NMA) handleResponse(res *http.Response) error {
if res.StatusCode > 300 || res.StatusCode < 200 {
return httputil.HTTPError(res)
}
_, err := decodeResponse(res.Body)
if err != nil {
// Fill response stuff here.
}
return err
}
// Verify your credentials.
func (nma *NMA) Verify(apikey string) error {
vals := url.Values{"apikey": {apikey}}
if nma.developerKey != "" {
vals["developerkey"] = []string{nma.developerKey}
}
r, err := nma.client.Get(verifyURL + "?" + vals.Encode())
if err != nil {
return err
}
defer r.Body.Close()
return nma.handleResponse(r)
}
// Notify sends a notification.
func (nma *NMA) Notify(n *Notification) (err error) {
vals := url.Values{
"apikey": {strings.Join(nma.apiKey, ",")},
"application": {n.Application},
"description": {n.Description},
"event": {n.Event},
}
if n.Priority != 0 {
vals["priority"] = []string{strconv.Itoa(int(n.Priority))}
}
if n.URL != "" {
vals["url"] = []string{n.URL}
}
if n.ContentType != "" {
vals["content-type"] = []string{string(n.ContentType)}
}
if nma.developerKey != "" {
vals["developerkey"] = []string{nma.developerKey}
}
r, err := nma.client.PostForm(notifyURL, vals)
if err != nil {
return
}
defer r.Body.Close()
return nma.handleResponse(r)
}