abstract_notifier 0.1.1 → 0.2.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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +42 -8
- data/lib/abstract_notifier/base.rb +77 -5
- data/lib/abstract_notifier/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a36463d0a1ed93c6f48229bed9135f6c1ec3e301c76dc5b9edcc28f19d75cc3e
|
4
|
+
data.tar.gz: 7c56ec837be932967f22c592018b2210912fb2e53a40e5b8526b619dff70c4b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a191cf257f1691d8df1b395ed14610246e2ae8614bde594abd359fea8104fe3c903a9332060545563e289652b45716d76c89d2f763a8bd0c911d305641c594d
|
7
|
+
data.tar.gz: 888f89197efafc92cbbfffc220959c449fcd405c8fea6932ab3f1dde4ed4f1d726e2c19ce4c43e68ca2021a8cc040a53831506c05a5272ce7f43330e4b054364
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Abstract Notifier is a tool which allows you to describe/model any text-based notifications (such as Push Notifications) the same way Action Mailer does for email notifications.
|
7
7
|
|
8
|
-
Abstract Notifier (as the name states) doesn't provide any specific
|
8
|
+
Abstract Notifier (as the name states) doesn't provide any specific implementation for sending notifications. Instead, it offers tools to organize your notification-specific code and make it easily testable.
|
9
9
|
|
10
10
|
<a href="https://evilmartians.com/?utm_source=action_policy">
|
11
11
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
@@ -31,7 +31,7 @@ $ bundle
|
|
31
31
|
|
32
32
|
## Usage
|
33
33
|
|
34
|
-
|
34
|
+
Notifier class is very similar to Action Mailer mailer class with `notification` method instead of a `mail` method:
|
35
35
|
|
36
36
|
```ruby
|
37
37
|
class EventsNotifier < ApplicationNotifier
|
@@ -60,7 +60,7 @@ class ApplicationNotifier < AbstractNotifier::Base
|
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
-
|
63
|
+
A driver could be any callable Ruby object (i.e., anything that responds to `#call`).
|
64
64
|
|
65
65
|
That's a developer responsibility to implement the driver (we do not provide any drivers out-of-the-box; at least yet).
|
66
66
|
|
@@ -83,13 +83,47 @@ end
|
|
83
83
|
EventsNotifier.with(profile: profile).canceled(event).notify_later
|
84
84
|
```
|
85
85
|
|
86
|
+
### Defaults
|
87
|
+
|
88
|
+
You can specify default notification fields at a class level:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class EventsNotifier < ApplicationNotifier
|
92
|
+
# `category` field will be added to the notification
|
93
|
+
# if missing
|
94
|
+
default category: "EVENTS"
|
95
|
+
|
96
|
+
# ...
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
**NOTE**: when subclassing notifiers, default parameters are merged.
|
101
|
+
|
102
|
+
You can also specify a block or a method name as the default params _generator_.
|
103
|
+
This could be useful in combination with the `#notification_name` method to generate dynamic payloads:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class ApplicationNotifier < AbstractNofitier::Base
|
107
|
+
default :build_defaults_from_locale
|
108
|
+
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def build_defaults_from_locale
|
113
|
+
{
|
114
|
+
subject: I18n.t(notification_name, scope: [:notifiers, self.class.name.underscore])
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
86
120
|
### Background jobs / async notifications
|
87
121
|
|
88
122
|
To use `notify_later` you **must** configure `async_adapter`.
|
89
123
|
|
90
124
|
We provide Active Job adapter out-of-the-box and use it if Active Job is present.
|
91
125
|
|
92
|
-
|
126
|
+
The custom async adapter must implement `enqueue` method:
|
93
127
|
|
94
128
|
```ruby
|
95
129
|
class MyAsyncAdapter
|
@@ -99,7 +133,7 @@ class MyAsyncAdapter
|
|
99
133
|
|
100
134
|
# `enqueue` method accepts notifier class and notification
|
101
135
|
# payload.
|
102
|
-
# We need to know notifier class to use
|
136
|
+
# We need to know notifier class to use its driver.
|
103
137
|
def enqueue(notifier_class, payload)
|
104
138
|
# your implementation here
|
105
139
|
end
|
@@ -159,7 +193,7 @@ expect { EventsNotifier.with(profile: profile).canceled(event).notify_later}.
|
|
159
193
|
|
160
194
|
### [`active_delivery`](https://github.com/palkan/active_delivery)
|
161
195
|
|
162
|
-
Active Delivery is the next-level abstraction which allows
|
196
|
+
Active Delivery is the next-level abstraction which allows combining multiple notification channels in one place.
|
163
197
|
|
164
198
|
Abstract Notifier provides a _notifier_ line for Active Delivery:
|
165
199
|
|
@@ -169,11 +203,11 @@ class ApplicationDelivery < ActiveDelivery::Base
|
|
169
203
|
register_line :notifier, ActiveDelivery::Lines::Notifier,
|
170
204
|
# you may provide a resolver, which infers notifier class
|
171
205
|
# from delivery name (resolver is a callable).
|
172
|
-
|
206
|
+
resolver: ->(name) { resolve_somehow(name) }
|
173
207
|
end
|
174
208
|
```
|
175
209
|
|
176
|
-
**NOTE:** we automatically add `:notifier` line with `"*Delivery" -> *Notifier` resolution mechanism if `#safe_constantize` method is defined for String, i.e
|
210
|
+
**NOTE:** we automatically add `:notifier` line with `"*Delivery" -> *Notifier` resolution mechanism if `#safe_constantize` method is defined for String, i.e., you don't have to configure the default notifier line when running Rails.
|
177
211
|
|
178
212
|
## Contributing
|
179
213
|
|
@@ -25,9 +25,26 @@ module AbstractNotifier
|
|
25
25
|
|
26
26
|
# Base class for notifiers
|
27
27
|
class Base
|
28
|
-
class
|
29
|
-
|
28
|
+
class ParamsProxy
|
29
|
+
attr_reader :notifier_class, :params
|
30
|
+
|
31
|
+
def initialize(notifier_class, params)
|
32
|
+
@notifier_class = notifier_class
|
33
|
+
@params = params
|
34
|
+
end
|
35
|
+
|
36
|
+
# rubocop:disable Style/MethodMissingSuper
|
37
|
+
def method_missing(method_name, *args)
|
38
|
+
notifier_class.new(method_name, params).public_send(method_name, *args)
|
39
|
+
end
|
40
|
+
# rubocop:enable Style/MethodMissingSuper
|
41
|
+
|
42
|
+
def respond_to_missing?(*args)
|
43
|
+
notifier_class.respond_to_missing?(*args)
|
44
|
+
end
|
45
|
+
end
|
30
46
|
|
47
|
+
class << self
|
31
48
|
attr_writer :driver
|
32
49
|
|
33
50
|
def driver
|
@@ -58,14 +75,51 @@ module AbstractNotifier
|
|
58
75
|
end
|
59
76
|
end
|
60
77
|
|
78
|
+
def default(method_name = nil, **hargs)
|
79
|
+
return @defaults_generator = Proc.new if block_given?
|
80
|
+
|
81
|
+
return @defaults_generator = proc { send(method_name) } unless method_name.nil?
|
82
|
+
|
83
|
+
@default_params =
|
84
|
+
if superclass.respond_to?(:default_params)
|
85
|
+
superclass.default_params.merge(hargs).freeze
|
86
|
+
else
|
87
|
+
hargs.freeze
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def defaults_generator
|
92
|
+
return @defaults_generator if instance_variable_defined?(:@defaults_generator)
|
93
|
+
|
94
|
+
@defaults_generator =
|
95
|
+
if superclass.respond_to?(:defaults_generator)
|
96
|
+
superclass.defaults_generator
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def default_params
|
101
|
+
return @default_params if instance_variable_defined?(:@default_params)
|
102
|
+
|
103
|
+
@default_params =
|
104
|
+
if superclass.respond_to?(:default_params)
|
105
|
+
superclass.default_params.dup
|
106
|
+
else
|
107
|
+
{}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
61
111
|
def method_missing(method_name, *args)
|
62
112
|
if action_methods.include?(method_name.to_s)
|
63
|
-
new.public_send(method_name, *args)
|
113
|
+
new(method_name).public_send(method_name, *args)
|
64
114
|
else
|
65
115
|
super
|
66
116
|
end
|
67
117
|
end
|
68
118
|
|
119
|
+
def with(params)
|
120
|
+
ParamsProxy.new(self, params)
|
121
|
+
end
|
122
|
+
|
69
123
|
def respond_to_missing?(method_name, _include_private = false)
|
70
124
|
action_methods.include?(method_name.to_s) || super
|
71
125
|
end
|
@@ -87,16 +141,34 @@ module AbstractNotifier
|
|
87
141
|
end
|
88
142
|
end
|
89
143
|
|
90
|
-
attr_reader :params
|
144
|
+
attr_reader :params, :notification_name
|
91
145
|
|
92
|
-
def initialize(**params)
|
146
|
+
def initialize(notification_name, **params)
|
147
|
+
@notification_name = notification_name
|
93
148
|
@params = params.freeze
|
94
149
|
end
|
95
150
|
|
96
151
|
def notification(**payload)
|
152
|
+
merge_defaults!(payload)
|
153
|
+
|
97
154
|
raise ArgumentError, "Notification body must be present" if
|
98
155
|
payload[:body].nil? || payload[:body].empty?
|
99
156
|
Notification.new(self.class, payload)
|
100
157
|
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def merge_defaults!(payload)
|
162
|
+
defaults =
|
163
|
+
if self.class.defaults_generator
|
164
|
+
instance_exec(&self.class.defaults_generator)
|
165
|
+
else
|
166
|
+
self.class.default_params
|
167
|
+
end
|
168
|
+
|
169
|
+
defaults.each do |k, v|
|
170
|
+
payload[k] = v unless payload.key?(k)
|
171
|
+
end
|
172
|
+
end
|
101
173
|
end
|
102
174
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstract_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_delivery
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- ".rspec"
|
92
92
|
- ".rubocop.yml"
|
93
93
|
- ".travis.yml"
|
94
|
+
- CHANGELOG.md
|
94
95
|
- Gemfile
|
95
96
|
- LICENSE.txt
|
96
97
|
- README.md
|
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
129
|
version: '0'
|
129
130
|
requirements: []
|
130
131
|
rubyforge_project:
|
131
|
-
rubygems_version: 2.7.
|
132
|
+
rubygems_version: 2.7.6
|
132
133
|
signing_key:
|
133
134
|
specification_version: 4
|
134
135
|
summary: ActionMailer-like interface for any type of notifications
|