excid3 / noticed

Notifications for Ruby on Rails applications
MIT License
2.44k stars 173 forks source link

[BUG] Params not being forwarded to mailer #401

Closed stlucasgarcia closed 8 months ago

stlucasgarcia commented 8 months ago

Params not being forwarded to mailer

Describe the Bug: params are not being sent to the mailer correctly. The only data that is being correctly set are :notification and static values such as:

  deliver_by :email do |config|
    config.mailer = "UserMailer"
    config.method = "new_post"
    config.params = -> { {foo: :bar} }
  end

To Reproduce:

Considering:

  1. Create a new notifier
rails generate noticed:notifier NewCommentNotifier
  1. Create user mailer
rails g mailer UserMailer
  1. Uncomment email deliver method
# new_comment_notifier.rb
# To deliver this notification:
#
# NewComment.with(record: @post, message: "New post").deliver(User.all)

class NewCommentNotifier < ApplicationNotifier
  # Add your delivery methods
  #
  deliver_by :email do |config|
    config.mailer = "UserMailer"
    config.method = "new_post"
    # config.params = ->(recipient) { {user: recipient} }  If a uncomment this code it throws ArgumentError (wrong number of arguments (given 0, expected 1))
  end
  #
  # bulk_deliver_by :slack do |config|
  #   config.url = -> { Rails.application.credentials.slack_webhook_url }
  # end
  #
  # deliver_by :custom do |config|
  #   config.class = "MyDeliveryMethod"
  # end

  # Add required params
  #
  # required_param :message
end
  1. Add new_post to UserMailer
# user_mailer.rb

class UserMailer < ApplicationMailer

  def new_post
    puts params
  end
end
  1. Run console and create a new notification
rails c
irb(main):001> NewCommentNotifier.with(record: Post.first).deliver(User.first)

Expected Behavior: The logged params object must contain the following:

{
 :notification => #<NewCommentNotifier::Notification>
 :record => #<Post>,
 :recipient => #<User>
}

Actual Behavior: Params contains only the :notification key with data, while :record and :recipient are nil

{
 :notification => #<NewCommentNotifier::Notification>
 :record => nil,
 :recipient => nil
}

Environment:

Related Issues:

365

Labels to Apply: BUG

Checklist:

excid3 commented 8 months ago

Params does not receive an argument so it should be:

config.params = ->{ {user: recipient} }
stlucasgarcia commented 8 months ago

Thanks for the quick reply @excid3

I have now the following code:

# new_comment_notifier.rb
# To deliver this notification:
#
# NewComment.with(record: @post, message: "New post").deliver(User.all)

class NewCommentNotifier < ApplicationNotifier
  # Add your delivery methods
  #
  deliver_by :email do |config|
    config.mailer = "UserMailer"
    config.method = "new_post"
    config.params = ->{ {user: recipient} }
  end
  #
  # bulk_deliver_by :slack do |config|
  #   config.url = -> { Rails.application.credentials.slack_webhook_url }
  # end
  #
  # deliver_by :custom do |config|
  #   config.class = "MyDeliveryMethod"
  # end

  # Add required params
  #
  # required_param :message
end

I made no changes to the mailer, when I create a new notification I get the following log:

{
 :user => nil,
 :notification => #<NewCommentNotifier::Notification>,
 :record => nil,
 :recipient => nil
}

Am I doing something wrong?

excid3 commented 8 months ago

Lemme check our test suite and see if I can reproduce.

excid3 commented 8 months ago

I'm not able to reproduce it. Everything is included correctly from my testing.

Screenshot 2024-02-14 at 10 24 43 AM
stlucasgarcia commented 8 months ago

It must be something on my side then. I am going to close this and keep investigating.

Thanks for the support!

excid3 commented 8 months ago

Trying to think of what else it could be. I'd check your Gemfile.lock and make sure you're on the latest. I know this was a bug in previous versions and fixed at some point.

stlucasgarcia commented 8 months ago

@excid3 I just found out what it was.

My models had id type of uuid, while I did not change the noticed migration to support uuid.

Is it worth adding a warning or error for these cases? Or have the generator to add theuuid type on the migrations if the initializer g.orm :active_record, primary_key_type: :uuid exists (just some brainstorming)

stlucasgarcia commented 8 months ago

I have seen you just did some fix in the migrations side

excid3 commented 8 months ago

Ah yeah! I just merged #402 which matches what Rails does for ActiveStorage migrations so we can do the same thing. Will cut a new release of that shortly.

rromanchuk commented 8 months ago

@excid3 i'm debugging this right now as we speak (this ticket specifically), let me clean up my noisy queue and i can send more details. I didn't see anything obvious in Noticed::DeliveryMethods::Email, so let me clean up the noise

rromanchuk commented 8 months ago

lol actually, looks like i have a general config error, hasn't even gotten to actual delivery methods. I'm guessing my :if blocks are out of scope

Screenshot 2024-02-14 at 12 37 40 PM
rromanchuk commented 8 months ago

This is how i had communication prefs logic split

module Apnable
  extend ActiveSupport::Concern

  included do
    deliver_by :ios do |config|
      # truncated
      config.if = :push_notifications?
    end
  end
end

class FollowedNotifier < Noticed::Event
  include Apnable

  def email_notifications?
    recipient.follower_alerts.include?('email')
  end

  def push_notifications?
    recipient.follower_alerts.include?('push')
  end

  def sms_notifications?
    recipient.follower_alerts.include?('sms')
  end
end

Looks like recipient is yielded and i'm not receiving it so probably explains the

ArgumentError (wrong number of arguments (given 1, expected 0))

Fixed It yields the notification https://github.com/excid3/noticed/blob/main/lib/noticed/delivery_method.rb#L54 now i'm getting actual channel specific delivery failures, which is a good sign and expected in my current env

def email_notifications?(notification)
  notification.recipient.follower_alerts.include?('email')
end