acts_as_pushable 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed12f0e669f857b1557bfd63ceaf0b707666202e
4
+ data.tar.gz: 82c4bbdfc796f1c940a6a0f1d4fa3eb89ee7b5c5
5
+ SHA512:
6
+ metadata.gz: cc1fda57e9415e2492820c26a233311c0d6eea4886dde6112d98b8f2a56482ddfe2e2220ffb6c7699808ecf4633e84ef788ad23dd2bb49c739b0be8e5abf200d
7
+ data.tar.gz: a8f27a82cd72ef09e38750ae37f5d1b722fb16f988be7b0b9abae1fd8ef23f186a302cbb217de5487f2b6a0d3f6723ab4a44b5084951e6ba65a02d7a49e8457c
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Adam Butler
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.md ADDED
@@ -0,0 +1,156 @@
1
+ # ActsAsPushable
2
+
3
+ [![Build Status](https://semaphoreci.com/api/v1/projects/28a53ae7-389f-4d93-9f8a-51c4b0756cf7/840599/badge.svg)](https://semaphoreci.com/simpleweb/acts_as_pushable)
4
+ [![Gem Version](https://badge.fury.io/rb/acts_as_pushable.svg)](https://badge.fury.io/rb/acts_as_pushable)
5
+
6
+ A gem for Ruby on Rails that makes managing devices and push notifications for both iOS and Android easy and reliable.
7
+
8
+ ## Setup
9
+
10
+ Add ActsAsPushable to your Gemfile
11
+
12
+ ```shell
13
+ gem 'acts_as_pushable'
14
+ bundle install
15
+ ```
16
+
17
+ or just install it -
18
+
19
+ ```shell
20
+ gem install acts_as_pushable
21
+ ```
22
+
23
+ ## Quick start
24
+
25
+ Run the generator to create the migrations and initializer template -
26
+
27
+ ```shell
28
+ rails generate act_as_pushable
29
+ ```
30
+
31
+ This a file at `config/initializers/acts_as_pushable.rb` that you can modify to match your settings. Follow the quick start guides for the platforms that you want to support.
32
+
33
+ Next add `acts_as_pushable` the following to the model that you want to have devices, this is usually the `User` model. It should look something like this -
34
+
35
+ ```ruby
36
+ class User < ActiveRecord::Base
37
+ acts_as_pushable
38
+ end
39
+ ```
40
+
41
+ ## Quick start - iOS
42
+
43
+ Before we start you'll need a push certificate for both APN Development and APN Production. You can find instructions on how to do this [here](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW11).
44
+
45
+ > **Important:** You should do both production and development and include them in all deployment environments. These relate to the two environments that Apple provide rather than your environments.
46
+
47
+ Once you have the certificate from Apple, you will need to export your key and the installed certificate as p12 files. Here how you do this -
48
+
49
+ 1. In Keychain Access find your installed certificate
50
+ 2. Right click the certificate, it should have an arrow next to it if install correctly, then export it.
51
+ ![export](https://cloud.githubusercontent.com/assets/1238468/15851982/5a9bb9e0-2c97-11e6-8407-2e4797673dff.jpg)
52
+ 3. Next convert the p12 file to a pem file by running the following command.
53
+ ```
54
+ $ openssl pkcs12 -in cert.p12 -out apple_push_notification.pem -nodes -clcerts
55
+ ```
56
+ 4. The output pem file should be put in one of the following locations depending on it's type -
57
+ - `config/acts_as_pushable/apn/production.pem`
58
+ - `config/acts_as_pushable/apn/development.pem`
59
+
60
+ > Note: You can change the location that the pem file is loaded stored in the `acts_as_pushable.rb` initializer.
61
+
62
+ ## Quick start - Android
63
+
64
+ 1. Register for GCM (Google Cloud Messaging) at [developers.google.com](https://developers.google.com/cloud-messaging/).
65
+ 2. Enter your key into the `acts_as_pushable.rb` initializer. You can get this from the [Google API Developer Console](https://console.developers.google.com). It should be entered as such -
66
+
67
+ ```ruby
68
+ ActsAsPushable.configure do |config|
69
+ config.gcm_key = 'replace_me_with_your_api_key'
70
+ end
71
+ ```
72
+
73
+ ## Add a device
74
+
75
+ You can add a device to any model with `acts_as_pushable`. In these examples we'll use a model named `User` as an example.
76
+
77
+ ```ruby
78
+ user = User.create
79
+ user.add_device({
80
+ token: 'the_token_generated_by_the_device',
81
+ platform: "ios",
82
+ platform_version: "9.3",
83
+ push_environment: "development",
84
+ })
85
+ ```
86
+
87
+ ## Send a push notification to a user
88
+
89
+ Sending a push notification to a user will send the message to all of their valid device tokens both on iOS & Android
90
+
91
+ ```ruby
92
+ user = User.find(id)
93
+ user.send_push_notification(title: 'My App', message: 'this is a test', options)
94
+ ```
95
+
96
+ > You might want to consider doing this inside a worker.
97
+
98
+ ## Send a push notification to a specific device
99
+
100
+ ```ruby
101
+ user = User.find(id)
102
+ device = user.devices.first
103
+
104
+ case device.platform
105
+ when "ios"
106
+ # iOS does not support titles
107
+ user.send_push_notification(message: 'this is a test', options)
108
+ when "android"
109
+ user.send_push_notification(message: 'this is a test', options)
110
+ end
111
+ ```
112
+
113
+ > You might want to consider doing this inside a worker.
114
+
115
+ ## Apple Feedback Service
116
+
117
+ Occasionally you'll want to cleanup old tokens that have been invalidated for various reasons. You can do this by running -
118
+
119
+ ```
120
+ ActsAsPushable::APN::FeedbackService.run
121
+ ```
122
+
123
+ We'd recommnd running this on a daily/weekly cron job.
124
+
125
+ > Note: With Android this happens at the time of sending a notification, no action is required.
126
+
127
+ ---
128
+
129
+ ## Setup for development
130
+
131
+ Clone the repository -
132
+
133
+ ```shell
134
+ git clone git@github.com:simpleweb/acts_as_pushable.git
135
+ cd acts_as_pushable
136
+ bundle install
137
+ ```
138
+
139
+ #### Run the specs with RSpec
140
+
141
+ ```
142
+ rspec
143
+ ```
144
+
145
+ ## Other useful resources
146
+
147
+ - [Bullet Proof Push](https://www.youtube.com/watch?v=k5J6t-y1bws) _15 minute talk by [Adam Butler](http://twitter.com/labfoo)_ - The ideas that this gem is based on.
148
+ - [simpleweb/ios-development-for-teams](https://github.com/simpleweb/ios-development-for-teams) - A guide by the author of this gem on setting up Certificates, ID's and Provisioning profiles that work well for teams.
149
+ - [nomad/houston](https://github.com/nomad/houston) - Powers the APN part of this gem
150
+ - [spacialdb/gcm](https://github.com/spacialdb/gcm) - Powers the GCM part of this gem.
151
+
152
+ ## Contributing
153
+
154
+ This project follows the [GitHub Flow workflow](https://guides.github.com/introduction/flow/). All contributions should be provided as descriptive atomic pull requests.
155
+
156
+ The gem should be versioned in accordance to [Semantic Versioning 2.0.0](http://semver.org/).
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ActsAsPushable'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,46 @@
1
+ module ActsAsPushable
2
+ class Device < ActiveRecord::Base
3
+ belongs_to :parent, polymorphic: true
4
+
5
+ validates :token, :platform, :valid_at, :parent, :platform_version, :push_environment, presence: true
6
+ validates :token, uniqueness: true
7
+ validates :active, inclusion: { in: [true, false] }
8
+
9
+ before_validation :set_valid_at, on: :create
10
+
11
+ scope :active, -> { where(invalidated_at: nil, active: true) }
12
+
13
+ default_scope { active }
14
+
15
+ def ios?
16
+ platform == 'ios'
17
+ end
18
+
19
+ def android?
20
+ platform == 'android'
21
+ end
22
+
23
+ def deactivate
24
+ self.update_attributes({
25
+ active: false,
26
+ deactivated_at: Time.now,
27
+ })
28
+ end
29
+
30
+ def send_push_notification(message:, **options)
31
+ case platform
32
+ when 'ios'
33
+ ActsAsPushable::APN::Notification.send(device: self, message: message, **options)
34
+ when 'android'
35
+ raise ArgumentError, 'missing keyword: title' unless options.key? :title
36
+ ActsAsPushable::GCM::Notification.send(device: self, title: options[:title], message: message, **options)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def set_valid_at
43
+ self.valid_at = Time.now
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,22 @@
1
+ require 'houston'
2
+
3
+ module ActsAsPushable
4
+ module APN
5
+ class FeedbackService
6
+ def self.run
7
+ development_apn = Houston::Client.development
8
+ production_apn = Houston::Client.production
9
+
10
+ development_apn.certificate = ActsAsPushable.configuration.apn_development_certificate_file
11
+ production_apn.certificate = ActsAsPushable.configuration.apn_production_certificate_file
12
+
13
+ devices = development_apn.devices + production_apn.devices
14
+
15
+ devices.each do |device|
16
+ device = ActsAsPushable::Device.find_by_token(device)
17
+ device.update_attribute('invalidated_at', Time.now) if device
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ require 'houston'
2
+
3
+ module ActsAsPushable
4
+ module APN
5
+ class Notification
6
+ def self.send(device:, message:, **options)
7
+ development_apn = Houston::Client.development
8
+ production_apn = Houston::Client.production
9
+
10
+ development_apn.certificate = ActsAsPushable.configuration.apn_development_certificate_file
11
+ production_apn.certificate = ActsAsPushable.configuration.apn_production_certificate_file
12
+
13
+ payload = {
14
+ popup: options.fetch('popup', true),
15
+ popup_title: options.fetch('popup_title', nil),
16
+ popup_body: options.fetch('popup_body', nil),
17
+ popup_type: options.fetch('popup_type', 'alert'),
18
+ popup_ok_button_text: options.fetch('popup_ok_button_text', 'Ok'),
19
+ popup_cancel_button_text: options.fetch('popup_cancel_button_text', 'Cancel'),
20
+ navigate_to_view: options.fetch('navigate_to_view', nil),
21
+ navigate_to_view_as_modal: options.fetch('navigate_to_view_as_modal', true),
22
+ navigate_to_view_parameters: options.fetch('navigate_to_view_parameters', {}),
23
+ }
24
+
25
+ notification = Houston::Notification.new(device: device.token)
26
+ notification.alert = message
27
+ notification.badge = options.fetch('count', nil)
28
+ notification.custom_data = payload
29
+
30
+ if device.push_environment == 'development'
31
+ development_apn.push(notification)
32
+ else
33
+ production_apn.push(notification)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ module ActsAsPushable
2
+ class Configuration
3
+ attr_accessor :apn_development_certificate_path, :apn_production_certificate_path, :gcm_key
4
+
5
+ def initialize
6
+ self.apn_development_certificate_path = Rails.root.join('config', 'acts_as_pushable', 'apn', 'development.pem')
7
+ self.apn_production_certificate_path = Rails.root.join('config', 'acts_as_pushable', 'apn', 'production.pem')
8
+ end
9
+
10
+ def apn_development_certificate_file
11
+ File.read(apn_development_certificate_path)
12
+ end
13
+
14
+ def apn_production_certificate_file
15
+ File.read(apn_production_certificate_path)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ require 'gcm'
2
+
3
+ module ActsAsPushable
4
+ module GCM
5
+ class Notification
6
+ def self.send(device:, title:, message:, **options)
7
+ payload = {
8
+ popup: options.fetch("popup", true),
9
+ popup_title: options.fetch("popup_title", nil),
10
+ popup_body: options.fetch("popup_body", nil),
11
+ popup_type: options.fetch("popup_type", 'alert'),
12
+ popup_ok_button_text: options.fetch("popup_ok_button_text", 'Ok'),
13
+ popup_cancel_button_text: options.fetch("popup_cancel_button_text", 'Cancel'),
14
+ navigate_to_view: options.fetch("navigate_to_view", nil),
15
+ navigate_to_view_as_modal: options.fetch("navigate_to_view_as_modal", true),
16
+ navigate_to_view_parameters: options.fetch("navigate_to_view_parameters", {}),
17
+ }
18
+
19
+ gcm = ::GCM.new(ActsAsPushable.configuration.gcm_key)
20
+
21
+ gcm_options = {
22
+ data: {
23
+ title: title,
24
+ message: message,
25
+ }.merge(payload)
26
+ }
27
+
28
+ response = gcm.send([device.token], gcm_options)
29
+ if response[:not_registered_ids].include? device.token
30
+ device.update_attribute 'invalidated_at', Time.now
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ module ActsAsPushable
2
+ module Pushable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ end
7
+
8
+ module ClassMethods
9
+ def acts_as_pushable(options = {})
10
+ has_many :devices, as: :parent, class_name: 'ActsAsPushable::Device'
11
+ end
12
+ end
13
+
14
+ def ios_devices
15
+ devices.where(platform: 'ios')
16
+ end
17
+
18
+ def android_devices
19
+ devices.where(platform: 'android')
20
+ end
21
+
22
+ def add_device(device_params)
23
+ device = build_device(device_params)
24
+ device.save
25
+ end
26
+
27
+ def add_device!(device_params)
28
+ device = build_device(device_params)
29
+ device.save!
30
+ end
31
+
32
+ def send_push_notification(title:, message:, **options)
33
+ devices.each do |device|
34
+ device.send_push_notification(title: title, message: message, **options)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def build_device(device_params)
41
+ self.devices.build(device_params)
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ ActiveRecord::Base.send :include, ActsAsPushable::Pushable
@@ -0,0 +1,3 @@
1
+ module ActsAsPushable
2
+ VERSION = '0.1.1'
3
+ end
@@ -0,0 +1,30 @@
1
+ require 'acts_as_pushable/version'
2
+ require 'acts_as_pushable/configuration'
3
+
4
+ require 'acts_as_pushable/active_record/device.rb'
5
+ require 'acts_as_pushable/pushable'
6
+
7
+ require 'acts_as_pushable/apn/notification'
8
+ require 'acts_as_pushable/apn/feedback_service'
9
+ require 'acts_as_pushable/gcm/notification'
10
+
11
+ module ActsAsPushable
12
+ LOCK = Mutex.new
13
+
14
+ class << self
15
+ def configure(config_hash=nil)
16
+ if config_hash
17
+ config_hash.each do |k,v|
18
+ configuration.send("#{k}=", v) rescue nil if configuration.respond_to?("#{k}=")
19
+ end
20
+ end
21
+
22
+ yield(configuration) if block_given?
23
+ end
24
+
25
+ def configuration
26
+ @configuration = nil unless defined?(@configuration)
27
+ @configuration || LOCK.synchronize { @configuration ||= ActsAsPushable::Configuration.new }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ require 'rails/generators/migration'
2
+
3
+ module ActsAsPushable
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ def copy_initializer_file
11
+ template "initializer.rb", "config/initializers/acts_as_pushable.rb"
12
+ end
13
+
14
+ def copy_migration_files
15
+ migration_template "migration/devices.rb", "db/migrate/devices.rb"
16
+ end
17
+
18
+ def self.next_migration_number(dirname)
19
+ if ActiveRecord::Base.timestamped_migrations
20
+ sleep 1 # make sure each time we get a different timestamp
21
+ Time.new.utc.strftime("%Y%m%d%H%M%S")
22
+ else
23
+ "%.3d" % (current_migration_number(dirname) + 1)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ ActsAsPushable.configure do |config|
2
+ # Defaults
3
+ # config.apn_development_certificate_path = Rails.root.join('config', 'acts_as_pushable', 'apn', 'development.pem')
4
+ # config.apn_production_certificate_path = Rails.root.join('config', 'acts_as_pushable', 'apn', 'production.pem')
5
+
6
+ config.gcm_key = "replace_me_with_your_gcm_api_key"
7
+ end
@@ -0,0 +1,21 @@
1
+ class Devices < ActiveRecord::Migration
2
+ def change
3
+ create_table :devices do |t|
4
+ t.string :token
5
+ t.integer :parent_id
6
+ t.string :parent_type
7
+ t.string :platform
8
+ t.boolean :active, default: true
9
+ t.datetime :valid_at
10
+ t.datetime :invalidated_at
11
+ t.datetime :deleted_at
12
+ t.string :platform_version
13
+ t.string :platform_type
14
+ t.string :push_environment
15
+ t.datetime :deactivated_at
16
+ t.timestamps
17
+ end
18
+
19
+ add_index :devices, :token, unique: true
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :acts_as_pushable do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_pushable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Adam Butler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0.beta4
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 5.0.0.beta4
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.1'
33
+ - !ruby/object:Gem::Dependency
34
+ name: houston
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: gcm
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: sqlite3
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-rails
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: fuubar
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: timecop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: pry
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: simplecov
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ description: A gem for Ruby on Rails that makes managing devices and push notifications
146
+ for both iOS and Android easy and reliable.
147
+ email:
148
+ - adam@simpleweb.co.uk
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - MIT-LICENSE
154
+ - README.md
155
+ - Rakefile
156
+ - lib/acts_as_pushable.rb
157
+ - lib/acts_as_pushable/active_record/device.rb
158
+ - lib/acts_as_pushable/apn/feedback_service.rb
159
+ - lib/acts_as_pushable/apn/notification.rb
160
+ - lib/acts_as_pushable/configuration.rb
161
+ - lib/acts_as_pushable/gcm/notification.rb
162
+ - lib/acts_as_pushable/pushable.rb
163
+ - lib/acts_as_pushable/version.rb
164
+ - lib/generators/acts_as_pushable/install_generator.rb
165
+ - lib/generators/acts_as_pushable/templates/initializer.rb
166
+ - lib/generators/acts_as_pushable/templates/migration/devices.rb
167
+ - lib/tasks/acts_as_pushable_tasks.rake
168
+ homepage: https://github.com/simpleweb/acts_as_pushable
169
+ licenses:
170
+ - MIT
171
+ metadata: {}
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubyforge_project:
188
+ rubygems_version: 2.4.5.1
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Add iOS & Android device and push notification support in your Rails application.
192
+ test_files: []