c2dm 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/.gitignore +3 -8
  2. data/Gemfile +0 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.markdown +29 -34
  5. data/c2dm.gemspec +6 -3
  6. data/lib/c2dm.rb +60 -75
  7. metadata +10 -5
data/.gitignore CHANGED
@@ -1,9 +1,3 @@
1
- <<<<<<< HEAD
2
- *.gem
3
- .bundle
4
- Gemfile.lock
5
- pkg/*
6
- =======
7
1
  # rcov generated
8
2
  coverage
9
3
 
@@ -33,7 +27,7 @@ pkg
33
27
  #
34
28
  # For MacOS:
35
29
  #
36
- #.DS_Store
30
+ .DS_Store
37
31
  #
38
32
  # For TextMate
39
33
  #*.tmproj
@@ -51,4 +45,5 @@ bin
51
45
  cache
52
46
  gems
53
47
  specifications
54
- >>>>>>> a574da36fd93ce0acc0703513e6c77a5b586b502
48
+ Gemfile.lock
49
+ .rvmrc
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in c2dm.gemspec
4
3
  gemspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Amro Mousa
1
+ Copyright (c) 2010-2012 Amro Mousa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,6 +1,6 @@
1
1
  # c2dm
2
2
 
3
- c2dm sends push notifications to Android devices via google [c2dm](http://code.google.com/android/c2dm/index.html).
3
+ c2dm sends push notifications to Android devices via c2dm sends push notifications to Android devices via [Google Cloud Messaging (GCM)](http://code.google.com/android/c2dm/index.html).
4
4
 
5
5
  ##Installation
6
6
 
@@ -8,59 +8,54 @@ c2dm sends push notifications to Android devices via google [c2dm](http://code.g
8
8
 
9
9
  ##Requirements
10
10
 
11
- An Android device running 2.2 or newer, its registration token, and a google account registered for c2dm.
11
+ An Android device running 2.2 or newer, its registration token, and a [GCM api key](https://code.google.com/apis/console).
12
12
 
13
13
  ##Usage
14
14
 
15
- *Important*: Version 0.2.0+ decouples auth from sending so the API changed. Please update your code.
16
-
17
15
  There are two ways to use c2dm.
18
16
 
19
- Sending many notifications:
17
+ Sending many individual notifications using a static method:
20
18
 
21
19
  notifications = [
22
20
  {
23
- :registration_id => "...",
24
- :data => {
25
- :some_message => "Some payload"
26
- :another_message => 10
21
+ registration_id: "...1",
22
+ data: {
23
+ some_message: "Some payload",
24
+ a_value: 10
27
25
  },
28
- :collapse_key => "foobar" #optional
26
+ collapse_key: "foobar" #optional
27
+ },
28
+ {
29
+ registration_id: "...2",
30
+ data: {
31
+ some_message: "Some other payload",
32
+ a_value: 20
33
+ }
29
34
  }
30
35
  ]
31
36
 
32
- C2DM.authenticate!("your@googleuser.com", "somepassword", "YourCo-App-1.0.0")
37
+ C2DM.api_key = "YourGCMApiKey" # This initializes all future instances of C2DM with "YourGCMApiKey"
33
38
  C2DM.send_notifications(notifications)
34
39
 
35
- ...or one at a time:
36
-
37
- C2DM.authenticate!("your@googleuser.com", "somepassword", "YourCo-App-1.0.0")
38
- c2dm = C2DM.new
39
-
40
- notification = {
41
- :registration_id => "...",
42
- :data => {
43
- :some_message => "Some payload",
44
- :another_message => 10
45
- },
46
- :collapse_key => "foobar" #optional
47
- }
40
+ Sending this way will not raise an error but `send_notifications` will return an array of
41
+ hashes including the `registration_id` and the `response`. If GCM returns an error while C2DM
42
+ is sending one of the notifications, the `response` in the hash of the appropriate notification
43
+ will be an object of type `C2DM::GCMError`.
48
44
 
49
- c2dm.send_notification(notification)
45
+ ...or one at a time by creating an instance:
50
46
 
51
- Note that calling *authenticate!* will authenticate all new instances of C2DM. You can override this by passing in your own auth_token:
47
+ c2dm = C2DM.new("YourGCMApiKey")
48
+ data = {some_message: "Some payload", a_value: 10}
49
+ collapse_key = "optional_collapse_key"
50
+ c2dm.send_notification("aRegistrationId", data, collapse_key)
52
51
 
53
- c2dm = C2DM.new(auth_token)
52
+ Sending using an instance of C2DM will raise a `C2DM::GCMError` error when sending fails.
54
53
 
55
54
  ##Copyrights
56
55
 
57
- * Copyright (c) 2010-2012 Amro Mousa, Shawn Veader. See LICENSE.txt for details.
56
+ * Copyright (c) 2010-2012 Amro Mousa. See LICENSE.txt for details.
58
57
 
59
58
  ##Thanks
60
-
59
+ * [Shawn Veader](https://github.com/veader)
61
60
  * [Paul Chun](https://github.com/sixofhearts)
62
- * [gowalla](https://github.com/gowalla)
63
-
64
- ##Other stuff
65
-
66
- You might want to checkout GroupMe's fork of this gem as well.
61
+ * [gowalla](https://github.com/gowalla)
@@ -3,14 +3,17 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "c2dm"
6
- s.version = "0.2.2"
6
+ s.version = "0.3.0"
7
7
  s.authors = ["Amro Mousa"]
8
8
  s.email = ["amromousa@gmail.com"]
9
- s.homepage = ""
9
+ s.homepage = "http://github.com/amro/c2dm"
10
10
  s.summary = %q{sends push notifications to Android devices}
11
- s.description = %q{c2dm sends push notifications to Android devices via google c2dm}
11
+ s.description = %q{c2dm sends push notifications to Android devices via Google Cloud Messaging (GCM)}
12
12
  s.license = "MIT"
13
13
 
14
+ s.post_install_message = "Warning: C2DM versions 0.3.0 and newer include breaking changes like raising exceptions by default\n" +
15
+ "and a slightly different API! Please read more at http://github.com/amro/c2dm before upgrading from 0.2.x!"
16
+
14
17
  s.rubyforge_project = "c2dm"
15
18
 
16
19
  s.files = `git ls-files`.split("\n")
@@ -1,98 +1,83 @@
1
1
  require 'httparty'
2
- require 'cgi'
2
+ require 'json'
3
3
 
4
4
  class C2DM
5
5
  include HTTParty
6
- default_timeout 30
6
+ format :plain
7
+ default_timeout 10
7
8
 
8
- attr_accessor :timeout, :auth_token
9
+ attr_accessor :timeout, :api_key
9
10
 
10
- AUTH_URL = 'https://www.google.com/accounts/ClientLogin'
11
- PUSH_URL = 'https://android.apis.google.com/c2dm/send'
11
+ GCMError = Class.new(StandardError)
12
+ API_ENDPOINT = 'https://android.googleapis.com/gcm/send'
12
13
 
13
14
  class << self
14
- attr_accessor :auth_token
15
-
16
- def authenticate!(username, password, source = nil)
17
- auth_options = {
18
- 'accountType' => 'HOSTED_OR_GOOGLE',
19
- 'service' => 'ac2dm',
20
- 'Email' => username,
21
- 'Passwd' => password,
22
- 'source' => source || 'MyCompany-MyAppName-1.0'
23
- }
24
- post_body = build_post_body(auth_options)
25
-
26
- params = {
27
- :body => post_body,
28
- :headers => {
29
- 'Content-type' => 'application/x-www-form-urlencoded',
30
- 'Content-length' => post_body.length.to_s
31
- }
32
- }
33
-
34
- response = self.post(AUTH_URL, params)
35
-
36
- # check for authentication failures
37
- raise response.parsed_response if response['Error=']
38
-
39
- @auth_token = response.body.split("\n")[2].gsub('Auth=', '')
40
- end
15
+ attr_accessor :api_key
41
16
 
17
+ # send_notifications([
18
+ # {registration_id: "aRegId1", data: {some_message: "hello", a_value: 5}, collapse_key: "optional_collapse_key"},
19
+ # {registration_id: "aRegId2", data: {some_message: "weeee", a_value: 1}},
20
+ # ...
21
+ # ])
42
22
  def send_notifications(notifications = [])
43
- c2dm = C2DM.new(@auth_token)
23
+ c2dm = C2DM.new(@api_key)
44
24
  notifications.collect do |notification|
25
+ response = nil
26
+
27
+ begin
28
+ response = c2dm.send_notification(notification[:registration_id], notification[:data], notification[:collapse_key])
29
+ rescue GCMError => e
30
+ response = e
31
+ end
32
+
45
33
  {
46
- :body => c2dm.send_notification(notification),
47
- :registration_id => notification[:registration_id]
34
+ "registration_id" => notification[:registration_id],
35
+ "response" => response
48
36
  }
49
37
  end
50
38
  end
51
-
52
- def build_post_body(options={})
53
- post_body = []
54
-
55
- # data attributes need a key in the form of "data.key"...
56
- data_attributes = options.delete(:data)
57
- data_attributes.each_pair do |k,v|
58
- post_body << "data.#{k}=#{CGI::escape(v.to_s)}"
59
- end if data_attributes
60
-
61
- options.each_pair do |k,v|
62
- post_body << "#{k}=#{CGI::escape(v.to_s)}"
63
- end
64
-
65
- post_body.join('&')
66
- end
67
-
68
39
  end
69
40
 
70
- def initialize(auth_token = nil)
71
- @auth_token = auth_token || self.class.auth_token
41
+ def initialize(api_key = nil)
42
+ @api_key = api_key || self.class.api_key
72
43
  end
73
44
 
74
- # {
75
- # :registration_id => "...",
76
- # :data => {
77
- # :some_message => "Hi!",
78
- # :another_message => 7
79
- # }
80
- # :collapse_key => "optional collapse_key string"
81
- # }
82
- def send_notification(options)
83
- options[:collapse_key] ||= 'foo'
84
- post_body = self.class.build_post_body(options)
85
-
86
- params = {
87
- :body => post_body,
88
- :headers => {
89
- 'Authorization' => "GoogleLogin auth=#{@auth_token}",
90
- 'Content-type' => 'application/x-www-form-urlencoded',
91
- 'Content-length' => "#{post_body.length}"
92
- }
45
+ # send_notification("aRegId...", {some_message: "hello", a_value: 5}, "optional collapse_key")
46
+ def send_notification(registration_id, data, collapse_key = nil)
47
+ raise GCMError.new("registration_id must be a String") unless registration_id.is_a?(String)
48
+
49
+ payload = {
50
+ registration_ids: [registration_id],
51
+ data: data,
52
+ collapse_key: collapse_key
93
53
  }
94
54
 
95
- self.class.post(PUSH_URL, params)
55
+ parse_response(send(payload))
56
+ end
57
+
58
+ private
59
+ def send(payload)
60
+ self.class.post(API_ENDPOINT, body: payload.to_json, headers: request_headers)
61
+ end
62
+
63
+ def request_headers
64
+ {
65
+ "Authorization" => "key=#{@api_key}",
66
+ "Content-Type" => "application/json"
67
+ }
68
+ end
69
+
70
+ def parse_response(response)
71
+ begin
72
+ parsed_response = JSON.parse(response.body)
73
+
74
+ if (parsed_response["results"].first["error"])
75
+ raise GCMError.new(parsed_response["results"].first["error"])
76
+ end
77
+
78
+ parsed_response
79
+ rescue JSON::ParserError
80
+ raise GCMError.new(response.body)
81
+ end
96
82
  end
97
-
98
83
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c2dm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-24 00:00:00.000000000 Z
12
+ date: 2013-01-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -43,7 +43,8 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
- description: c2dm sends push notifications to Android devices via google c2dm
46
+ description: c2dm sends push notifications to Android devices via Google Cloud Messaging
47
+ (GCM)
47
48
  email:
48
49
  - amromousa@gmail.com
49
50
  executables: []
@@ -58,10 +59,14 @@ files:
58
59
  - Rakefile
59
60
  - c2dm.gemspec
60
61
  - lib/c2dm.rb
61
- homepage: ''
62
+ homepage: http://github.com/amro/c2dm
62
63
  licenses:
63
64
  - MIT
64
- post_install_message:
65
+ post_install_message: ! 'Warning: C2DM versions 0.3.0 and newer include breaking changes
66
+ like raising exceptions by default
67
+
68
+ and a slightly different API! Please read more at http://github.com/amro/c2dm before
69
+ upgrading from 0.2.x!'
65
70
  rdoc_options: []
66
71
  require_paths:
67
72
  - lib