ionic_notification 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee5e9c16fb782a621dd32fbf84f5c9e86ed03af7
4
+ data.tar.gz: 32401e6b956423a974c4e8d319e84809aa77e7c4
5
+ SHA512:
6
+ metadata.gz: cb6f1768764d9f270806c68d8e4bfd6fb60859d84767ffcb7951ed534848ee36aa4a5c4f6a983bdb2634981b4b4395032c20154bf37428091378944f6196609f
7
+ data.tar.gz: 5bd12f0054420bae6aff470221eb1e2dc6e62056e4ef6fb368b846e241e62a772912bd83ff4dfdf3897b85da00177e843da110a091efd89aaff010eb90cea70a
@@ -0,0 +1,22 @@
1
+ Copyright 2015 Francesco Renzi
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.
21
+
22
+ This internal project started from the code base of nwwatson `ionic_push_repo`
@@ -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 = 'IonicNotification'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_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,16 @@
1
+ require 'rails/generators'
2
+
3
+ module IonicNotification
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ desc "Generates IonicNotification initializer"
10
+
11
+ def copy_config
12
+ copy_file "ionic_notification.rb", "config/initializers/ionic_notification.rb"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,58 @@
1
+ IonicNotification.setup do |config|
2
+ # ==> Configuration for the Ionic.io Application ID
3
+ # The Application ID can be found on the dashboard of
4
+ # https://apps.ionic.io/apps
5
+ config.ionic_application_id = ENV["IONIC_APPLICATION_ID"]
6
+
7
+ # ==> Configuration for the Ionic API Key
8
+ # The API Key for your application can be found
9
+ # within the Settings of your application on
10
+ # https://apps.ionic.io/apps
11
+ config.ionic_api_key = ENV["IONIC_API_KEY"]
12
+
13
+ # Your Ionic app name will be used for the notification
14
+ # title if none is provided. If you leave this undefined
15
+ # IonicNotification will use your Rails app name
16
+ config.ionic_app_name = Rails.application.class.parent_name
17
+
18
+ # If you want, you can customize IonicNotification logging level
19
+ # It defaults to :debug
20
+ # config.log_level = :debug
21
+ #
22
+ # You can change the amount of stored sent notifications
23
+ # config.notification_store_limit = 3
24
+ #
25
+ # By default, notifications with no message provided will be skipped,
26
+ # you don't want your clients to receive a notification with no message,
27
+ # right? Well, sometimes it can be useful to speed up development
28
+ # and test. You could like to be able to do something like:
29
+ # User.first.notify
30
+ # and see what happens, without bothering writing a fake message.
31
+ # You can enable this if you want:
32
+ # config.process_empty_messages = true
33
+ # Or in a more safe way:
34
+ # config.process_empty_messages = !Rails.env.production?
35
+ #
36
+ # Anyway, you can set up a default message to be used when you don't
37
+ # provide one:
38
+ # config.default_message = "This was intended to be a beautiful notification. Unfortunately, you're not qualified to read it."
39
+
40
+ # If production is set to true, notifications will be sent
41
+ # to all devices which have your app running with production
42
+ # certificates (generally coming from store). Otherwise,
43
+ # if set to false, to all devices which have your app running
44
+ # with developer certificates.
45
+ config.ionic_app_in_production = true
46
+ # If you want a more flexible solution, you can
47
+ # uncomment this, so that notifications will be sent
48
+ # to "production devices" only while Rails app is running
49
+ # in production environment
50
+ # config.ionic_app_in_production = Rails.env.production?
51
+
52
+ # ==> Configuration for the location of the API
53
+ # Refer to the Ionic documentation for the correct location
54
+ # Current documentation can be found here:
55
+ # http://docs.ionic.io/docs/push-sending-push and
56
+ # defaults to https://push.ionic.io
57
+ # config.ionic_api_url = ENV["IONIC_API_URL"]
58
+ end
@@ -0,0 +1,34 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/active_record'
3
+ require 'generators/ionic_notification/orm_helpers'
4
+
5
+ module IonicNotification
6
+ module Generators
7
+ class ModelGenerator < ActiveRecord::Generators::Base
8
+
9
+ include IonicNotification::Generators::OrmHelpers
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ desc "Generates a migration for the given MODEL, adding :device_tokens column"
13
+
14
+ def copy_migration
15
+ migration_template "migration.rb", "db/migrate/add_device_tokens_to_#{table_name}.rb"
16
+ end
17
+
18
+ def inject_ionic_notification_content
19
+ content = model_contents
20
+
21
+ class_path = if namespaced?
22
+ class_name.to_s.split("::")
23
+ else
24
+ [class_name]
25
+ end
26
+
27
+ indent_depth = class_path.size - 1
28
+ content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
29
+
30
+ inject_into_class(model_path, class_path.last, content)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ class AddDeviceTokensTo<%= table_name.camelize %> < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :<%= table_name %>, :device_tokens, :text
4
+ end
5
+
6
+ def down
7
+ remove_column :<%= table_name %>, :device_tokens
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ module IonicNotification
2
+ module Generators
3
+ module OrmHelpers
4
+ def model_contents
5
+ buffer = <<-CONTENT
6
+ # Include IonicNotification behaviour
7
+ include IonicNotification::Concerns::IonicNotificable
8
+
9
+
10
+ CONTENT
11
+ buffer
12
+ end
13
+
14
+ private
15
+
16
+ def model_exists?
17
+ File.exists?(File.join(destination_root, model_path))
18
+ end
19
+
20
+ def migration_exists?(table_name)
21
+ Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_devise_to_#{table_name}.rb$/).first
22
+ end
23
+
24
+ def migration_path
25
+ @migration_path ||= File.join("db", "migrate")
26
+ end
27
+
28
+ def model_path
29
+ @model_path ||= File.join("app", "models", "#{file_path}.rb")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,63 @@
1
+ require 'rails'
2
+ require 'httparty'
3
+
4
+ module IonicNotification
5
+ # Registered application if for the ionic platform
6
+ mattr_accessor :ionic_application_id
7
+ @@ionic_application_id = ""
8
+
9
+ # Private key for sending information
10
+ mattr_accessor :ionic_api_key
11
+ @@ionic_api_key = ""
12
+
13
+ # Application name
14
+ mattr_accessor :ionic_app_name
15
+ @@ionic_app_name = Rails.application.class.parent_name
16
+
17
+ # Is application in production
18
+ mattr_accessor :ionic_app_in_production
19
+ @@ionic_app_in_production = true
20
+
21
+ # Send notification even if it has no message
22
+ mattr_accessor :process_empty_messages
23
+ @@process_empty_messages = false
24
+
25
+ # Default message for notifications
26
+ mattr_accessor :default_message
27
+ @@default_message = "This was intended to be a beautiful notification. Unfortunately, you're not qualified to read it."
28
+
29
+ # Logging level
30
+ mattr_accessor :log_level
31
+ @@log_level = :debug
32
+
33
+ # Array that stores latest X sent notifications
34
+ mattr_accessor :latest_notifications
35
+ @@latest_notifications = []
36
+
37
+ # Array that stores latest X sent notifications
38
+ mattr_accessor :notification_store_limit
39
+ @@notification_store_limit = 3
40
+
41
+ # API URL
42
+ mattr_accessor :ionic_api_url
43
+ @@ionic_api_url = "https://push.ionic.io"
44
+
45
+ def self.setup
46
+ yield self
47
+ end
48
+
49
+ def self.store(notification)
50
+ if latest_notifications.count >= notification_store_limit
51
+ latest_notifications.shift
52
+ end
53
+ latest_notifications << notification
54
+ end
55
+ end
56
+
57
+ require "ionic_notification/logger"
58
+ require "ionic_notification/push_service"
59
+ require "ionic_notification/status_service"
60
+ require "ionic_notification/notification"
61
+ require "ionic_notification/sent_notification"
62
+ require "ionic_notification/exceptions"
63
+ require "ionic_notification/concerns/ionic_notificable"
@@ -0,0 +1,46 @@
1
+ module IonicNotification
2
+ module Concerns
3
+ module IonicNotificable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ serialize :device_tokens, Array
8
+
9
+ def notify(options = {})
10
+ logger = self.class.new_logger
11
+ return logger.missing_device_tokens unless respond_to?(:device_tokens)
12
+ tokens = device_tokens.uniq
13
+ return logger.no_device_tokens(self) unless tokens.count > 0
14
+ notification = IonicNotification::Notification.new(options.merge!(tokens: tokens))
15
+ notification.send
16
+ end
17
+
18
+ def notify_at(schedule, options = {})
19
+ options.merge!(scheduled: schedule.to_time.to_i)
20
+ notify options
21
+ end
22
+
23
+ def notify_in(delay, options = {})
24
+ schedule = Time.now + delay
25
+ options.merge!(scheduled: schedule.to_i)
26
+ notify options
27
+ end
28
+
29
+ def self.notify_all(options = {})
30
+ logger = new_logger
31
+ return logger.missing_device_tokens unless method_defined?(:device_tokens)
32
+ tokens = all.map(&:device_tokens).flatten.uniq
33
+ return logger.no_device_tokens(self) unless tokens.count > 0
34
+ notification = IonicNotification::Notification.new(options.merge!(tokens: tokens))
35
+ notification.send
36
+ end
37
+
38
+ private
39
+
40
+ def self.new_logger
41
+ IonicNotification::Logger.new
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ module IonicNotification
2
+ class WrongTokenType < StandardError
3
+ def initialize(klazz = nil)
4
+ return complete_message(klazz) if klazz
5
+ default_message
6
+ end
7
+
8
+ private
9
+
10
+ def default_message
11
+ "Wrong type of tokens provided."
12
+ end
13
+
14
+ def complete_message(klazz)
15
+ "Wrong type of tokens provided. String and Array are accepted, #{klazz} was given."
16
+ end
17
+ end
18
+
19
+ class WrongPayloadType < StandardError
20
+ def initialize(klazz = nil)
21
+ return complete_message(klazz) if klazz
22
+ default_message
23
+ end
24
+
25
+ private
26
+
27
+ def default_message
28
+ "Wrong type of payload provided."
29
+ end
30
+
31
+ def complete_message(klazz)
32
+ "Wrong type of payload provided. Hash is accepted, #{klazz} was given."
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ module IonicNotification
2
+ class Logger
3
+ def no_device_tokens(instance)
4
+ return unless available?
5
+ ionic_logger "#{logger_label} No device tokens were found for #{instance}, skipping."
6
+ end
7
+
8
+ def missing_device_tokens
9
+ return unless available?
10
+ ionic_logger "#{logger_label} This model does not respond to :device_tokens, did you run your migrations?"
11
+ end
12
+
13
+ def empty_message
14
+ return unless available?
15
+ ionic_logger "#{logger_label} WARNING! You tried to send a notification with empty message, but you wisely chose not to allow this practice."
16
+ end
17
+
18
+ def logger_label
19
+ "IonicNotification:"
20
+ end
21
+
22
+ private
23
+
24
+ def ionic_logger(message)
25
+ Rails.logger.send(IonicNotification.log_level, message)
26
+ nil
27
+ end
28
+
29
+ def available_log_levels
30
+ [:debug, :info, :warn, :error, :fatal, :unknown]
31
+ end
32
+
33
+ def available?
34
+ if available_log_levels.include? IonicNotification.log_level
35
+ true
36
+ else
37
+ Rails.logger.fatal "#{logger_label} The specified log level is not available!"
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,82 @@
1
+ module IonicNotification
2
+ class Notification
3
+ attr_accessor :tokens, :title, :message, :android_payload,
4
+ :ios_payload, :production, :scheduled
5
+
6
+ def initialize(options = {})
7
+ @message_provided = options[:message]
8
+
9
+ @tokens = init_tokens(options[:tokens])
10
+ @title ||= options[:title] || default_title
11
+ @message ||= options[:message] || default_message
12
+
13
+ if options[:android_payload]
14
+ @android_payload ||= assign_payload(options[:android_payload])
15
+ end
16
+
17
+ if options[:ios_payload]
18
+ @ios_payload ||= assign_payload(options[:ios_payload])
19
+ end
20
+
21
+ if options[:payload]
22
+ @android_payload ||= assign_payload(options[:payload])
23
+ @ios_payload ||= assign_payload(options[:payload])
24
+ end
25
+
26
+ @android_payload ||= default_payload
27
+ @ios_payload ||= default_payload
28
+
29
+ @scheduled = options[:scheduled]
30
+
31
+ @production = options[:production] || init_production
32
+ end
33
+
34
+ def send
35
+ if @message_provided || IonicNotification.process_empty_messages
36
+ service = PushService.new self
37
+ service.notify!
38
+ else
39
+ self.class.new_logger.empty_message
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def self.new_logger
46
+ IonicNotification::Logger.new
47
+ end
48
+
49
+ def init_tokens(tokens)
50
+ case tokens
51
+ when Array
52
+ tokens
53
+ when String
54
+ [tokens]
55
+ else
56
+ raise IonicNotification::WrongTokenType.new(tokens.class)
57
+ end
58
+ end
59
+
60
+ def default_title
61
+ IonicNotification.ionic_app_name
62
+ end
63
+
64
+ def default_message
65
+ IonicNotification.default_message
66
+ end
67
+
68
+ def default_payload
69
+ { payload: {} }
70
+ end
71
+
72
+ def init_production
73
+ IonicNotification.ionic_app_in_production || false
74
+ end
75
+
76
+ def assign_payload(payload)
77
+ return default_payload unless payload
78
+ return { payload: payload } if payload.is_a? Hash
79
+ raise IonicNotification::WrongPayloadType.new(payload.class)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,62 @@
1
+ module IonicNotification
2
+ class PushService
3
+ include HTTParty
4
+ base_uri IonicNotification.ionic_api_url
5
+
6
+ attr_accessor :body
7
+
8
+ def initialize(notification)
9
+ @notification = notification
10
+ end
11
+
12
+ def notify!
13
+ resp = self.class.post("/api/v1/push", payload)
14
+ IonicNotification.store(sent_notification(resp))
15
+ end
16
+
17
+ def payload
18
+ options = {}
19
+ options.merge!(body: body).
20
+ merge!(basic_auth: auth).
21
+ merge!(headers: headers)
22
+ end
23
+
24
+ private
25
+
26
+ def sent_notification(resp)
27
+ IonicNotification::SentNotification.new(
28
+ tokens: @notification.tokens,
29
+ production: @notification.production,
30
+ title: @notification.title,
31
+ message: @notification.message,
32
+ android_payload: @notification.android_payload,
33
+ ios_payload: @notification.ios_payload,
34
+ scheduled: @notification.scheduled,
35
+ result: resp["result"],
36
+ message_id: resp["message_id"]
37
+ )
38
+ end
39
+
40
+ def body
41
+ {
42
+ tokens: @notification.tokens,
43
+ scheduled: @notification.scheduled,
44
+ production: @notification.production,
45
+ notification: {
46
+ title: @notification.title,
47
+ alert: @notification.message,
48
+ android: @notification.android_payload,
49
+ ios: @notification.ios_payload
50
+ }
51
+ }.to_json
52
+ end
53
+
54
+ def auth
55
+ { username: IonicNotification.ionic_api_key }
56
+ end
57
+
58
+ def headers
59
+ { 'Content-Type' => 'application/json', 'X-Ionic-Application-Id' => IonicNotification.ionic_application_id }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ module IonicNotification
2
+ class SentNotification
3
+ attr_accessor :tokens, :title, :message, :android_payload,
4
+ :ios_payload, :production, :result, :message_id, :sent_at
5
+
6
+ def initialize(options = {})
7
+ @tokens = options[:tokens]
8
+ @title = options[:title]
9
+ @message = options[:message]
10
+ @android_payload = options[:android_payload]
11
+ @ios_payload = options[:ios_payload]
12
+ @production = options[:production]
13
+ @result = options[:result]
14
+ @message_id = options[:message_id]
15
+ @sent_at = Time.now
16
+ @scheduled = init_scheduled(options[:scheduled])
17
+ end
18
+
19
+ def status
20
+ service = StatusService.new @message_id
21
+ service.check_status!
22
+ end
23
+
24
+ private
25
+
26
+ def init_scheduled(timestamp)
27
+ return DateTime.strptime(timestamp.to_s,'%s') if timestamp
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ module IonicNotification
2
+ class StatusService
3
+ include HTTParty
4
+ base_uri IonicNotification.ionic_api_url
5
+
6
+ attr_accessor :body
7
+
8
+ def initialize(message_id)
9
+ @message_id = message_id
10
+ end
11
+
12
+ def check_status!
13
+ self.class.get("/api/v1/status/#{@message_id}", payload)
14
+ end
15
+
16
+ def payload
17
+ options = {}
18
+ options.
19
+ merge!(basic_auth: auth).
20
+ merge!(headers: headers)
21
+ end
22
+
23
+ private
24
+
25
+ def auth
26
+ { username: IonicNotification.ionic_api_key }
27
+ end
28
+
29
+ def headers
30
+ { 'Content-Type' => 'application/json', 'X-Ionic-Application-Id' => IonicNotification.ionic_application_id }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module IonicNotification
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ionic_push do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ionic_notification
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Francesco Renzi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-08 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: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.13.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.13.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Interface built for Rails to use Ionic.io Push Notification service
56
+ email:
57
+ - rentziass@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - MIT-LICENSE
63
+ - Rakefile
64
+ - lib/generators/ionic_notification/install/install_generator.rb
65
+ - lib/generators/ionic_notification/install/templates/ionic_notification.rb
66
+ - lib/generators/ionic_notification/model/model_generator.rb
67
+ - lib/generators/ionic_notification/model/templates/migration.rb
68
+ - lib/generators/ionic_notification/orm_helpers.rb
69
+ - lib/ionic_notification.rb
70
+ - lib/ionic_notification/concerns/ionic_notificable.rb
71
+ - lib/ionic_notification/exceptions.rb
72
+ - lib/ionic_notification/logger.rb
73
+ - lib/ionic_notification/notification.rb
74
+ - lib/ionic_notification/push_service.rb
75
+ - lib/ionic_notification/sent_notification.rb
76
+ - lib/ionic_notification/status_service.rb
77
+ - lib/ionic_notification/version.rb
78
+ - lib/tasks/ionic_notification_tasks.rake
79
+ homepage: https://github.com/rentziass/ionic_notification
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.4.5.1
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Simple interface to use Ionic.io Push Notification service
103
+ test_files: []