gcm_on_rails 0.1.1
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/.document +5 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +20 -0
- data/README.textile +129 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/lib/gcm_on_rails.rb +3 -0
- data/lib/gcm_on_rails/app/models/gcm/base.rb +5 -0
- data/lib/gcm_on_rails/app/models/gcm/device.rb +29 -0
- data/lib/gcm_on_rails/app/models/gcm/notification.rb +87 -0
- data/lib/gcm_on_rails/gcm_on_rails.rb +88 -0
- data/lib/gcm_on_rails/libs/connection.rb +44 -0
- data/lib/gcm_on_rails/tasks/gcm.rake +9 -0
- data/lib/gcm_on_rails_tasks.rb +3 -0
- data/lib/generators/gcm_migrations_generator.rb +32 -0
- data/lib/generators/templates/gcm_migrations/create_gcm_devices.rb +16 -0
- data/lib/generators/templates/gcm_migrations/create_gcm_notifications.rb +21 -0
- metadata +176 -0
data/.document
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
configatron (2.9.1)
|
5
|
+
yamler (>= 0.1.0)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.8.4)
|
8
|
+
bundler (~> 1.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
rdoc
|
12
|
+
json (1.7.3)
|
13
|
+
rake (0.9.2.2)
|
14
|
+
rdoc (3.12)
|
15
|
+
json (~> 1.4)
|
16
|
+
yamler (0.1.0)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
bundler (~> 1.0.0)
|
23
|
+
configatron
|
24
|
+
jeweler (~> 1.8.4)
|
25
|
+
json
|
26
|
+
rdoc (~> 3.12)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Dennis Ondeng
|
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.textile
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
h1. Gcm on Rails (Google Cloud Messaging for Android on Rails)
|
2
|
+
|
3
|
+
Gcm on Rails (gcm_on_rails) is a Ruby on Rails gem that allows you to easily incorporate Google's 'Google Cloud Messaging for Android' into your Rails application. This gem was derived from c2dm_on_rails (https://github.com/pimeys/c2dm_on_rails) after Google deprecated C2DM on June 27, 2012
|
4
|
+
|
5
|
+
h2. Acknowledgements:
|
6
|
+
|
7
|
+
This gem was derived from Julius de Bruijn's gem c2dm_on_rails which according to him, was originally a rewrite of the gem
|
8
|
+
apn_on_rails written by Mark Bates and before him Fabien Penso and Sam Soffes. Thanks to all the above who were involved in
|
9
|
+
earlier versions or derivatives of the gem. I originally wanted to use the c2dm_on_rails gem for a project at Kopo Kopo, Inc
|
10
|
+
and the rug was pulled from under me when Google deprecated C2DM in favor of GCM (Google Cloud Messaging). I thus decided to
|
11
|
+
create an updated gem. This is also my first rubygem so please feel free to fix or add on anything you may see fit.
|
12
|
+
|
13
|
+
h2. Requirements:
|
14
|
+
|
15
|
+
You will have to sign up to GCM first via the Google APIs Console page (https://code.google.com/apis/console).
|
16
|
+
When you create an new API project, the browser url will change to something like:
|
17
|
+
<pre><code>
|
18
|
+
https://code.google.com/apis/console/#project:4815162342
|
19
|
+
</code></pre>
|
20
|
+
|
21
|
+
The value after #project (4815162342) in this example is the project ID and will be used later on as the GCM sender
|
22
|
+
ID. You will also need to obtain an Api Key and for detailed instructions on how to get one, follow the instructions
|
23
|
+
here:-
|
24
|
+
|
25
|
+
"http://developer.android.com/guide/google/gcm/gs.html":http://developer.android.com/guide/google/gcm/gs.html
|
26
|
+
|
27
|
+
GCM is designed to work on Android version 2.2 or greater, so only Android 2.2> devices are eligible. The device must
|
28
|
+
also have an active Google Account if the Android version is less than version 4.1
|
29
|
+
|
30
|
+
h2. Installing:
|
31
|
+
|
32
|
+
Installation is by simply adding the following to your Gemfile:
|
33
|
+
<pre><code>
|
34
|
+
gem 'gcm_on_rails'
|
35
|
+
</code></pre>
|
36
|
+
|
37
|
+
h2. Setup and Configuration
|
38
|
+
|
39
|
+
The following needs to be added to your Rakefile so that you can use the the Rake tasks that ship with gcm_on_rails:
|
40
|
+
<pre><code>
|
41
|
+
begin
|
42
|
+
require 'gcm_on_rails_tasks'
|
43
|
+
rescue MissingSourceFile => e
|
44
|
+
puts e.message
|
45
|
+
end
|
46
|
+
</code></pre>
|
47
|
+
|
48
|
+
To create the tables needed for Gcm on Rails, run the following task:
|
49
|
+
<pre><code>
|
50
|
+
$ rails generate gcm_migrations
|
51
|
+
</code></pre>
|
52
|
+
|
53
|
+
Gcm on Rails like its predecessor uses the Configatron gem, "http://github.com/markbates/configatron/tree/master":http://github.com/markbates/configatron/tree/master,
|
54
|
+
Some settings need to be loaded for configuration purposes. An initialzer script that can be put in config/initializers/gcm_on_rails.rb
|
55
|
+
will suffice. Below is an example of such a script.
|
56
|
+
<pre><code>
|
57
|
+
configatron.gcm_on_rails.api_url = 'https://android.googleapis.com/gcm/send'
|
58
|
+
configatron.gcm_on_rails.api_key = 'AAAAAAPPPPPPPIIIIIIIKKKKKEEEEYYYYY'
|
59
|
+
configatron.gcm_on_rails.app_name = 'com.yourapppackage.com'
|
60
|
+
configatron.gcm_on_rails.delivery_format = 'json'
|
61
|
+
</code></pre>
|
62
|
+
|
63
|
+
A couple of notes:
|
64
|
+
- The api_key is the api key that you received from Google when signing up for GCM
|
65
|
+
- Note that unlike the old C2dm on Rails, GCM on Rails switches to a simple API key for authentication. ClientLogin or OAuth2 tokens will NOT work.
|
66
|
+
- The app_name is simply the name of the pacakge of your Android app.
|
67
|
+
- GCM on Rails message requests can be either be sent in plain text or JSON format. Specify 'json' fro JSON and 'plain_text' for plain text format.
|
68
|
+
|
69
|
+
That's it, you are now ready to start creating notifications.
|
70
|
+
|
71
|
+
h2. Upgrade Notes:
|
72
|
+
|
73
|
+
When upgrading to a new version of Gcm on Rails, you should alwasy run:
|
74
|
+
<pre><code>
|
75
|
+
$ rails generate gcm_migrations
|
76
|
+
</code></pre>
|
77
|
+
|
78
|
+
That way you are ensured to have the latest version of the database tables needed.
|
79
|
+
|
80
|
+
h2. Example:
|
81
|
+
|
82
|
+
Please note that a more detailed introduction to GCM is located at "http://developer.android.com/guide/google/gcm/index.html":http://developer.android.com/guide/google/gcm/index.html
|
83
|
+
<pre><code>
|
84
|
+
$ rails console
|
85
|
+
>> device = Gcm::Device.create(:registration_id => "XXXXXXXXXXXXXXXXXXXXXX")
|
86
|
+
>> notification = Gcm::Notification.new
|
87
|
+
>> notification.device = device
|
88
|
+
>> notification.collapse_key = "updates_available"
|
89
|
+
>> notification.delay_while_idle = true
|
90
|
+
>> notification.data = {:registration_ids => ["RegistrationID"], :data => {:message_text => "Get on cloud nine"}}
|
91
|
+
>> notification.save
|
92
|
+
</code></pre>
|
93
|
+
|
94
|
+
The following Rake task can then be used to deliver notifications:
|
95
|
+
<pre><code>
|
96
|
+
$ rake gcm:notifications:deliver
|
97
|
+
</code></pre>
|
98
|
+
|
99
|
+
The rake task will look for any unsent notifications in the database. If found, the notifications will then be dispatched
|
100
|
+
for delivery. If no unsent notifications exist, the Rake task simply does nothing. As described by Google, possible errors
|
101
|
+
from the GCM servers are:
|
102
|
+
|
103
|
+
|Code 200| |
|
104
|
+
| |Error: MissingRegistration. Happens when the request did not actually contain a registration_id parameter when in plain text format or registration_ids when in json format.|
|
105
|
+
| |Error: InvalidRegistration. The registration_id passed is not on the GCM servers. The device and all of its notifications will be deleted.|
|
106
|
+
| |Error: MismatchedSenderId. The sender Id that was passed is not one that the application specified as an allowed sender.|
|
107
|
+
| |Error: NotRegistered. An existing registration Id has ceased to be valid. The device and all of tis notifications will be deleted.|
|
108
|
+
| |Error: MessageTooBig. The total payload data that is in the message exceeds 4096 bytes.|
|
109
|
+
|
110
|
+
|Code 401| |
|
111
|
+
| |API Key is Invalid. Check the configuration file|
|
112
|
+
|
113
|
+
|Code 503| |
|
114
|
+
| |Service is unavailable and you should retry later. However, you must honor the 'Retry-After' header if it is included in the response from the GCM server.
|
115
|
+
Exponential backoff should be implemented in your retry mechanism.|
|
116
|
+
|
117
|
+
|Code 500| |
|
118
|
+
| |Internal server error. Retry again while still honoring 'Retry-After' header and using exponential backoff.|
|
119
|
+
|
120
|
+
|
121
|
+
h2. To-Do's:
|
122
|
+
|
123
|
+
- Tests, tests then some more tests. These need to be implemented.
|
124
|
+
- Implement "broadcasting" sending and processing responses to multiple registration id's within one request. Currently only one message to a single registration id is implemented.
|
125
|
+
|
126
|
+
|
127
|
+
Released under the MIT license.
|
128
|
+
Copyright (c) 2012 Dennis Ondeng. See LICENSE.txt for further details.
|
129
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "gcm_on_rails"
|
18
|
+
gem.homepage = "http://github.com/dondeng/gcm_on_rails"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Google Cloud Messaging for Android on Rails}
|
21
|
+
gem.description = %Q{gcm_on_rails is a Ruby on Rails gem that allows you to easily incorporate Google's
|
22
|
+
'Google Cloud Messaging for Android' into your Rails application. This gem was derived from
|
23
|
+
c2dm_on_rails (https://github.com/pimeys/c2dm_on_rails) after Google deprecated C2DM on June 27, 2012}
|
24
|
+
gem.email = "dondeng2@gmail.com"
|
25
|
+
gem.authors = ["Dennis Ondeng"]
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
|
31
|
+
require 'rdoc/task'
|
32
|
+
Rake::RDocTask.new do |rdoc|
|
33
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
34
|
+
|
35
|
+
rdoc.rdoc_dir = 'rdoc'
|
36
|
+
rdoc.title = "gcm_on_rails #{version}"
|
37
|
+
rdoc.rdoc_files.include('README*')
|
38
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/lib/gcm_on_rails.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Represents an Android phone.
|
2
|
+
# An Gcm::Device can have many Gcm::Notification.
|
3
|
+
#
|
4
|
+
# In order for the Gcm::Feedback system to work properly you *MUST*
|
5
|
+
# touch the <tt>last_registered_at</tt> column every time someone opens
|
6
|
+
# your application. If you do not, then it is possible, and probably likely,
|
7
|
+
# that their device will be removed and will no longer receive notifications.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# Device.create(:registration_id => 'FOOBAR')
|
11
|
+
class Gcm::Device < Gcm::Base
|
12
|
+
self.table_name = "gcm_devices"
|
13
|
+
|
14
|
+
has_many :notifications, :class_name => 'Gcm::Notification', :dependent => :destroy
|
15
|
+
validates_presence_of :registration_id
|
16
|
+
validates_uniqueness_of :registration_id
|
17
|
+
|
18
|
+
before_save :set_last_registered_at
|
19
|
+
|
20
|
+
# The <tt>feedback_at</tt> accessor is set when the
|
21
|
+
# device is marked as potentially disconnected from your
|
22
|
+
# application by Google.
|
23
|
+
attr_accessor :feedback_at
|
24
|
+
|
25
|
+
private
|
26
|
+
def set_last_registered_at
|
27
|
+
self.last_registered_at = Time.now if self.last_registered_at.nil?
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class Gcm::Notification < Gcm::Base
|
2
|
+
self.table_name = "gcm_notifications"
|
3
|
+
|
4
|
+
include ::ActionView::Helpers::TextHelper
|
5
|
+
extend ::ActionView::Helpers::TextHelper
|
6
|
+
serialize :data
|
7
|
+
|
8
|
+
belongs_to :device, :class_name => 'Gcm::Device'
|
9
|
+
validates_presence_of :collapse_key if :time_to_live?
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Opens a connection to the Google GCM server and attempts to batch deliver
|
13
|
+
# an Array of notifications.
|
14
|
+
#
|
15
|
+
# This method expects an Array of Gcm::Notifications. If no parameter is passed
|
16
|
+
# in then it will use the following:
|
17
|
+
# Gcm::Notification.all(:conditions => {:sent_at => nil})
|
18
|
+
#
|
19
|
+
# As each Gcm::Notification is sent the <tt>sent_at</tt> column will be timestamped,
|
20
|
+
# so as to not be sent again.
|
21
|
+
#
|
22
|
+
# This can be run from the following Rake task:
|
23
|
+
# $ rake gcm:notifications:deliver
|
24
|
+
def send_notifications(notifications = Gcm::Notification.all(:conditions => {:sent_at => nil}, :joins => :device, :readonly => false))
|
25
|
+
|
26
|
+
if configatron.gcm_on_rails.delivery_format and configatron.gcm_on_rails.delivery_format == 'plain_text'
|
27
|
+
format = "plain_text"
|
28
|
+
else
|
29
|
+
format = "json"
|
30
|
+
end
|
31
|
+
|
32
|
+
unless notifications.nil? || notifications.empty?
|
33
|
+
api_key = Gcm::Connection.open
|
34
|
+
if api_key
|
35
|
+
notifications.each do |notification|
|
36
|
+
#puts "sending notification #{notification.id} to device #{notification.device.registration_id}"
|
37
|
+
response = Gcm::Connection.send_notification(notification, api_key, format)
|
38
|
+
#puts "response: #{response[:code]}; #{response.inspect}"
|
39
|
+
if response[:code] == 200
|
40
|
+
if format == "json"
|
41
|
+
error = ""
|
42
|
+
message_data = JSON.parse response[:message]
|
43
|
+
success = message_data['success']
|
44
|
+
error = message_data['results'][0]['error'] if success == 0
|
45
|
+
else #format is plain text
|
46
|
+
message_data = response[:message]
|
47
|
+
error = response[:message].split('=')[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
case error
|
52
|
+
when "MissingRegistration"
|
53
|
+
ex = Gcm::Errors::MissingRegistration.new(response[:message])
|
54
|
+
logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
55
|
+
notification.device.destroy
|
56
|
+
when "InvalidRegistration"
|
57
|
+
ex = Gcm::Errors::InvalidRegistration.new(response[:message])
|
58
|
+
logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
59
|
+
notification.device.destroy
|
60
|
+
when "MismatchedSenderId"
|
61
|
+
ex = Gcm::Errors::MismatchSenderId.new(response[:message])
|
62
|
+
logger.warn(ex.message)
|
63
|
+
when "NotRegistered"
|
64
|
+
ex = Gcm::Errors::NotRegistered.new(response[:message])
|
65
|
+
logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
66
|
+
notification.device.destroy
|
67
|
+
when "MessageTooBig"
|
68
|
+
ex = Gcm::Errors::MessageTooBig.new(response[:message])
|
69
|
+
logger.warn(ex.message)
|
70
|
+
else
|
71
|
+
notification.sent_at = Time.now
|
72
|
+
notification.save!
|
73
|
+
end
|
74
|
+
elsif response[:code] == 401
|
75
|
+
raise Gcm::Errors::InvalidAuthToken.new(message_data)
|
76
|
+
elsif response[:code] == 503
|
77
|
+
raise Gcm::Errors::ServiceUnavailable.new(message_data)
|
78
|
+
elsif response[:code] == 500
|
79
|
+
raise Gcm::Errors::InternalServerError.new(message_data)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'configatron'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Gcm
|
5
|
+
module Errors
|
6
|
+
|
7
|
+
# Missing registration_id.
|
8
|
+
class MissingRegistration < StandardError
|
9
|
+
def initialize(message) # :nodoc:
|
10
|
+
super("Missing registration_id: '#{message}'")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Invalid registration_id. Check the formatting of the registration ID that is passed to the server. Make sure
|
15
|
+
# it matches the the registration ID the phone receives in the com.google.android.c2dm.intent.REGISTRATION intent
|
16
|
+
# and that it is not being truncated or additional characters being appended
|
17
|
+
class InvalidRegistration < StandardError
|
18
|
+
def initialize(message) # :nodoc:
|
19
|
+
super("Invalid registration_id: '#{message}'")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# A registration ID is tied to a certain group of senders. When an application registers for GCM usage, it must
|
24
|
+
# specify which senders are allowed to send messages.
|
25
|
+
class MismatchSenderId < StandardError
|
26
|
+
def initialize(message) # :nodoc
|
27
|
+
super("Mismatched Sender Id: '#{message}'")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# From Google:-
|
32
|
+
# An existing registration ID may cease to be valid in a number of scenarios, including:
|
33
|
+
# - If the application manually unregisters
|
34
|
+
# - If the application is automatically unregistered which can (but not guaranteed) to happen if the user
|
35
|
+
# uninstalls the application
|
36
|
+
# - If the registration ID expires. Google might decide to refresh registration IDs
|
37
|
+
#
|
38
|
+
# For all cases above, it is recommended that this registration ID is removed from the 3rd party server
|
39
|
+
class NotRegistered < StandardError
|
40
|
+
def initialize(message) # :nodoc
|
41
|
+
super("The registration_id is no longer valid: '#{message}'")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# The payload of the message is too big, the limit is currently 4096
|
46
|
+
# bytes. Reduce the size of the message.
|
47
|
+
class MessageTooBig < StandardError
|
48
|
+
def initialize(message) # :nodoc:
|
49
|
+
super("The maximum size allowed for a notification payload is 4096 bytes: '#{message}'")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# ClientLogin AUTH_TOKEN is invalid. Check the config
|
54
|
+
class InvalidAuthToken < StandardError
|
55
|
+
def initialize(message)
|
56
|
+
super("Invalid auth token: '#{message}'")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Indicates that server is temporarily unavailable (i.e because of timeouts, etc.)
|
61
|
+
# Sender must retry later, honoring any Retry-After header included in the response.
|
62
|
+
# Application servers must implement exponential back-off
|
63
|
+
class ServiceUnavailable < StandardError
|
64
|
+
def initialize(message)
|
65
|
+
super("Service is currently unavailable. Try again later: '#{message}'")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Indicates an internal server error with the GCM server
|
70
|
+
class InternalServerError < StandardError
|
71
|
+
def initialize(message)
|
72
|
+
super("The was an internal error in the GCM server while trying to process the request: '#{message}'")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'app', 'models', 'gcm', '*.rb')).sort.each do |f|
|
78
|
+
require f
|
79
|
+
end
|
80
|
+
|
81
|
+
%w{ models controllers helpers }.each do |dir|
|
82
|
+
path = File.join(File.dirname(__FILE__), 'app', dir)
|
83
|
+
$LOAD_PATH << path
|
84
|
+
# puts "Adding #{path}"
|
85
|
+
ActiveSupport::Dependencies.autoload_paths << path
|
86
|
+
ActiveSupport::Dependencies.autoload_once_paths.delete(path)
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Gcm
|
5
|
+
module Connection
|
6
|
+
class << self
|
7
|
+
def send_notification(notification, api_key, format)
|
8
|
+
|
9
|
+
if format == 'json'
|
10
|
+
headers = {"Content-Type" => "application/json",
|
11
|
+
"Authorization" => "key=#{api_key}"}
|
12
|
+
|
13
|
+
data = notification.data.merge({:collapse_key => notification.collapse_key}) unless notification.collapse_key.nil?
|
14
|
+
data = data.merge({:delay_while_idle => notification.delay_while_idle}) unless notification.delay_while_idle.nil?
|
15
|
+
data = data.merge({:time_to_live => notification.time_to_live}) unless notification.time_to_live.nil?
|
16
|
+
data = data.to_json
|
17
|
+
else #plain text format
|
18
|
+
headers = {"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8",
|
19
|
+
"Authorization" => "key=#{api_key}"}
|
20
|
+
|
21
|
+
post_data = notification.data[:data].map{|k, v| "&data.#{k}=#{URI.escape(v)}".reduce{|k, v| k + v}}[0]
|
22
|
+
extra_data = "registration_id=#{notification.data[:registration_ids][0]}"
|
23
|
+
extra_data = "#{extra_data}&collapse_key=#{notification.collapse_key}" unless notification.collapse_key.nil?
|
24
|
+
extra_data = "#{extra_data}&delay_while_idle=1" if notification.delay_while_idle
|
25
|
+
data = "#{extra_data}#{post_data}"
|
26
|
+
end
|
27
|
+
|
28
|
+
url_string = configatron.gcm_on_rails.api_url
|
29
|
+
url = URI.parse url_string
|
30
|
+
http = Net::HTTP.new(url.host, url.port)
|
31
|
+
http.use_ssl = true
|
32
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
33
|
+
|
34
|
+
resp, dat = http.post(url.path, data, headers)
|
35
|
+
|
36
|
+
return {:code => resp.code.to_i, :message => dat }
|
37
|
+
end
|
38
|
+
|
39
|
+
def open
|
40
|
+
configatron.gcm_on_rails.api_key
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
# Generates the migrations necessary for Gcm on Rails.
|
3
|
+
# This should be run upon install and upgrade of the
|
4
|
+
# Gcm on Rails gem.
|
5
|
+
#
|
6
|
+
# $ ruby script/generate gcm_migrations
|
7
|
+
class GcmMigrationsGenerator < Rails::Generators::Base
|
8
|
+
include Rails::Generators::Migration
|
9
|
+
extend ActiveRecord::Generators::Migration
|
10
|
+
|
11
|
+
# Set the current directory as base for the inherited generators.
|
12
|
+
def self.base_root
|
13
|
+
File.dirname(__FILE__)
|
14
|
+
end
|
15
|
+
|
16
|
+
source_root File.expand_path('../templates/gcm_migrations', __FILE__)
|
17
|
+
|
18
|
+
def create_migrations
|
19
|
+
templates = {
|
20
|
+
'create_gcm_devices.rb' => 'db/migrate/create_gcm_devices.rb',
|
21
|
+
'create_gcm_notifications.rb' => 'db/migrate/create_gcm_notifications.rb'
|
22
|
+
}
|
23
|
+
|
24
|
+
templates.each_pair do |name, path|
|
25
|
+
begin
|
26
|
+
migration_template(name, path)
|
27
|
+
rescue => err
|
28
|
+
puts "WARNING: #{err.message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end # GcmMigrationsGenerator
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateGcmDevices < ActiveRecord::Migration # :nodoc:
|
2
|
+
def self.up
|
3
|
+
create_table :gcm_devices do |t|
|
4
|
+
t.string :registration_id, :size => 120, :null => false
|
5
|
+
t.datetime :last_registered_at
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :gcm_devices, :registration_id, :unique => true
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :gcm_devices
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateGcmNotifications < ActiveRecord::Migration # :nodoc:
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
|
5
|
+
create_table :gcm_notifications do |t|
|
6
|
+
t.integer :device_id, :null => false
|
7
|
+
t.string :collapse_key
|
8
|
+
t.text :data
|
9
|
+
t.boolean :delay_while_idle
|
10
|
+
t.datetime :sent_at
|
11
|
+
t.integer :time_to_live
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :gcm_notifications, :device_id
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :gcm_notifications
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gcm_on_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Dennis Ondeng
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-07-10 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 63
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 8
|
30
|
+
- 4
|
31
|
+
version: 1.8.4
|
32
|
+
version_requirements: *id001
|
33
|
+
name: jeweler
|
34
|
+
prerelease: false
|
35
|
+
type: :runtime
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
version_requirements: *id002
|
47
|
+
name: configatron
|
48
|
+
prerelease: false
|
49
|
+
type: :runtime
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
version_requirements: *id003
|
61
|
+
name: json
|
62
|
+
prerelease: false
|
63
|
+
type: :runtime
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 31
|
71
|
+
segments:
|
72
|
+
- 3
|
73
|
+
- 12
|
74
|
+
version: "3.12"
|
75
|
+
version_requirements: *id004
|
76
|
+
name: rdoc
|
77
|
+
prerelease: false
|
78
|
+
type: :development
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 23
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 0
|
89
|
+
- 0
|
90
|
+
version: 1.0.0
|
91
|
+
version_requirements: *id005
|
92
|
+
name: bundler
|
93
|
+
prerelease: false
|
94
|
+
type: :development
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 63
|
102
|
+
segments:
|
103
|
+
- 1
|
104
|
+
- 8
|
105
|
+
- 4
|
106
|
+
version: 1.8.4
|
107
|
+
version_requirements: *id006
|
108
|
+
name: jeweler
|
109
|
+
prerelease: false
|
110
|
+
type: :development
|
111
|
+
description: |-
|
112
|
+
gcm_on_rails is a Ruby on Rails gem that allows you to easily incorporate Google's
|
113
|
+
'Google Cloud Messaging for Android' into your Rails application. This gem was derived from
|
114
|
+
c2dm_on_rails (https://github.com/pimeys/c2dm_on_rails) after Google deprecated C2DM on June 27, 2012
|
115
|
+
email: dondeng2@gmail.com
|
116
|
+
executables: []
|
117
|
+
|
118
|
+
extensions: []
|
119
|
+
|
120
|
+
extra_rdoc_files:
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.textile
|
123
|
+
files:
|
124
|
+
- .document
|
125
|
+
- Gemfile
|
126
|
+
- Gemfile.lock
|
127
|
+
- LICENSE.txt
|
128
|
+
- README.textile
|
129
|
+
- Rakefile
|
130
|
+
- VERSION
|
131
|
+
- lib/gcm_on_rails.rb
|
132
|
+
- lib/gcm_on_rails/app/models/gcm/base.rb
|
133
|
+
- lib/gcm_on_rails/app/models/gcm/device.rb
|
134
|
+
- lib/gcm_on_rails/app/models/gcm/notification.rb
|
135
|
+
- lib/gcm_on_rails/gcm_on_rails.rb
|
136
|
+
- lib/gcm_on_rails/libs/connection.rb
|
137
|
+
- lib/gcm_on_rails/tasks/gcm.rake
|
138
|
+
- lib/gcm_on_rails_tasks.rb
|
139
|
+
- lib/generators/gcm_migrations_generator.rb
|
140
|
+
- lib/generators/templates/gcm_migrations/create_gcm_devices.rb
|
141
|
+
- lib/generators/templates/gcm_migrations/create_gcm_notifications.rb
|
142
|
+
homepage: http://github.com/dondeng/gcm_on_rails
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
hash: 3
|
165
|
+
segments:
|
166
|
+
- 0
|
167
|
+
version: "0"
|
168
|
+
requirements: []
|
169
|
+
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 1.8.10
|
172
|
+
signing_key:
|
173
|
+
specification_version: 3
|
174
|
+
summary: Google Cloud Messaging for Android on Rails
|
175
|
+
test_files: []
|
176
|
+
|