speedy_c2dm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +34 -0
- data/Rakefile +1 -0
- data/lib/speedy_c2dm/version.rb +3 -0
- data/lib/speedy_c2dm.rb +110 -0
- data/speedy_c2dm.gemspec +22 -0
- data/test/helper.rb +18 -0
- data/test/test_speedy_c2dm.rb +38 -0
- metadata +72 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use "ruby-1.9.2-p290@speedy_c2dm"
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Amro Mousa, (c) 2011 Brandon Keene, (c) 2011 Sandeep Ghael
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# c2dm
|
2
|
+
|
3
|
+
c2dm sends push notifications to Android devices via google [c2dm](http://code.google.com/android/c2dm/index.html).
|
4
|
+
|
5
|
+
# How is this GEM different than other C2DM gems?
|
6
|
+
|
7
|
+
To use C2DM the server needs to fetch and store authenticaion tokens from Google. This token will periodically expire, and the recommendation from Google is that "the server should store the token and have a policy to refresh it periodically." Other C2DM gems take a brute force method around this issue, by requesting a new authenticaion token from Google for *each* notification request they send. This effectively doubles the number of HTTP calls being made for each notification.
|
8
|
+
|
9
|
+
This GEM will request the token when the SpeedyC2DM::API class is first initialized. From then on, it will use the auth token stored as an instance variable. On subsequent notification calls, it will check for 'Update-Client-Auth' or check for status 401 (auth failed). When it detects either of these, it will then request new tokens from Google servers. In the case of status 503 (service unavailable), a return message indicating 503 is returned. It is suggested that you retry after exponential back-off in the case of 503 (using something like resque-retry).
|
10
|
+
|
11
|
+
##Installation
|
12
|
+
|
13
|
+
$ gem install speedy_c2dm
|
14
|
+
|
15
|
+
##Requirements
|
16
|
+
|
17
|
+
An Android device running 2.2 or newer, its registration token, and a google account registered for c2dm.
|
18
|
+
|
19
|
+
##Usage
|
20
|
+
|
21
|
+
c2dm = SpeedyC2DM::API.new(TEST_EMAIL, TEST_PASSWORD)
|
22
|
+
|
23
|
+
options = {
|
24
|
+
:registration_id => TEST_REGISTRATION_ID,
|
25
|
+
:message => "Hi!",
|
26
|
+
:extra_data => 42,
|
27
|
+
:collapse_key => "some-collapse-key"
|
28
|
+
}
|
29
|
+
|
30
|
+
response = c2dm.send_notification(options)
|
31
|
+
|
32
|
+
##Copyrights
|
33
|
+
|
34
|
+
* See LICENSE.txt for details.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/lib/speedy_c2dm.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require "speedy_c2dm/version"
|
2
|
+
require 'typhoeus'
|
3
|
+
|
4
|
+
module SpeedyC2DM
|
5
|
+
|
6
|
+
class API
|
7
|
+
AUTH_URL = 'https://www.google.com/accounts/ClientLogin'
|
8
|
+
PUSH_URL = 'https://android.apis.google.com/c2dm/send'
|
9
|
+
|
10
|
+
# Initialize with an API key and config options
|
11
|
+
def initialize(email, password)
|
12
|
+
@email = email
|
13
|
+
@password = password
|
14
|
+
|
15
|
+
@auth_token = get_auth_token(@email, @password)
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_auth_token(email, password)
|
19
|
+
post_body = "accountType=HOSTED_OR_GOOGLE&Email=#{email}&Passwd=#{password}&service=ac2dm"
|
20
|
+
params = {
|
21
|
+
:body => post_body,
|
22
|
+
:headers => {
|
23
|
+
'Content-type' => 'application/x-www-form-urlencoded',
|
24
|
+
'Content-length' => "#{post_body.length}"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
response = Typhoeus::Request.post(AUTH_URL, params)
|
28
|
+
return response.body.split("\n")[2].gsub("Auth=", "")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Send a notification
|
32
|
+
#
|
33
|
+
# :registration_id is required.
|
34
|
+
# :collapse_key is optional.
|
35
|
+
#
|
36
|
+
# Other +options+ will be sent as "data.<key>=<value>"
|
37
|
+
#
|
38
|
+
# +options+ = {
|
39
|
+
# :registration_id => "...",
|
40
|
+
# :message => "Hi!",
|
41
|
+
# :extra_data => 42,
|
42
|
+
# :collapse_key => "some-collapse-key"
|
43
|
+
# }
|
44
|
+
def send_notification(options)
|
45
|
+
request = requestObject(options)
|
46
|
+
|
47
|
+
hydra = Typhoeus::Hydra.new
|
48
|
+
hydra.queue request
|
49
|
+
hydra.run # this is a blocking call that returns once all requests are complete
|
50
|
+
|
51
|
+
# the response object will be set after the request is run
|
52
|
+
response = request.response
|
53
|
+
|
54
|
+
# the response can be one of three codes:
|
55
|
+
# 200 (success)
|
56
|
+
# 401 (auth failed)
|
57
|
+
# 503 (retry later with exponential backoff)
|
58
|
+
# see more documentation here: http://code.google.com/android/c2dm/#testing
|
59
|
+
if response.code.eql? 200
|
60
|
+
|
61
|
+
# look for the header 'Update-Client-Auth'
|
62
|
+
# in the response you get after sending a message. It indicates that
|
63
|
+
# this is the token to be used for the next message to send.
|
64
|
+
if response.headers_hash['Update-Client-Auth']
|
65
|
+
@auth_token = get_auth_token(@email, @password)
|
66
|
+
end
|
67
|
+
return "success: 200"
|
68
|
+
|
69
|
+
elsif response.code.eql? 401
|
70
|
+
|
71
|
+
# auth failed. Refresh auth key and requeue
|
72
|
+
@auth_token = get_auth_token(@email, @password)
|
73
|
+
hydra.queue request(options)
|
74
|
+
hydra.run # this is a blocking call that returns once all requests are complete
|
75
|
+
|
76
|
+
response_inner = request.response
|
77
|
+
if response_inner.code.eql? 200
|
78
|
+
return "success"
|
79
|
+
elsif response_inner.code.eql? 401
|
80
|
+
return "failed: 401 - auth failed"
|
81
|
+
elsif response_inner.code.eql? 503
|
82
|
+
return "failed: 503 - service unavailable"
|
83
|
+
end
|
84
|
+
|
85
|
+
elsif response.code.eql? 503
|
86
|
+
|
87
|
+
# service un-available.
|
88
|
+
return "failed: 503 - service unavailable"
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def requestObject(options)
|
94
|
+
payload = {}
|
95
|
+
payload[:registration_id] = options.delete(:registration_id)
|
96
|
+
payload[:collapse_key] = options.delete(:collapse_key)
|
97
|
+
options.each {|key, value| payload["data.#{key}"] = value}
|
98
|
+
|
99
|
+
Typhoeus::Request.new(PUSH_URL, {
|
100
|
+
:method => :post,
|
101
|
+
:params => payload,
|
102
|
+
:headers => {
|
103
|
+
'Authorization' => "GoogleLogin auth=#{@auth_token}"
|
104
|
+
}
|
105
|
+
})
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
data/speedy_c2dm.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "speedy_c2dm/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "speedy_c2dm"
|
7
|
+
s.version = SpeedyC2dm::VERSION
|
8
|
+
s.authors = ["Sandeep Ghael"]
|
9
|
+
s.email = ["sghael@ravidapp.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Speedy C2DM is an intelligent gem for sending push notifications to Android devices via Google C2DM.}
|
12
|
+
s.description = %q{Speedy C2DM sends push notifications to Android devices via google c2dm.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "speedy_c2dm"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "typhoeus"
|
22
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'speedy_c2dm'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
current_dir = File.expand_path(File.dirname(__FILE__))
|
2
|
+
require File.join(current_dir, 'helper')
|
3
|
+
|
4
|
+
class TestSpeedyC2DM < Test::Unit::TestCase
|
5
|
+
|
6
|
+
TEST_EMAIL = "TODO - Fill me"
|
7
|
+
TEST_PASSWORD = "TODO - Fill me"
|
8
|
+
INVALID_TEST_EMAIL = "foo-bar.com"
|
9
|
+
TEST_REGISTRATION_ID = "TODO - Fill me"
|
10
|
+
|
11
|
+
should "not raise an error if the API key is valid" do
|
12
|
+
assert_nothing_raised do
|
13
|
+
SpeedyC2DM::API.new(TEST_EMAIL, TEST_PASSWORD)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
should "raise an error if the email/password is not provided" do
|
18
|
+
assert_raise(ArgumentError) do
|
19
|
+
SpeedyC2DM::API.new()
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
should "not raise an error if a send notification call succeeds" do
|
24
|
+
assert_nothing_raised do
|
25
|
+
speedyC2DM = SpeedyC2DM::API.new(TEST_EMAIL, TEST_PASSWORD)
|
26
|
+
|
27
|
+
options = {
|
28
|
+
:registration_id => TEST_REGISTRATION_ID,
|
29
|
+
:message => "Hi!",
|
30
|
+
:extra_data => 42,
|
31
|
+
:collapse_key => "some-collapse-key"
|
32
|
+
}
|
33
|
+
|
34
|
+
response = speedyC2DM.send_notification(options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: speedy_c2dm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sandeep Ghael
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-01 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: typhoeus
|
17
|
+
requirement: &2157328800 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2157328800
|
26
|
+
description: Speedy C2DM sends push notifications to Android devices via google c2dm.
|
27
|
+
email:
|
28
|
+
- sghael@ravidapp.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- .rvmrc
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE.txt
|
37
|
+
- README.markdown
|
38
|
+
- Rakefile
|
39
|
+
- lib/speedy_c2dm.rb
|
40
|
+
- lib/speedy_c2dm/version.rb
|
41
|
+
- speedy_c2dm.gemspec
|
42
|
+
- test/helper.rb
|
43
|
+
- test/test_speedy_c2dm.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: ''
|
46
|
+
licenses: []
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project: speedy_c2dm
|
65
|
+
rubygems_version: 1.6.2
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Speedy C2DM is an intelligent gem for sending push notifications to Android
|
69
|
+
devices via Google C2DM.
|
70
|
+
test_files:
|
71
|
+
- test/helper.rb
|
72
|
+
- test/test_speedy_c2dm.rb
|