pushing 0.1.0
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 +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +28 -0
- data/Appraisals +29 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +21 -0
- data/README.md +225 -0
- data/Rakefile +22 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/certs/apns_example_production.pem.enc +0 -0
- data/gemfiles/rails_42.gemfile +17 -0
- data/gemfiles/rails_50.gemfile +17 -0
- data/gemfiles/rails_51.gemfile +17 -0
- data/gemfiles/rails_edge.gemfile +20 -0
- data/lib/generators/pushing/USAGE +14 -0
- data/lib/generators/pushing/notifier_generator.rb +46 -0
- data/lib/generators/pushing/templates/application_notifier.rb +4 -0
- data/lib/generators/pushing/templates/initializer.rb +10 -0
- data/lib/generators/pushing/templates/notifier.rb +11 -0
- data/lib/generators/pushing/templates/template.json+apn.jbuilder +53 -0
- data/lib/generators/pushing/templates/template.json+fcm.jbuilder +75 -0
- data/lib/pushing.rb +16 -0
- data/lib/pushing/adapters.rb +43 -0
- data/lib/pushing/adapters/apn/apnotic_adapter.rb +86 -0
- data/lib/pushing/adapters/apn/houston_adapter.rb +33 -0
- data/lib/pushing/adapters/apn/lowdown_adapter.rb +70 -0
- data/lib/pushing/adapters/fcm/andpush_adapter.rb +47 -0
- data/lib/pushing/adapters/fcm/fcm_gem_adapter.rb +52 -0
- data/lib/pushing/adapters/test_adapter.rb +37 -0
- data/lib/pushing/base.rb +187 -0
- data/lib/pushing/delivery_job.rb +31 -0
- data/lib/pushing/log_subscriber.rb +44 -0
- data/lib/pushing/notification_delivery.rb +79 -0
- data/lib/pushing/platforms.rb +91 -0
- data/lib/pushing/railtie.rb +25 -0
- data/lib/pushing/rescuable.rb +28 -0
- data/lib/pushing/template_handlers.rb +15 -0
- data/lib/pushing/template_handlers/jbuilder_handler.rb +17 -0
- data/lib/pushing/version.rb +3 -0
- data/pushing.gemspec +30 -0
- metadata +211 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
require "active_support/log_subscriber"
|
2
|
+
require "active_support/core_ext/string/indent"
|
3
|
+
|
4
|
+
module Pushing
|
5
|
+
# Implements the ActiveSupport::LogSubscriber for logging notifications when
|
6
|
+
# a push notification is delivered.
|
7
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
8
|
+
# A notification was delivered.
|
9
|
+
def deliver(event)
|
10
|
+
return unless logger.info?
|
11
|
+
|
12
|
+
event.payload[:notification].each do |platform, payload|
|
13
|
+
info do
|
14
|
+
recipients = payload.recipients.map {|r| r.truncate(32) }.join(", ")
|
15
|
+
" #{platform.upcase}: sent push notification to #{recipients} (#{event.duration.round(1)}ms)"
|
16
|
+
end
|
17
|
+
|
18
|
+
next unless logger.debug?
|
19
|
+
debug do
|
20
|
+
"Payload:\n#{JSON.pretty_generate(payload.payload).indent(2)}\n".indent(2)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# A notification was generated.
|
26
|
+
def process(event)
|
27
|
+
return unless logger.debug?
|
28
|
+
|
29
|
+
debug do
|
30
|
+
notifier = event.payload[:notifier]
|
31
|
+
action = event.payload[:action]
|
32
|
+
|
33
|
+
"#{notifier}##{action}: processed outbound push notification in #{event.duration.round(1)}ms"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Use the logger configured for Pushing::Base.
|
38
|
+
def logger
|
39
|
+
Pushing::Base.logger
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Pushing::LogSubscriber.attach_to :push_notification
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
module Pushing
|
4
|
+
class NotificationDelivery < Delegator
|
5
|
+
def initialize(notifier_class, action, *args) #:nodoc:
|
6
|
+
@notifier_class, @action, @args = notifier_class, action, args
|
7
|
+
|
8
|
+
# The notification is only processed if we try to call any methods on it.
|
9
|
+
# Typical usage will leave it unloaded and call deliver_later.
|
10
|
+
@processed_notifier = nil
|
11
|
+
@notification_message = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def __getobj__ #:nodoc:
|
15
|
+
@notification_message ||= processed_notifier.notification
|
16
|
+
end
|
17
|
+
|
18
|
+
# Unused except for delegator internals (dup, marshaling).
|
19
|
+
def __setobj__(notification_message) #:nodoc:
|
20
|
+
@notification_message = notification_message
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
__getobj__
|
25
|
+
end
|
26
|
+
|
27
|
+
def processed?
|
28
|
+
@processed_notifier || @notification_message
|
29
|
+
end
|
30
|
+
|
31
|
+
def deliver_later!(options = {})
|
32
|
+
enqueue_delivery :deliver_now!, options
|
33
|
+
end
|
34
|
+
|
35
|
+
def deliver_now!
|
36
|
+
processed_notifier.handle_exceptions { do_deliver }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def do_deliver
|
42
|
+
@notifier_class.inform_interceptors(self)
|
43
|
+
|
44
|
+
responses = nil
|
45
|
+
@notifier_class.deliver_notification(self) do
|
46
|
+
responses = ::Pushing::Platforms.config.map do |platform, config|
|
47
|
+
Adapters.instance(config).push!(message[platform]) if message[platform]
|
48
|
+
end.compact
|
49
|
+
end
|
50
|
+
|
51
|
+
responses.each {|response| @notifier_class.inform_observers(self, response) }
|
52
|
+
responses
|
53
|
+
end
|
54
|
+
|
55
|
+
def processed_notifier
|
56
|
+
@processed_notifier ||= begin
|
57
|
+
notifier = @notifier_class.new
|
58
|
+
notifier.process @action, *@args
|
59
|
+
notifier
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def enqueue_delivery(delivery_method, options = {})
|
64
|
+
if processed?
|
65
|
+
::Kernel.raise "You've accessed the message before asking to " \
|
66
|
+
"deliver it later, so you may have made local changes that would " \
|
67
|
+
"be silently lost if we enqueued a job to deliver it. Why? Only " \
|
68
|
+
"the notifier method *arguments* are passed with the delivery job! " \
|
69
|
+
"Do not access the message in any way if you mean to deliver it " \
|
70
|
+
"later. Workarounds: 1. don't touch the message before calling " \
|
71
|
+
"#deliver_later, 2. only touch the message *within your notifier " \
|
72
|
+
"method*, or 3. use a custom Active Job instead of #deliver_later."
|
73
|
+
else
|
74
|
+
args = @notifier_class.name, @action.to_s, delivery_method.to_s, *@args
|
75
|
+
::Pushing::DeliveryJob.set(options).perform_later(*args)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'active_support/configurable'
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
5
|
+
|
6
|
+
module Pushing
|
7
|
+
module Platforms
|
8
|
+
include ActiveSupport::Configurable
|
9
|
+
|
10
|
+
config.apn = ActiveSupport::OrderedOptions.new
|
11
|
+
config.fcm = ActiveSupport::OrderedOptions.new
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def lookup(platform_name)
|
15
|
+
const_get(:"#{platform_name.capitalize}Payload")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ApnPayload
|
20
|
+
attr_reader :payload, :device_token, :environment
|
21
|
+
|
22
|
+
EMPTY_HASH = {}.freeze
|
23
|
+
|
24
|
+
def self.should_render?(options)
|
25
|
+
options.is_a?(Hash) ? options[:device_token].present? : options.present?
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(payload, options)
|
29
|
+
if options.is_a?(String)
|
30
|
+
@device_token = options
|
31
|
+
else options.is_a?(Hash)
|
32
|
+
@device_token, @environment, @headers = options.values_at(:device_token, :environment, :headers)
|
33
|
+
end
|
34
|
+
|
35
|
+
@payload = payload
|
36
|
+
@headers ||= EMPTY_HASH
|
37
|
+
end
|
38
|
+
|
39
|
+
def recipients
|
40
|
+
Array(@device_token)
|
41
|
+
end
|
42
|
+
|
43
|
+
def headers
|
44
|
+
@normalized_headers ||= begin
|
45
|
+
h = @headers.stringify_keys.transform_keys!(&:dasherize)
|
46
|
+
|
47
|
+
{
|
48
|
+
authorization: h['authorization'],
|
49
|
+
'apns-id': h['apns-id'] || h['id'],
|
50
|
+
'apns-expiration': h['apns-expiration'] || h['expiration'],
|
51
|
+
'apns-priority': h['apns-priority'] || h['priority'],
|
52
|
+
'apns-topic': h['apns-topic'] || h['topic'],
|
53
|
+
'apns-collapse-id': h['apns-collapse-id'] || h['collapse-id'],
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class FcmPayload
|
60
|
+
attr_reader :payload
|
61
|
+
|
62
|
+
def self.should_render?(options)
|
63
|
+
options.present?
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(payload, *)
|
67
|
+
@payload = payload
|
68
|
+
end
|
69
|
+
|
70
|
+
def recipients
|
71
|
+
Array(payload[:to] || payload[:registration_ids])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class DeliveryError < RuntimeError
|
77
|
+
attr_reader :response, :notification
|
78
|
+
|
79
|
+
def initialize(message, response = nil, notification = nil)
|
80
|
+
super(message)
|
81
|
+
@response = response
|
82
|
+
@notification = notification
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class ApnDeliveryError < DeliveryError
|
87
|
+
end
|
88
|
+
|
89
|
+
class FcmDeliveryError < DeliveryError
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "active_job/railtie"
|
2
|
+
require "rails"
|
3
|
+
|
4
|
+
module Pushing
|
5
|
+
class Railtie < Rails::Railtie # :nodoc:
|
6
|
+
config.eager_load_namespaces << Pushing
|
7
|
+
|
8
|
+
initializer "pushing.logger" do
|
9
|
+
ActiveSupport.on_load(:pushing) { self.logger ||= Rails.logger }
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer "pushing.add_view_paths" do |app|
|
13
|
+
views = app.config.paths["app/views"].existent
|
14
|
+
if !views.empty?
|
15
|
+
ActiveSupport.on_load(:pushing) { prepend_view_path(views) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer "pushing.compile_config_methods" do
|
20
|
+
ActiveSupport.on_load(:pushing) do
|
21
|
+
config.compile_methods! if config.respond_to?(:compile_methods!)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support/rescuable'
|
2
|
+
|
3
|
+
module Pushing #:nodoc:
|
4
|
+
module Rescuable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include ActiveSupport::Rescuable
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def handle_exception(exception) #:nodoc:
|
10
|
+
rescue_with_handler(exception) || raise(exception)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle_exceptions #:nodoc:
|
15
|
+
yield
|
16
|
+
rescue => exception
|
17
|
+
rescue_with_handler(exception) || raise
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def process(*)
|
23
|
+
handle_exceptions do
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Pushing
|
4
|
+
module TemplateHandlers
|
5
|
+
extend ActiveSupport::Autoload
|
6
|
+
|
7
|
+
autoload :JbuilderHandler
|
8
|
+
|
9
|
+
def self.lookup(template)
|
10
|
+
const_get("#{template.to_s.camelize}Handler")
|
11
|
+
rescue NameError
|
12
|
+
raise NotImplementedError.new("The template engine `#{template}' is not yet supported.")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'jbuilder/jbuilder_template'
|
4
|
+
|
5
|
+
module Pushing
|
6
|
+
module TemplateHandlers
|
7
|
+
class JbuilderHandler < ::JbuilderHandler
|
8
|
+
def self.call(*)
|
9
|
+
super.gsub("json.target!", "json.attributes!").gsub("new(self)", "new(self, key_formatter: ::Pushing::TemplateHandlers::JbuilderHandler)")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.format(key)
|
13
|
+
key
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/pushing.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pushing/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pushing"
|
8
|
+
spec.version = Pushing::VERSION
|
9
|
+
spec.authors = ["Yuki Nishijima"]
|
10
|
+
spec.email = ["mail@yukinishijima.net"]
|
11
|
+
spec.summary = %q{Push notification framework that does not hurt. finally.}
|
12
|
+
spec.description = %q{Pushing is like ActionMailer, but for sending push notifications.}
|
13
|
+
spec.homepage = "https://github.com/yuki24/pushing"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "actionpack", ">= 4.2.0"
|
21
|
+
spec.add_dependency "actionview", ">= 4.2.0"
|
22
|
+
spec.add_dependency "activejob", ">= 4.2.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "minitest"
|
27
|
+
spec.add_development_dependency "appraisal"
|
28
|
+
spec.add_development_dependency "jbuilder"
|
29
|
+
spec.add_development_dependency "webmock"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pushing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yuki Nishijima
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.0
|
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.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionview
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activejob
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.2.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.2.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: appraisal
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: jbuilder
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Pushing is like ActionMailer, but for sending push notifications.
|
140
|
+
email:
|
141
|
+
- mail@yukinishijima.net
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".travis.yml"
|
148
|
+
- Appraisals
|
149
|
+
- CODE_OF_CONDUCT.md
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE.txt
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
- bin/console
|
155
|
+
- bin/setup
|
156
|
+
- certs/apns_example_production.pem.enc
|
157
|
+
- gemfiles/rails_42.gemfile
|
158
|
+
- gemfiles/rails_50.gemfile
|
159
|
+
- gemfiles/rails_51.gemfile
|
160
|
+
- gemfiles/rails_edge.gemfile
|
161
|
+
- lib/generators/pushing/USAGE
|
162
|
+
- lib/generators/pushing/notifier_generator.rb
|
163
|
+
- lib/generators/pushing/templates/application_notifier.rb
|
164
|
+
- lib/generators/pushing/templates/initializer.rb
|
165
|
+
- lib/generators/pushing/templates/notifier.rb
|
166
|
+
- lib/generators/pushing/templates/template.json+apn.jbuilder
|
167
|
+
- lib/generators/pushing/templates/template.json+fcm.jbuilder
|
168
|
+
- lib/pushing.rb
|
169
|
+
- lib/pushing/adapters.rb
|
170
|
+
- lib/pushing/adapters/apn/apnotic_adapter.rb
|
171
|
+
- lib/pushing/adapters/apn/houston_adapter.rb
|
172
|
+
- lib/pushing/adapters/apn/lowdown_adapter.rb
|
173
|
+
- lib/pushing/adapters/fcm/andpush_adapter.rb
|
174
|
+
- lib/pushing/adapters/fcm/fcm_gem_adapter.rb
|
175
|
+
- lib/pushing/adapters/test_adapter.rb
|
176
|
+
- lib/pushing/base.rb
|
177
|
+
- lib/pushing/delivery_job.rb
|
178
|
+
- lib/pushing/log_subscriber.rb
|
179
|
+
- lib/pushing/notification_delivery.rb
|
180
|
+
- lib/pushing/platforms.rb
|
181
|
+
- lib/pushing/railtie.rb
|
182
|
+
- lib/pushing/rescuable.rb
|
183
|
+
- lib/pushing/template_handlers.rb
|
184
|
+
- lib/pushing/template_handlers/jbuilder_handler.rb
|
185
|
+
- lib/pushing/version.rb
|
186
|
+
- pushing.gemspec
|
187
|
+
homepage: https://github.com/yuki24/pushing
|
188
|
+
licenses:
|
189
|
+
- MIT
|
190
|
+
metadata: {}
|
191
|
+
post_install_message:
|
192
|
+
rdoc_options: []
|
193
|
+
require_paths:
|
194
|
+
- lib
|
195
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
|
+
requirements:
|
202
|
+
- - ">="
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '0'
|
205
|
+
requirements: []
|
206
|
+
rubyforge_project:
|
207
|
+
rubygems_version: 2.6.11
|
208
|
+
signing_key:
|
209
|
+
specification_version: 4
|
210
|
+
summary: Push notification framework that does not hurt. finally.
|
211
|
+
test_files: []
|