pushlet 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +13 -13
- data/lib/pushlet/apns_gateway.rb +1 -1
- data/lib/pushlet/auth_middleware.rb +2 -2
- data/lib/pushlet/gateway_pool.rb +2 -2
- data/lib/pushlet/version.rb +1 -1
- data/pushlet.gemspec +0 -2
- data/test/gcm_push_test.rb +7 -7
- metadata +2 -35
- data/SPEC-OLD.md +0 -238
data/README.md
CHANGED
@@ -29,7 +29,7 @@ Then, setup a `config.ru` with the following. Setup an HTTP Auth so that you can
|
|
29
29
|
Pushlet is **thread optimized**, so use a threaded web server. I highly recommend using [Puma](http://puma.io), which is designed for threaded applications. You can add it by putting `gem 'puma'` in your Gemfile:
|
30
30
|
|
31
31
|
$ bundle exec puma
|
32
|
-
|
32
|
+
|
33
33
|
You can also use `rackup`:
|
34
34
|
|
35
35
|
$ bundle exec rackup -s puma
|
@@ -56,7 +56,7 @@ GCM does not have a concept of a "message" field. You are given a data input tha
|
|
56
56
|
|
57
57
|
curl http://127.0.0.1:9292/send_notification -d "device_token=YOUR_GCM_DEVICE_KEY&gcm_api_key=YOUR_GCM_API_KEY&data=%7B%22text%22%3A%22hello%22%7D"
|
58
58
|
|
59
|
-
## POST /
|
59
|
+
## POST /application\_feedback
|
60
60
|
|
61
61
|
Returns the feedback information from Apple. Not required for GCM.
|
62
62
|
|
@@ -87,18 +87,18 @@ Returns the feedback information from Apple. Not required for GCM.
|
|
87
87
|
}
|
88
88
|
|
89
89
|
{
|
90
|
-
"error": "application_not_found",
|
90
|
+
"error": "application_not_found",
|
91
91
|
"message": "no application found for the provided application_id"
|
92
92
|
}
|
93
93
|
|
94
|
-
## POST /
|
94
|
+
## POST /register\_application
|
95
95
|
|
96
96
|
Registers the APNS application with a certificate. This will create a socket connection when the first message is sent, providing a persistent connection to the Apple push servers.
|
97
97
|
|
98
|
-
*
|
98
|
+
* application\_id - a unique identifier for this application. If none is provided, a UUID-based one will be generated and returned to you, and you will need to store it somewhere to use the connection.
|
99
99
|
* apns\_p12 - Apple certificate in P12 format. Either this or apns\_pem are required.
|
100
100
|
* apns\_pem - Apple certificate in PEM format. Either this or apns\_p12 are required.
|
101
|
-
*
|
101
|
+
* apns\_mode - toggles whether to use sandbox mode or not. If set to "development", the sandbox is used. Defaults to production.
|
102
102
|
* apns\_p12\_pass - password for P12. Optional.
|
103
103
|
|
104
104
|
### Example Response
|
@@ -120,13 +120,13 @@ Registers the APNS application with a certificate. This will create a socket con
|
|
120
120
|
}
|
121
121
|
|
122
122
|
|
123
|
-
## POST /
|
123
|
+
## POST /send\_notification
|
124
124
|
|
125
125
|
Sends a message to either the GCM REST service or the APNS application socket.
|
126
126
|
|
127
127
|
* type - "apns" or "gcm". Required.
|
128
128
|
* application\_id - application\_id provided for registered APNS application. Either this or gcm\_api\_key are required.
|
129
|
-
* gcm\_api\_key - GCM secret key from Google. Either this or
|
129
|
+
* gcm\_api\_key - GCM secret key from Google. Either this or application\_id are required.
|
130
130
|
* device\_token - the device push token provided by the phone for your application. Required.
|
131
131
|
* data - the generic data JSON payload to send to either APNS or GCM.
|
132
132
|
|
@@ -160,27 +160,27 @@ APNS specific:
|
|
160
160
|
"error": "missing_identifier",
|
161
161
|
"message": "an application_id or gcm_api_key are required for this call"
|
162
162
|
}
|
163
|
-
|
163
|
+
|
164
164
|
{
|
165
165
|
"error": "device_token_required",
|
166
166
|
"message": "device_token is required, which is registed with the application on your phone"
|
167
167
|
}
|
168
|
-
|
168
|
+
|
169
169
|
{
|
170
170
|
"error": "application_not_found",
|
171
171
|
"message": "no application found for the provided application_id"
|
172
172
|
}
|
173
|
-
|
173
|
+
|
174
174
|
{
|
175
175
|
"error": "invalid_data_json",
|
176
176
|
"message": "data could not be converted to json: ERROR_MESSAGE_FROM_JSON_PARSER"
|
177
177
|
}
|
178
|
-
|
178
|
+
|
179
179
|
{
|
180
180
|
"error": "invalid_data_json",
|
181
181
|
"message": "data could not be converted to json: ERROR_MESSAGE_FROM_JSON_PARSER"
|
182
182
|
}
|
183
|
-
|
183
|
+
|
184
184
|
{
|
185
185
|
"error": "invalid_gcm_credentials",
|
186
186
|
"message": "the provided credentials were rejected by google servers"
|
data/lib/pushlet/apns_gateway.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module Pushlet
|
1
|
+
module Pushlet
|
2
2
|
class AuthMiddleware
|
3
3
|
def initialize(app, username, password)
|
4
4
|
@app = app
|
@@ -26,4 +26,4 @@ module Pushlet
|
|
26
26
|
[200, {'Content-Type' => 'application/json', 'Content-Length' => payload.length.to_s}, [payload]]
|
27
27
|
end
|
28
28
|
end
|
29
|
-
end
|
29
|
+
end
|
data/lib/pushlet/gateway_pool.rb
CHANGED
data/lib/pushlet/version.rb
CHANGED
data/pushlet.gemspec
CHANGED
@@ -15,11 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.add_dependency 'json'
|
17
17
|
s.add_dependency 'httpclient'
|
18
|
-
s.add_dependency 'sinatra'
|
19
18
|
s.add_dependency 'sinatra-jsonapi'
|
20
19
|
s.add_dependency 'escape'
|
21
20
|
s.add_dependency 'running'
|
22
|
-
s.add_dependency 'httpclient'
|
23
21
|
s.add_dependency 'uuid'
|
24
22
|
s.add_dependency 'grocer'
|
25
23
|
s.add_dependency 'puma'
|
data/test/gcm_push_test.rb
CHANGED
@@ -12,21 +12,21 @@ describe 'send gcm push' do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should fail gracefully for invalid key' do
|
15
|
-
|
15
|
+
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'works' do
|
19
|
-
|
19
|
+
|
20
20
|
stub_request(:post, "https://android.googleapis.com/gcm/send").
|
21
21
|
with(:body => "{\"registration_ids\":[\"1234\"],\"data\":{\"text\":\"hello\"},\"collapse_key\":null,\"delay_while_idle\":null,\"time_to_live\":null,\"dry_run\":null}",
|
22
22
|
:headers => {'Authorization'=>'key=ABCD', 'Content-Type'=>'application/json'}).
|
23
23
|
to_return(:status => 200, :body => %{{"multicast_id":6782339717028231855,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}})
|
24
|
-
|
24
|
+
|
25
25
|
post '/send_notification', gcm_api_key: 'ABCD', data: {text: 'hello'}, device_tokens: ['1234']
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
|
28
28
|
|
29
29
|
# binding.pry
|
30
|
-
|
30
|
+
|
31
31
|
end
|
32
|
-
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pushlet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-12-
|
13
|
+
date: 2012-12-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -44,22 +44,6 @@ dependencies:
|
|
44
44
|
- - ! '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: sinatra
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- - ! '>='
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
63
47
|
- !ruby/object:Gem::Dependency
|
64
48
|
name: sinatra-jsonapi
|
65
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,22 +92,6 @@ dependencies:
|
|
108
92
|
- - ! '>='
|
109
93
|
- !ruby/object:Gem::Version
|
110
94
|
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: httpclient
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
|
-
requirements:
|
116
|
-
- - ! '>='
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
119
|
-
type: :runtime
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
|
-
requirements:
|
124
|
-
- - ! '>='
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: '0'
|
127
95
|
- !ruby/object:Gem::Dependency
|
128
96
|
name: uuid
|
129
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -281,7 +249,6 @@ files:
|
|
281
249
|
- Gemfile
|
282
250
|
- README.md
|
283
251
|
- Rakefile
|
284
|
-
- SPEC-OLD.md
|
285
252
|
- lib/pushlet.rb
|
286
253
|
- lib/pushlet/api.rb
|
287
254
|
- lib/pushlet/apns_gateway.rb
|
data/SPEC-OLD.md
DELETED
@@ -1,238 +0,0 @@
|
|
1
|
-
# `POST /register_application`
|
2
|
-
|
3
|
-
TODO: Update spec with updated parameter names.
|
4
|
-
|
5
|
-
TODO: feedback_url not yet implemented.
|
6
|
-
|
7
|
-
* app_id: Required. A unique identifier for this application.
|
8
|
-
* feedback\_url: http://yoursite.com/notification_errors
|
9
|
-
* mode: development or production. Only applies to apple.
|
10
|
-
|
11
|
-
Provide either a P12 certificate or a Google GCM API Key
|
12
|
-
|
13
|
-
* p12: The P12 certificate as a string
|
14
|
-
* gcm\_api\_key: sefsdjfsdlkfj
|
15
|
-
|
16
|
-
## Response
|
17
|
-
|
18
|
-
```
|
19
|
-
{
|
20
|
-
"application_id": "a9b20610187a0130d39614109feae54c"
|
21
|
-
}
|
22
|
-
```
|
23
|
-
|
24
|
-
## Errors
|
25
|
-
|
26
|
-
### /application_feedback
|
27
|
-
|
28
|
-
```
|
29
|
-
{
|
30
|
-
"error": "missing_identifier",
|
31
|
-
"message": "an application\_id or gcm\_api\_key are required for this call"
|
32
|
-
}
|
33
|
-
```
|
34
|
-
|
35
|
-
```
|
36
|
-
{
|
37
|
-
"error": "application\_not\_found",
|
38
|
-
"message": "no application found for the provided application_id"
|
39
|
-
}
|
40
|
-
```
|
41
|
-
|
42
|
-
```
|
43
|
-
{
|
44
|
-
"error": "expired_certificate",
|
45
|
-
"message": "The certificate provided has expired. Please generate a new certificate."
|
46
|
-
}
|
47
|
-
```
|
48
|
-
|
49
|
-
|
50
|
-
# `/send_notification?type=apns`
|
51
|
-
|
52
|
-
TODO: Explain why the "device_token" parameter implemented but not the plural version.
|
53
|
-
|
54
|
-
* device_tokens - array or string. Apple does not support multiple, so just loop for that case.x
|
55
|
-
* alert - "text message to send or see apple docs for other options"
|
56
|
-
* badge - example: 5
|
57
|
-
* sound - "soundfile.aiff"
|
58
|
-
* identifier - unique key for message. enforce as a 32 bit integer if grocer does not
|
59
|
-
* data - JSON to dump in the root with the aps payload.
|
60
|
-
|
61
|
-
## Errors
|
62
|
-
|
63
|
-
```
|
64
|
-
{
|
65
|
-
"error": "invalid_input",
|
66
|
-
"message": "badge must be an integer"
|
67
|
-
}
|
68
|
-
```
|
69
|
-
|
70
|
-
```
|
71
|
-
{
|
72
|
-
"error": "missing_application",
|
73
|
-
"message": "The application could not be found. Register the application first using POST /register\_application"
|
74
|
-
}
|
75
|
-
```
|
76
|
-
|
77
|
-
### APNS Error Codes
|
78
|
-
|
79
|
-
TODO: Error responses are not sent back from the send_notification endpoint. Why not?
|
80
|
-
|
81
|
-
* 1: processing error
|
82
|
-
* 2: missing device token
|
83
|
-
* 3: missing topic
|
84
|
-
* 4: missing payload
|
85
|
-
* 5: invalid token size
|
86
|
-
* 6: invalid topic size
|
87
|
-
* 7: invalid payload size
|
88
|
-
* 8: invalid token
|
89
|
-
* 255: unknown
|
90
|
-
|
91
|
-
```
|
92
|
-
{
|
93
|
-
"error": "missing_topic",
|
94
|
-
"code": 3,
|
95
|
-
"device_token": "b85a40425e91a68512259b40f480a2a645efd185106dc66a3e73f6c89e95c963",
|
96
|
-
"identifier": "asdjfhd"
|
97
|
-
}
|
98
|
-
```
|
99
|
-
|
100
|
-
## APNS Payload Examples (Internal use only)
|
101
|
-
|
102
|
-
### Send text:
|
103
|
-
```
|
104
|
-
{
|
105
|
-
"aps": {
|
106
|
-
"alert": "hello"
|
107
|
-
}
|
108
|
-
}
|
109
|
-
```
|
110
|
-
|
111
|
-
### Set number on badge:
|
112
|
-
```
|
113
|
-
{
|
114
|
-
"aps": {
|
115
|
-
"badge": 9
|
116
|
-
}
|
117
|
-
}
|
118
|
-
```
|
119
|
-
|
120
|
-
### Sound (plays sound)
|
121
|
-
```
|
122
|
-
{
|
123
|
-
"aps": {
|
124
|
-
"sound": "ping.aiff"
|
125
|
-
}
|
126
|
-
}
|
127
|
-
```
|
128
|
-
|
129
|
-
All three of these parameters can be combined. You can also send a push notification with custom data and leave out the standard "aps" keys.
|
130
|
-
|
131
|
-
Other keys can be sent outside of the aps root. Example:
|
132
|
-
|
133
|
-
```
|
134
|
-
{
|
135
|
-
"aps": {
|
136
|
-
"alert": "hello"
|
137
|
-
},
|
138
|
-
"hello": "kitty"
|
139
|
-
}
|
140
|
-
```
|
141
|
-
|
142
|
-
|
143
|
-
# `/send_notification?type=gcm`
|
144
|
-
|
145
|
-
* app_id OR gcm\_api\_key
|
146
|
-
* device_tokens - json array or string (one device)
|
147
|
-
* data - the notification payload
|
148
|
-
* collapse\_key - if you send multiple pushes with the same collapse\_key, only the last will be delivered when the phone comes back online
|
149
|
-
* delay\_while\_idle - this will send the message when the device comes back from idle. Default: false
|
150
|
-
* time\_to\_live - number of seconds the message should be kept if the device is offline. Default: 4 weeks
|
151
|
-
* dry\_run - default: false
|
152
|
-
|
153
|
-
## Input/Format Errors
|
154
|
-
|
155
|
-
```
|
156
|
-
{
|
157
|
-
"error": "missing_input",
|
158
|
-
"message": "data is required"
|
159
|
-
}
|
160
|
-
```
|
161
|
-
|
162
|
-
```
|
163
|
-
{
|
164
|
-
"error": "missing_input",
|
165
|
-
"message": "device_tokens is required"
|
166
|
-
}
|
167
|
-
```
|
168
|
-
|
169
|
-
```
|
170
|
-
{
|
171
|
-
"error": "missing_input",
|
172
|
-
"message": "app_id OR gcm_api_key is required"
|
173
|
-
}
|
174
|
-
```
|
175
|
-
|
176
|
-
These errors will come from the GCM service
|
177
|
-
|
178
|
-
`{"error": "message_too_big"}`
|
179
|
-
|
180
|
-
`{"error": "invalid_data_key"}`
|
181
|
-
|
182
|
-
`{"error": "invalid_ttl"}`
|
183
|
-
|
184
|
-
## Error format for multiple responses
|
185
|
-
|
186
|
-
If the input format is valid, the service will attempt to send the notification. The results of sending each notification will be returned in "results".
|
187
|
-
|
188
|
-
```
|
189
|
-
{
|
190
|
-
"results": [
|
191
|
-
{"device_token": "fsdsfegr", "error": "invalid_registration"},
|
192
|
-
{"device_token": "dsdfdgfg", "success": true}
|
193
|
-
]
|
194
|
-
}
|
195
|
-
```
|
196
|
-
|
197
|
-
## Other possbile errors from the GCM service
|
198
|
-
|
199
|
-
* 401: "Invalid API Key"
|
200
|
-
* MissingRegistration
|
201
|
-
* InvalidRegistration
|
202
|
-
* MismatchSenderId
|
203
|
-
* NotRegistered
|
204
|
-
* MessageTooBig
|
205
|
-
* InvalidDataKey
|
206
|
-
* InvalidTtl
|
207
|
-
* InternalServerError
|
208
|
-
|
209
|
-
{"type": "MissingRegistration", device_token: "sdfsdf"} <- maybe convert to undercase?
|
210
|
-
|
211
|
-
## GCM Documentation
|
212
|
-
|
213
|
-
* http://developer.android.com/guide/google/gcm/index.html
|
214
|
-
* http://developer.android.com/guide/google/gcm/adv.html
|
215
|
-
|
216
|
-
|
217
|
-
# `apns\_feedback`
|
218
|
-
|
219
|
-
TODO: Update this explanation with a reason why this was implemented as a GET API
|
220
|
-
method instead of as described below.
|
221
|
-
|
222
|
-
The Pushlet service will periodically check the APNS feedback service for errors. If any
|
223
|
-
errors are reported by Apple, Pushlet will deliver a POST to the registered `callback_url`
|
224
|
-
for the application.
|
225
|
-
|
226
|
-
The feedback payload will contain the device token and the timestamp of the error.
|
227
|
-
|
228
|
-
|
229
|
-
```
|
230
|
-
{
|
231
|
-
"app_id": "14002",
|
232
|
-
"type": "feedback",
|
233
|
-
"device_token": "b85a40425e91a68512259b40f480a2a645efd185106dc66a3e73f6c89e95c963",
|
234
|
-
"timestamp": 1352502272
|
235
|
-
}
|
236
|
-
```
|
237
|
-
|
238
|
-
|