apple_push_notification 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/LICENSE +22 -0
- data/Rakefile +38 -0
- data/Readme.markdown +62 -0
- data/VERSION +1 -0
- data/init.rb +0 -0
- data/install.rb +0 -0
- data/lib/app/models/apple_push_notification.rb +101 -0
- data/lib/apple_push_notification.rb +9 -0
- data/lib/db/migrate/20090406132059_create_apple_push_notifications.rb +18 -0
- data/tasks/apple_push_notification_tasks.rake +10 -0
- data/test/apple_push_notification_test.rb +8 -0
- data/test/test_helper.rb +3 -0
- data/uninstall.rb +1 -0
- metadata +70 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.DS_Store
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009 Fabien Penso, Sam Soffes
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the apple_push_notification plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the apple_push_notification plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'ApplePushNotification'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'jeweler'
|
27
|
+
Jeweler::Tasks.new do |gemspec|
|
28
|
+
gemspec.name = "apple_push_notification"
|
29
|
+
gemspec.summary = "Rails plugin for Apple Push Notifications"
|
30
|
+
gemspec.description = "Rails plugin for Apple Push Notifications"
|
31
|
+
gemspec.email = "sam@samsoff.es"
|
32
|
+
gemspec.homepage = "http://github.com/samsoffes/apple_push_notification"
|
33
|
+
gemspec.authors = ["Sam Soffes", "Fabien Penso"]
|
34
|
+
end
|
35
|
+
Jeweler::GemcutterTasks.new
|
36
|
+
rescue LoadError
|
37
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
|
38
|
+
end
|
data/Readme.markdown
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Apple Push Notification
|
2
|
+
|
3
|
+
This plugin helps you use the Apple Push Notification system.
|
4
|
+
|
5
|
+
## Converting Your Certificate
|
6
|
+
|
7
|
+
Once you have the certificate from Apple for your application, export your key
|
8
|
+
and the apple certificate as p12 files. Here's how:
|
9
|
+
|
10
|
+
1. Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
|
11
|
+
2. Right click and choose `Export 2 items...`.
|
12
|
+
3. Choose the p12 format from the drop down and name it `cert.p12`.
|
13
|
+
|
14
|
+
Now covert the p12 file to a pem file:
|
15
|
+
|
16
|
+
$ openssl pkcs12 -in cert.p12 -out apn_development.pem -nodes -clcerts && rm -f cert.p12
|
17
|
+
|
18
|
+
Put `apn_development.pem` in `config/certs` in your rails app. For production, name your certificate `apn_production.pem` and put it in the same directory. See the environment section for more about environments.
|
19
|
+
|
20
|
+
## Installing
|
21
|
+
|
22
|
+
Install as a gem:
|
23
|
+
|
24
|
+
# Add to config/environment.rb:
|
25
|
+
config.gem "apple_push_notification", :source => "http://gemcutter.org/"
|
26
|
+
|
27
|
+
# At command prompt:
|
28
|
+
$ sudo rake gems:install
|
29
|
+
|
30
|
+
or as a plugin:
|
31
|
+
|
32
|
+
$ script/plugin install git://github.com/samsoffes/apple_push_notification.git
|
33
|
+
|
34
|
+
Once you have installed apple\_push\_notification, run the following command:
|
35
|
+
|
36
|
+
$ rake apn:migrate
|
37
|
+
|
38
|
+
## Environment
|
39
|
+
|
40
|
+
By default, the development environment will always be used. This makes it easy to test your app in production before your iPhone application is approved and your production certificate is active. You can easily override this by adding this line in an initializer or environment file.
|
41
|
+
|
42
|
+
ApplePushNotification.enviroment = Rails.env.to_sym
|
43
|
+
|
44
|
+
You can also simply set `ApplePushNotification.enviroment` to `:development` or `:production`. Setting the `ApplePushNotification.enviroment` chooses the appropriate certificate in your `certs` folder and Apple push notification server.
|
45
|
+
|
46
|
+
## Example
|
47
|
+
|
48
|
+
$ ./script/console
|
49
|
+
>> a = ApplePushNotification.new
|
50
|
+
>> a.device_token = "XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX"
|
51
|
+
>> a.badge = 5
|
52
|
+
>> a.sound = true
|
53
|
+
>> a.alert = "Hello world"
|
54
|
+
>> a.send_notification
|
55
|
+
=> nil
|
56
|
+
|
57
|
+
### Notes
|
58
|
+
|
59
|
+
* The spaces in `device_token` are optional.
|
60
|
+
* The `sound` can be the filename (i.e. `explosion.aiff`) or `true` which will play the default notification sound.
|
61
|
+
|
62
|
+
Copyright (c) 2009 Fabien Penso. Released under the MIT license. Modified by [Sam Soffes](http://samsoff.es).
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
File without changes
|
data/install.rb
ADDED
File without changes
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
class ApplePushNotification < ActiveRecord::Base
|
5
|
+
|
6
|
+
attr_accessor :paylod, :sound, :badge, :alert
|
7
|
+
attr_accessible :device_token
|
8
|
+
|
9
|
+
PORT = 2195
|
10
|
+
|
11
|
+
cattr_accessor :enviroment
|
12
|
+
self.enviroment = :development
|
13
|
+
|
14
|
+
validates_uniqueness_of :device_token
|
15
|
+
|
16
|
+
def send_notification
|
17
|
+
raise "Missing cert: #{_path}" unless @@cert
|
18
|
+
|
19
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
20
|
+
ctx.key = OpenSSL::PKey::RSA.new(@@cert)
|
21
|
+
ctx.cert = OpenSSL::X509::Certificate.new(@@cert)
|
22
|
+
|
23
|
+
s = TCPSocket.new(@@host, PORT)
|
24
|
+
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
|
25
|
+
ssl.sync = true
|
26
|
+
ssl.connect
|
27
|
+
|
28
|
+
ssl.write(self.apn_message_for_sending)
|
29
|
+
|
30
|
+
ssl.close
|
31
|
+
s.close
|
32
|
+
|
33
|
+
rescue SocketError => error
|
34
|
+
raise "Error while sending notifications: #{error}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.enviroment= enviroment
|
38
|
+
@@enviroment = enviroment.to_sym
|
39
|
+
@@host = self.production? ? "gateway.push.apple.com" : "gateway.sandbox.push.apple.com"
|
40
|
+
cert = self.production? ? "apn_production.pem" : "apn_development.pem"
|
41
|
+
path = File.join(File.expand_path(RAILS_ROOT), "config", "certs", cert)
|
42
|
+
@@cert = File.exists?(path) ? File.read(path) : nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.development?
|
46
|
+
@@enviroment != :production
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.production?
|
50
|
+
@@enviroment == :production
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.send_notifications(notifications)
|
54
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
55
|
+
ctx.key = OpenSSL::PKey::RSA.new(@@cert)
|
56
|
+
ctx.cert = OpenSSL::X509::Certificate.new(@@cert)
|
57
|
+
|
58
|
+
s = TCPSocket.new(@@host, PORT)
|
59
|
+
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
|
60
|
+
ssl.sync = true
|
61
|
+
ssl.connect
|
62
|
+
|
63
|
+
for notif in notifications do
|
64
|
+
ssl.write(notif.apn_message_for_sending)
|
65
|
+
end
|
66
|
+
|
67
|
+
ssl.close
|
68
|
+
s.close
|
69
|
+
rescue SocketError => error
|
70
|
+
raise "Error while sending notifications: #{error}"
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
|
75
|
+
def to_apple_json
|
76
|
+
json = self.apple_array.to_json
|
77
|
+
logger.debug "Sending #{json}"
|
78
|
+
json
|
79
|
+
end
|
80
|
+
|
81
|
+
def apn_message_for_sending
|
82
|
+
json = self.to_apple_json
|
83
|
+
message = "\0\0 #{self.device_token_hexa}\0#{json.length.chr}#{json}"
|
84
|
+
raise "The maximum size allowed for a notification payload is 256 bytes." if message.size.to_i > 256
|
85
|
+
message
|
86
|
+
end
|
87
|
+
|
88
|
+
def device_token_hexa
|
89
|
+
[self.device_token.delete(' ')].pack('H*')
|
90
|
+
end
|
91
|
+
|
92
|
+
def apple_array
|
93
|
+
result = {}
|
94
|
+
result['aps'] = {}
|
95
|
+
result['aps']['alert'] = alert if alert
|
96
|
+
result['aps']['badge'] = badge.to_i if badge
|
97
|
+
result['aps']['sound'] = sound if sound and sound.is_a? String
|
98
|
+
result['aps']['sound'] = 'default' if sound and sound.is_a? TrueClass
|
99
|
+
result
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "app", "models", "apple_push_notification.rb")
|
2
|
+
|
3
|
+
%w{ models }.each do |dir|
|
4
|
+
path = File.join(File.dirname(__FILE__), 'app', dir)
|
5
|
+
$LOAD_PATH << path
|
6
|
+
puts "Adding #{path}"
|
7
|
+
ActiveSupport::Dependencies.load_paths << path
|
8
|
+
ActiveSupport::Dependencies.load_once_paths.delete(path)
|
9
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateApplePushNotifications < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
# This is used to store the device UID informations
|
4
|
+
create_table :apple_push_notifications do |t|
|
5
|
+
t.string :device_token, :size => 71
|
6
|
+
t.integer :errors_nb, :default => 0 # used for storing errors from apple feedbacks
|
7
|
+
t.string :device_language, :size => 5 # if you don't want to send localized strings
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :apple_push_notifications, :device_token
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :apple_push_notifications
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
namespace :apn do
|
2
|
+
desc "migrates ugin's migration files into the database."
|
3
|
+
task :migrate => :environment do
|
4
|
+
|
5
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
6
|
+
ActiveRecord::Migrator.migrate(File.expand_path(File.dirname(__FILE__) + "/../lib/db/migrate"), ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
7
|
+
|
8
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
9
|
+
end
|
10
|
+
end
|
data/test/test_helper.rb
ADDED
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apple_push_notification
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Soffes
|
8
|
+
- Fabien Penso
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-11-10 00:00:00 -06:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Rails plugin for Apple Push Notifications
|
18
|
+
email: sam@samsoff.es
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- LICENSE
|
28
|
+
- Rakefile
|
29
|
+
- Readme.markdown
|
30
|
+
- VERSION
|
31
|
+
- init.rb
|
32
|
+
- install.rb
|
33
|
+
- lib/app/models/apple_push_notification.rb
|
34
|
+
- lib/apple_push_notification.rb
|
35
|
+
- lib/db/migrate/20090406132059_create_apple_push_notifications.rb
|
36
|
+
- tasks/apple_push_notification_tasks.rake
|
37
|
+
- test/apple_push_notification_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
- uninstall.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/samsoffes/apple_push_notification
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Rails plugin for Apple Push Notifications
|
68
|
+
test_files:
|
69
|
+
- test/apple_push_notification_test.rb
|
70
|
+
- test/test_helper.rb
|