Search code examples
ruby-on-railsherokudevisemailjet

Linking Devise to Mailjet


We are trying to linkup our devise password reset form to the mailjet gem. I have followed all instructions on the mailjet repo read-me, but I'm still having trouble connecting the API up to the Devise 'reset password' form, and it seems clear something is missing.

a) First, I've searched everywhere on google, mailjet's support site, and here on Stackoverflow, but can't seem to find any instructions anywhere for helping to link up MailJet to Devise. Have I missed anything?

b) If there are no pre-written guides on how to do this, could someone kindly help with the particular steps I need to take to ensure that when I press 'Send Password Reset Link' on our devise sign-in page, it properly sends the email? Right now, we are getting an error: email is required. But my email address IS there. So it's not linking up properly. I think we need to connect that particular devise page to the mailjet api, but I'm not certain how to do that.

c) Next, is this testable on localhost, or is the only way to test to go live on heroku? Perhaps that may be one of the issues...

d) Finally, do I have to do anything on Heroku itself to link up to my MailJet account? Apparently, you do with SendGrid, but I think because I already have the mailjet API and Secret Key, I don't need to connect directly through Heroku, yes?

Thanks in advance for any assistance. -Monroe

Here is my code so far:

THE PASSWORD RESET PAGE

<main class="form forgot-form">
  <section class="form-container">
    <h1>Reset password</h1>
    <p>Enter the email address associated with your account, and we’ll email you a link to reset your password.</p>
    <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }, :defaults => {  wrapper: false }) do |f| %>
      <%= f.error_notification %>
      <%= f.input :email, required: true, autofocus: true, error: 'Email is required', 
      input_html: { class: 'form__field' }, label_html: { class: 'sr-only' }, placeholder: 'Email Address' %>
      <%= f.button :submit, "Send reset link", class: 'form__button mt-4' %>
    <% end%>
    <%= link_to '< Back to Login', new_user_session_path, class: "link go-page" %>
  </section>
</main>

THE MAILER ITSELF:

<p>Hello <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

THE INITIALIZER:

# kindly generated by appropriated Rails generator
Mailjet.configure do |config|
  config.api_key = 'my-api-key--removed for safety'
  config.secret_key = 'my-secret-key--removed for safety'
  config.default_from = 'my-email--removed for safety'
  # Mailjet API v3.1 is at the moment limited to Send API.
  # We’ve not set the version to it directly since there is no other endpoint in that version.
  # We recommend you create a dedicated instance of the wrapper set with it to send your emails.
  # If you're only using the gem to send emails, then you can safely set it to this version.
  # Otherwise, you can remove the dedicated line into config/initializers/mailjet.rb.
  config.api_version = 'v3.1'
end

DEVELOPMENT.RB

  # Specify that we are using the MailJet API for transactional emails
  config.action_mailer.delivery_method = :mailjet

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  config.action_mailer.perform_caching = false

PRODUCTION.RB

# Use a real queuing backend for Active Job (and separate queues per environment)
  # config.active_job.queue_adapter     = :resque
  # config.active_job.queue_name_prefix = "bdcommunity_#{Rails.env}"
  config.action_mailer.perform_caching = false
  # Ignore bad email addresses and do not raise email delivery errors.
  #Set this to true and configure the email server for immediate delivery to raise delivery errors.
  #NOTE FROM MONROE: We should look into this after we launch and as we develope the site further
  #config.action_mailer.raise_delivery_errors = false
  # Specify that we are using the MailJet API for transactional emails
  config.action_mailer.delivery_method = :mailjet
  # config.action_mailer.perform_deliveries = true

The 'perform_deliveries' above I found on a post from 2011, so it very well may not work. I just put it there (commented out) in case it may help you in figuring out what we are doing wrong.


Solution

  • The only things you should need are the Mailjet gem in your Gemfile:

    gem 'mailjet'
    

    And the following config, which I wrote to config/initializers/mail.rb:

    Mailjet.configure do |config|
      config.api_key      = Rails.application.secrets.mailjet_username
      config.secret_key   = Rails.application.secrets.mailjet_password
      config.default_from = 'user@example.com'
    end
    

    Then you'll configure your environments to use mailjet to send email in your config/environments files:

    config.action_mailer.delivery_method = :mailjet
    

    You may also need to check in your Mailjet account for the "sender addresses" to spot any issues: https://app.mailjet.com/account/sender

    For https://gorails.com, I've added the gorails.com domain here to approve all emails with that domain.

    Then for Devise, you can edit config/initializers/devise.rb to change the email address it uses:

    config.mailer_sender = 'GoRails <no-reply@gorails.com>'
    

    You can also customize ApplicationMailer to use the same default.

    class ApplicationMailer < ActionMailer::Base
      default from: 'GoRails <no-reply@gorails.com>'
      layout 'mailer'
    end