apn_on_rails 0.2.0 → 0.2.2
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 +7 -2
- data/generators/apn_migrations_generator.rb +17 -5
- data/generators/templates/apn_migrations/{create_apn_devices.rb → 001_create_apn_devices.rb} +0 -0
- data/generators/templates/apn_migrations/{create_apn_notifications.rb → 002_create_apn_notifications.rb} +0 -0
- data/lib/apn_on_rails/apn_on_rails.rb +12 -2
- data/lib/apn_on_rails/app/models/apn/connection.rb +65 -0
- data/lib/apn_on_rails/app/models/apn/notification.rb +8 -18
- metadata +5 -4
data/README
CHANGED
@@ -94,10 +94,15 @@ That's it, now you're ready to start creating notifications.
|
|
94
94
|
>> notification.sound = true
|
95
95
|
>> notification.alert = "foobar"
|
96
96
|
>> notification.save
|
97
|
-
>> APN::Notification.send_notifications
|
98
97
|
|
99
|
-
You can
|
98
|
+
You can use the following Rake task to deliver your notifications:
|
100
99
|
|
101
100
|
$ rake apn:notifications:deliver
|
102
101
|
|
102
|
+
The Rake task will find any unsent notifications in the database. If there aren't any notifications
|
103
|
+
it will simply do nothing. If there are notifications waiting to be delivered it will open a single connection
|
104
|
+
to Apple and push all the notifications through that one connection. Apple does not like people opening/closing
|
105
|
+
connections constantly, so it's pretty important that you are careful about batching up your notifications so
|
106
|
+
Apple doesn't shut you down.
|
107
|
+
|
103
108
|
Released under the MIT license.
|
@@ -4,10 +4,22 @@ class ApnMigrationsGenerator < Rails::Generator::Base
|
|
4
4
|
|
5
5
|
def manifest # :nodoc:
|
6
6
|
record do |m|
|
7
|
-
|
8
|
-
|
7
|
+
timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
|
8
|
+
db_migrate_path = File.join('db', 'migrate')
|
9
|
+
|
10
|
+
m.directory(db_migrate_path)
|
11
|
+
|
12
|
+
['001_create_apn_devices', '002_create_apn_notifications'].each_with_index do |f, i|
|
13
|
+
timestamp = timestamp.succ
|
14
|
+
if Dir.glob(File.join(db_migrate_path, "*_#{f}.rb")).empty?
|
15
|
+
m.file(File.join('apn_migrations', "#{f}.rb"),
|
16
|
+
File.join(db_migrate_path, "#{timestamp}_#{f}.rb"),
|
17
|
+
{:collision => :skip})
|
18
|
+
end
|
9
19
|
end
|
10
|
-
|
11
|
-
|
20
|
+
|
21
|
+
end # record
|
22
|
+
|
23
|
+
end # manifest
|
12
24
|
|
13
|
-
end
|
25
|
+
end # ApnMigrationsGenerator
|
data/generators/templates/apn_migrations/{create_apn_devices.rb → 001_create_apn_devices.rb}
RENAMED
File without changes
|
File without changes
|
@@ -14,12 +14,22 @@ end
|
|
14
14
|
|
15
15
|
configatron.apn.set_default(:passphrase, '')
|
16
16
|
configatron.apn.set_default(:port, 2195)
|
17
|
-
|
18
|
-
configatron.apn.set_default(:
|
17
|
+
|
18
|
+
configatron.apn.feedback.set_default(:passphrase, configatron.apn.passphrase)
|
19
|
+
configatron.apn.feedback.set_default(:port, 2196)
|
19
20
|
|
20
21
|
if rails_env == 'production'
|
21
22
|
configatron.apn.set_default(:host, 'gateway.push.apple.com')
|
22
23
|
configatron.apn.set_default(:cert, File.join(rails_root, 'config', 'apple_push_notification_production.pem'))
|
24
|
+
|
25
|
+
configatron.apn.feedback.set_default(:host, 'feedback.push.apple.com')
|
26
|
+
configatron.apn.feedback.set_default(:cert, configatron.apn.cert)
|
27
|
+
else
|
28
|
+
configatron.apn.set_default(:host, 'gateway.sandbox.push.apple.com')
|
29
|
+
configatron.apn.set_default(:cert, File.join(rails_root, 'config', 'apple_push_notification_development.pem'))
|
30
|
+
|
31
|
+
configatron.apn.feedback.set_default(:host, 'feedback.sandbox.push.apple.com')
|
32
|
+
configatron.apn.feedback.set_default(:cert, configatron.apn.cert)
|
23
33
|
end
|
24
34
|
|
25
35
|
module APN # :nodoc:
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module APN
|
2
|
+
module Connection
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# Yields up an SSL socket to write notifications to.
|
7
|
+
# The connections are close automatically.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# APN::Configuration.open_for_delivery do |conn|
|
11
|
+
# conn.write('my cool notification')
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Configuration parameters are:
|
15
|
+
#
|
16
|
+
# configatron.apn.passphrase = ''
|
17
|
+
# configatron.apn.port = 2195
|
18
|
+
# configatron.apn.host = 'gateway.sandbox.push.apple.com' # Development
|
19
|
+
# configatron.apn.host = 'gateway.push.apple.com' # Production
|
20
|
+
# configatron.apn.cert = File.join(rails_root, 'config', 'apple_push_notification_development.pem')) # Development
|
21
|
+
# configatron.apn.cert = File.join(rails_root, 'config', 'apple_push_notification_production.pem')) # Production
|
22
|
+
def open_for_delivery(options = {}, &block)
|
23
|
+
open(options, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Yields up an SSL socket to receive feedback from.
|
27
|
+
# The connections are close automatically.
|
28
|
+
# Configuration parameters are:
|
29
|
+
#
|
30
|
+
# configatron.apn.feedback.passphrase = ''
|
31
|
+
# configatron.apn.feedback.port = 2196
|
32
|
+
# configatron.apn.feedback.host = 'feedback.sandbox.push.apple.com' # Development
|
33
|
+
# configatron.apn.feedback.host = 'feedback.push.apple.com' # Production
|
34
|
+
# configatron.apn.feedback.cert = File.join(rails_root, 'config', 'apple_push_notification_development.pem')) # Development
|
35
|
+
# configatron.apn.feedback.cert = File.join(rails_root, 'config', 'apple_push_notification_production.pem')) # Production
|
36
|
+
def open_for_feedback(options = {}, &block) # :nodoc:
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def open(options = {}, &block) # :nodoc:
|
42
|
+
options = {:cert => configatron.apn.cert,
|
43
|
+
:passphrase => configatron.apn.passphrase,
|
44
|
+
:host => configatron.apn.host,
|
45
|
+
:port => configatron.apn.port}.merge(options)
|
46
|
+
cert = File.read(options[:cert])
|
47
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
48
|
+
ctx.key = OpenSSL::PKey::RSA.new(cert, options[:passphrase])
|
49
|
+
ctx.cert = OpenSSL::X509::Certificate.new(cert)
|
50
|
+
|
51
|
+
s = TCPSocket.new(options[:host], options[:port])
|
52
|
+
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
|
53
|
+
ssl.sync = true
|
54
|
+
ssl.connect
|
55
|
+
|
56
|
+
yield ssl if block_given?
|
57
|
+
|
58
|
+
ssl.close
|
59
|
+
s.close
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end # Connection
|
65
|
+
end # APN
|
@@ -86,25 +86,15 @@ class APN::Notification < ActiveRecord::Base
|
|
86
86
|
# so as to not be sent again.
|
87
87
|
def send_notifications(notifications = APN::Notification.all(:conditions => {:sent_at => nil}))
|
88
88
|
unless notifications.nil? || notifications.empty?
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
|
97
|
-
ssl.sync = true
|
98
|
-
ssl.connect
|
99
|
-
|
100
|
-
notifications.each do |noty|
|
101
|
-
ssl.write(noty.message_for_sending)
|
102
|
-
noty.sent_at = Time.now
|
103
|
-
noty.save
|
89
|
+
|
90
|
+
APN::Connection.open_for_delivery do |conn|
|
91
|
+
notifications.each do |noty|
|
92
|
+
conn.write(noty.message_for_sending)
|
93
|
+
noty.sent_at = Time.now
|
94
|
+
noty.save
|
95
|
+
end
|
104
96
|
end
|
105
|
-
|
106
|
-
ssl.close
|
107
|
-
s.close
|
97
|
+
|
108
98
|
end
|
109
99
|
end
|
110
100
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apn_on_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- markbates
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-30 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -33,6 +33,7 @@ extra_rdoc_files:
|
|
33
33
|
- LICENSE
|
34
34
|
files:
|
35
35
|
- lib/apn_on_rails/apn_on_rails.rb
|
36
|
+
- lib/apn_on_rails/app/models/apn/connection.rb
|
36
37
|
- lib/apn_on_rails/app/models/apn/device.rb
|
37
38
|
- lib/apn_on_rails/app/models/apn/notification.rb
|
38
39
|
- lib/apn_on_rails/tasks/apn.rake
|
@@ -42,8 +43,8 @@ files:
|
|
42
43
|
- README
|
43
44
|
- LICENSE
|
44
45
|
- generators/apn_migrations_generator.rb
|
45
|
-
- generators/templates/apn_migrations/
|
46
|
-
- generators/templates/apn_migrations/
|
46
|
+
- generators/templates/apn_migrations/001_create_apn_devices.rb
|
47
|
+
- generators/templates/apn_migrations/002_create_apn_notifications.rb
|
47
48
|
has_rdoc: true
|
48
49
|
homepage: http://www.metabates.com
|
49
50
|
licenses: []
|