Skip to content

Commit

Permalink
[#53] Add an ActionMailer notification-pusher that lets you use exist…
Browse files Browse the repository at this point in the history
…ing mailers and templates (#101)

* [#53] Add an ActionMailer notification-pusher that lets you use existing mailers and templates

* fix travis
  • Loading branch information
jonhue authored and probot-auto-merge[bot] committed Jun 1, 2019
1 parent 7cc892e commit 3c3d719
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Notifications Rails follows Semantic Versioning 2.0 as defined at http://semver.

* All used statuses & notification categories must now be configured in the NotificationSettings initializer. [#38] (#95)

* When using the ActionMailer delivery method with NotificationRenderer, `'notification-renderer'` must be required explicitly. Otherwise the delivery method expects `:mailer` and `:action` options that specify a custom mailer. [#53] (#101)

### Deprecated

* None
23 changes: 21 additions & 2 deletions notification-pusher/notification-pusher-actionmailer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ NotificationPusher.configure do |config|
end
```

You can pass a `from` parameter, which will override the default email address specified in `ApplicationMailer`:
You can pass a `from` parameter, which will be used if you don't provide a `from` address when delivering:

```ruby
NotificationPusher.configure do |config|
Expand All @@ -58,6 +58,8 @@ Then add a renderer called `_actionmailer.html.erb` to every notification type y
Now you can deliver your notifications:

```ruby
require 'notification-renderer'

notification = Notification.create(target: User.first, object: Recipe.first)
notification.deliver(:email, to: 'another@email.com')
```
Expand All @@ -66,16 +68,33 @@ notification.deliver(:email, to: 'another@email.com')

It is also possible to override the email address sending this notification, by passing a `from` parameter.

If you don't want to use [NotificationRenderer](https://github.com/jonhue/notifications-rails/tree/master/notification-renderer):

```ruby
notification = Notification.create(target: User.first, object: Recipe.first)
notification.deliver(:email, to: 'another@email.com', mailer: MyCustomMailer, action: :deliver_notification)
```

`MyCustomMailer.deliver_notification` is then called with a `notification` as first argument and an options hash as second argument.

### Options

**`to`** Receiver email address. Takes a string.

**`from`** Sender email address. Takes a string. Defaults to email specified in `ApplicationMailer`.
**`from`** Sender email address. Takes a string.

**`renderer`** Specify a renderer. Takes a string. Defaults to `'actionmailer'`.

**`layout`** Layout used for template rendering. Takes a string. Defaults to layout specified in `ApplicationMailer`.

**`mail_options`** A hash that is passed to `mail` (e.g. including `:subject`). Takes a hash. Defaults to `{}`.

**`mailer`** ActionMailer class. Takes a constant. Defaults to `NotificationPusher::ActionMailer::NotificationMailer`.

**`action`** ActionMailer action. Takes a symbol. Defaults to `:push`.

**`deliver_method`** ActionMailer deliver_method (e.g. `:deliver_later`). Takes a symbol. Defaults to `:deliver`.

---

## To Do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
module NotificationPusher
class ActionMailer
class NotificationMailer < ApplicationMailer
# rubocop:disable Metrics/ParameterLists
def push(notification,
from:, to: nil, renderer: 'actionmailer', layout: nil)
from:, to: nil, renderer: 'actionmailer', layout: nil,
mail_options: {})
render(layout: layout) unless layout.nil?

@notification = notification
@renderer = renderer
mail(to: to || notification.target.email, from: from)

mail({
to: to || notification.target.email,
from: from
}.merge(mail_options))
end
# rubocop:enable Metrics/ParameterLists
end
end
end
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
# frozen_string_literal: true

require 'notification-renderer'

module NotificationPusher
module DeliveryMethod
class ActionMailer < NotificationPusher::DeliveryMethod::Base
require_relative 'action_mailer/engine'

DEFAULT_MAILER_ACTION = :push
DEFAULT_DELIVER_METHOD = :deliver

def call
::NotificationPusher::ActionMailer::NotificationMailer.push(
notification, options
).deliver
mailer_class.send(mailer_action, notification, options)
.send(deliver_method)
end

private

def mailer_class
return options[:mailer] if options.key?(:mailer)
if defined?(NotificationRenderer)
return ::NotificationPusher::ActionMailer::NotificationMailer
end

raise(ArgumentError,
'You have to pass the :mailer option explicitly or require ' \
"'notification-renderer'")
end

def mailer_action
options[:action] || DEFAULT_MAILER_ACTION
end

def deliver_method
options[:deliver_method] || DEFAULT_DELIVER_METHOD
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ Gem::Specification.new do |gem|

gem.add_dependency 'actionmailer', '>= 5.0'
gem.add_dependency 'notification-pusher', version
gem.add_dependency 'notification-renderer', version
gem.add_dependency 'railties', '>= 5.0'

gem.add_development_dependency 'factory_bot'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# rubocop:disable RSpec/DescribedClass
expect(defined?(NotificationPusher)).to eq 'constant'
# rubocop:enable RSpec/DescribedClass
expect(defined?(NotificationRenderer)).to eq 'constant'
expect(defined?(NotificationRenderer)).to eq nil
expect(defined?(NotificationSettings)).to eq nil
end
end
Expand Down
2 changes: 1 addition & 1 deletion notification-renderer/app/helpers/notification_renderer_helper.rb
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def render_notification(notification,

def render_notifications(notifications, renderer: default_renderer)
content_tag :div, class: 'notification-renderer notifications' do
notifications&.each do |notification|
notifications&.map do |notification|
render_notification(notification, renderer: renderer)
end
end
Expand Down

0 comments on commit 3c3d719

Please sign in to comment.