Godzilla74
Godzilla74

Reputation: 2512

Devise custom mailer SMTPAPI headers & Sendgrid

I'm using a devise custom mailer and have the signup process using my new method, however I'm getting the error undefined local variable or method 'headers' for DeviseMailer:Class when it's attempting to send the email after the signup. I need to be able to specify SMTPAPI headers to be able to use my Sendgrid template. I have this working for some other mailers (not devise related), so I've taken the same code and added it to my new devise mailer.

models/devise_mailer.rb

class DeviseMailer < Devise::Mailer
  helper :application
  include Devise::Controllers::UrlHelpers
  default template_path: 'devise/mailer'

  def self.confirmation_instructions(record, token, opts={})
    new(:confirmation_instructions, record, token, opts)

    headers "X-SMTPAPI" => {
     "sub": {
      "-user-" => [user.name]
     },
     "filters": {
      "templates": {
        "settings": {
          "enable": 1,
          "template_id": "f67a241a-b5af-46b3-9e9a-xxxxxxxxx"
        }
      }
     }
    }.to_json

    mail(
      to: user.email,
      subject: "Confirm your account",
      template_path: '../views/devise/mailer',
      template_name: 'confirmation_instructions'
    )


    opts[:from] = '[email protected]'
    opts[:reply_to] = '[email protected]'
    opts[:to] = "[email protected]" # just hardcoded right now, remove after testing
    super

  end
end

What am I missing here?

Upvotes: 0

Views: 619

Answers (1)

Carlos Ramirez III
Carlos Ramirez III

Reputation: 7434

I believe headers is defined as an instance method, not a class method. Since you are trying to call it within the context of the class (i.e. self.confirmation_instructions), it is undefined.

If you notice in the Devise wiki post on using custom mailers, the instructions reference headers on the instance, not the class.


If you just want to add some custom headers / options, the recommended approach is to just override the instance method then call super. For example

class DeviseMailer < Devise::Mailer
  helper :application
  include Devise::Controllers::UrlHelpers
  default template_path: 'devise/mailer'

  def confirmation_instructions(record, token, opts={})
    # custom header(s)
    headers["X-SMTPAPI"]= {
     "sub": {
      "-user-" => [user.name]
     },
     "filters": {
      "templates": {
        "settings": {
          "enable": 1,
          "template_id": "f67a241a-b5af-46b3-9e9a-xxxxxxxxx"
        }
      }
     }
    }.to_json

    # custom option(s)
    opts[:from] = '[email protected]'
    opts[:reply_to] = '[email protected]'
    opts[:to] = "[email protected]"

    super
  end
end

I recommend reading the linked blog post, as it talks about overriding the default behavior for mailers in more detail.

Upvotes: 1

Related Questions