notification_manager 0.1.1 → 0.1.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e376c2270a096ff8d19676ce7487dfb9740acc3659ed7a41c789ce32417b3dd3
|
|
4
|
+
data.tar.gz: 17b18422bc6b2f193e53796d25d9dd5eccb8b5644641bbabb2dda30dde404d49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0749cbc681d8526d3f7a593aaf4b9f62323a60cd1880792c269a14b8ff9d6b488fad3a6b665d0b3999752744a3e89412f1c33f2e11494cf95b562cc37d1197ee'
|
|
7
|
+
data.tar.gz: acb945c0b0a496740a79535e97b315a91df1ff6a795ed6c2427bcf5e5c6414038591d8daa4ed641068b76773e90d3a88c74eba37876c8dcb684dd4646f3aaf4d
|
data/README.md
CHANGED
|
@@ -1,31 +1,288 @@
|
|
|
1
1
|
# NotificationManager
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A flexible notification management system for Rails applications that automatically triggers notifications based on ActiveRecord model lifecycle events and attribute changes.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 🔔 Trigger notifications on model lifecycle events (create, update, destroy)
|
|
8
|
+
- 🎯 Trigger notifications based on attribute status changes
|
|
9
|
+
- 🏷️ Tag-based notification clearing to prevent duplicate notifications
|
|
10
|
+
- 👥 Support for multiple recipients per notification
|
|
11
|
+
- 🔄 Polymorphic notification system supporting any notifiable model
|
|
12
|
+
- ⏭️ Conditional notification skipping
|
|
13
|
+
- 🎨 Extensible architecture with customizable notification managers
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Ruby >= 3.2.0
|
|
18
|
+
- Rails >= 6.1
|
|
8
19
|
|
|
9
|
-
|
|
20
|
+
## Installation
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
Add this line to your application's Gemfile:
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
```ruby
|
|
25
|
+
gem 'notification_manager'
|
|
26
|
+
```
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
And then execute:
|
|
16
29
|
|
|
17
|
-
|
|
30
|
+
```bash
|
|
31
|
+
$ bundle install
|
|
32
|
+
```
|
|
18
33
|
|
|
19
34
|
## Usage
|
|
20
35
|
|
|
21
|
-
|
|
36
|
+
### 1. Generate the Notification Model
|
|
37
|
+
|
|
38
|
+
First, generate the notification model and migration:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
$ rails generate notification_manager:notifications
|
|
42
|
+
$ rails db:migrate
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This creates:
|
|
46
|
+
- `app/models/notification.rb` - The Notification model
|
|
47
|
+
- `db/migrate/[timestamp]_create_notifications.rb` - The database migration
|
|
48
|
+
|
|
49
|
+
The notifications table includes:
|
|
50
|
+
- `user_id` - Reference to the user receiving the notification
|
|
51
|
+
- `notifiable` - Polymorphic reference to any notifiable model
|
|
52
|
+
- `description` - Notification message
|
|
53
|
+
- `link` - Optional link for the notification
|
|
54
|
+
- `tag` - Tag for grouping/clearing related notifications
|
|
55
|
+
- `opened` - Boolean flag to track read/unread status
|
|
56
|
+
|
|
57
|
+
### 2. Include the Notifiable Concern
|
|
58
|
+
|
|
59
|
+
Add the `ActiveRecordNotifiable` concern to any model you want to send notifications from:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
class Order < ApplicationRecord
|
|
63
|
+
include NotificationManager::NotificationSources::ActiveRecordNotifiable
|
|
64
|
+
|
|
65
|
+
# Your model code...
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This adds an `after_commit` callback that automatically triggers notifications based on your notification manager configuration.
|
|
70
|
+
|
|
71
|
+
### 3. Create a Notification Manager
|
|
72
|
+
|
|
73
|
+
Create a notification manager class for your notifiable model. The class name should follow the pattern `[ModelName]NotificationManager`:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# app/notification_managers/order_notification_manager.rb
|
|
77
|
+
class OrderNotificationManager < NotificationManager::NotificationManagers::Base
|
|
78
|
+
def notification_steps
|
|
79
|
+
[
|
|
80
|
+
order_created_notification,
|
|
81
|
+
order_shipped_notification,
|
|
82
|
+
order_delivered_notification
|
|
83
|
+
]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def order_created_notification
|
|
89
|
+
NotificationManager::NotificationDefinitions::Base.new(
|
|
90
|
+
lifecycle_triggers: [:created],
|
|
91
|
+
status_triggers: [],
|
|
92
|
+
notification_tags_to_clear: [],
|
|
93
|
+
notifications_to_send: [
|
|
94
|
+
{
|
|
95
|
+
recipients: :seller_recipient,
|
|
96
|
+
notification: :send_order_created_notification
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def order_shipped_notification
|
|
103
|
+
NotificationManager::NotificationDefinitions::Base.new(
|
|
104
|
+
lifecycle_triggers: [:updated],
|
|
105
|
+
status_triggers: [
|
|
106
|
+
{
|
|
107
|
+
attr: :status,
|
|
108
|
+
triggers: -> { ['shipped'] }
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
notification_tags_to_clear: ['order_pending'],
|
|
112
|
+
notifications_to_send: [
|
|
113
|
+
{
|
|
114
|
+
recipients: :buyer_recipient,
|
|
115
|
+
notification: :send_order_shipped_notification
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def order_delivered_notification
|
|
122
|
+
NotificationManager::NotificationDefinitions::Base.new(
|
|
123
|
+
lifecycle_triggers: [:updated],
|
|
124
|
+
status_triggers: [
|
|
125
|
+
{
|
|
126
|
+
attr: :status,
|
|
127
|
+
triggers: -> { ['delivered'] }
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
notification_tags_to_clear: ['order_shipped'],
|
|
131
|
+
notifications_to_send: [
|
|
132
|
+
{
|
|
133
|
+
recipients: :buyer_recipient,
|
|
134
|
+
notification: :send_order_delivered_notification
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Recipient methods return arrays of users
|
|
141
|
+
def seller_recipient
|
|
142
|
+
[notifiable.seller]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def buyer_recipient
|
|
146
|
+
[notifiable.buyer]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Notification sender methods
|
|
150
|
+
def send_order_created_notification(order, recipient)
|
|
151
|
+
Notification.create!(
|
|
152
|
+
user: recipient,
|
|
153
|
+
notifiable: order,
|
|
154
|
+
description: "New order ##{order.id} received",
|
|
155
|
+
link: "/orders/#{order.id}",
|
|
156
|
+
tag: 'order_created'
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def send_order_shipped_notification(order, recipient)
|
|
161
|
+
Notification.create!(
|
|
162
|
+
user: recipient,
|
|
163
|
+
notifiable: order,
|
|
164
|
+
description: "Your order ##{order.id} has been shipped",
|
|
165
|
+
link: "/orders/#{order.id}",
|
|
166
|
+
tag: 'order_shipped'
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def send_order_delivered_notification(order, recipient)
|
|
171
|
+
Notification.create!(
|
|
172
|
+
user: recipient,
|
|
173
|
+
notifiable: order,
|
|
174
|
+
description: "Your order ##{order.id} has been delivered",
|
|
175
|
+
link: "/orders/#{order.id}",
|
|
176
|
+
tag: 'order_delivered'
|
|
177
|
+
)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 4. Notification Definition Options
|
|
183
|
+
|
|
184
|
+
Each notification definition accepts the following options:
|
|
185
|
+
|
|
186
|
+
#### `lifecycle_triggers` (Array)
|
|
187
|
+
Specifies which lifecycle events should trigger the notification:
|
|
188
|
+
- `:created` - Triggers when the record is created
|
|
189
|
+
- `:updated` - Triggers when the record is updated
|
|
190
|
+
- `:destroyed` - Triggers when the record is destroyed
|
|
191
|
+
|
|
192
|
+
#### `status_triggers` (Array of Hashes)
|
|
193
|
+
Defines attribute-based conditions for triggering notifications:
|
|
194
|
+
```ruby
|
|
195
|
+
status_triggers: [
|
|
196
|
+
{
|
|
197
|
+
attr: :status, # The attribute to watch
|
|
198
|
+
triggers: -> { ['value'] } # Lambda returning array of trigger values
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Use `-> { '*' }` to trigger on any change to the attribute.
|
|
204
|
+
|
|
205
|
+
#### `notification_tags_to_clear` (Array)
|
|
206
|
+
Array of notification tags to clear before sending new notifications. This prevents duplicate or outdated notifications:
|
|
207
|
+
```ruby
|
|
208
|
+
notification_tags_to_clear: ['order_pending', 'order_processing']
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### `notifications_to_send` (Array of Hashes)
|
|
212
|
+
Defines which notifications to send:
|
|
213
|
+
```ruby
|
|
214
|
+
notifications_to_send: [
|
|
215
|
+
{
|
|
216
|
+
recipients: :method_name, # Method that returns array of users
|
|
217
|
+
notification: :method_name # Method that creates the notification
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 5. Skipping Notifications
|
|
223
|
+
|
|
224
|
+
You can temporarily skip notifications for a specific operation:
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
order = Order.new(...)
|
|
228
|
+
order.skip_notifications = true
|
|
229
|
+
order.save
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Advanced Examples
|
|
233
|
+
|
|
234
|
+
### Multiple Recipients
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
def admin_recipients
|
|
238
|
+
User.where(role: 'admin').to_a
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def stakeholder_recipients
|
|
242
|
+
[notifiable.owner, notifiable.manager].compact
|
|
243
|
+
end
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Conditional Status Triggers
|
|
247
|
+
|
|
248
|
+
```ruby
|
|
249
|
+
status_triggers: [
|
|
250
|
+
{
|
|
251
|
+
attr: :priority,
|
|
252
|
+
triggers: -> { ['high', 'critical'] }
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
attr: :assigned_to_id,
|
|
256
|
+
triggers: -> { '*' } # Trigger on any assignment change
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Chaining Notifications
|
|
262
|
+
|
|
263
|
+
Clear previous notifications when sending new ones to maintain a clean notification state:
|
|
264
|
+
|
|
265
|
+
```ruby
|
|
266
|
+
NotificationManager::NotificationDefinitions::Base.new(
|
|
267
|
+
lifecycle_triggers: [:updated],
|
|
268
|
+
status_triggers: [{ attr: :status, triggers: -> { ['completed'] } }],
|
|
269
|
+
notification_tags_to_clear: ['task_pending', 'task_in_progress'],
|
|
270
|
+
notifications_to_send: [
|
|
271
|
+
{ recipients: :task_owner, notification: :send_completion_notification }
|
|
272
|
+
]
|
|
273
|
+
)
|
|
274
|
+
```
|
|
22
275
|
|
|
23
276
|
## Development
|
|
24
277
|
|
|
25
278
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
26
279
|
|
|
27
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
280
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
28
281
|
|
|
29
282
|
## Contributing
|
|
30
283
|
|
|
31
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
284
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/CodeTectonics/notification-manager. This project is intended to be a safe, welcoming space for collaboration.
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
@@ -10,6 +10,7 @@ module NotificationManager
|
|
|
10
10
|
|
|
11
11
|
def send_notifications
|
|
12
12
|
return if skip_notifications
|
|
13
|
+
return if notification_manager_class_name.nil?
|
|
13
14
|
|
|
14
15
|
notification_manager = notification_manager_class_name.constantize.new(self)
|
|
15
16
|
notification_manager.run_notification_flow
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: notification_manager
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mark Harbison
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|