Linking Devise to Mailjet

842 Views Asked by At

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.

2

There are 2 best solutions below

8
On BEST ANSWER

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 = '[email protected]'
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 <[email protected]>'

You can also customize ApplicationMailer to use the same default.

class ApplicationMailer < ActionMailer::Base
  default from: 'GoRails <[email protected]>'
  layout 'mailer'
end
0
On

We got it working. Here are some additional tips you may find handy:

  • Chris confirmed that my development.rb and production.rb were correct, so you can use mine as guides.
  • We discovered that there were two main issues: 1) we forgot to update config.mailer_sender as Chris pointed out AND 2) We had to remove the error:email is required code.
  • Once we did that, it worked, even in development. However, we received an email kicked back saying we didn't authorize the email address (the one we set up in config.mailer_sender) so we followed the link it provided us in the email, which took us to an impossible to find otherwise page on mailjet that allowed us to whitelist all email addresses from our company's domain. That's what Chris was discussing above. He provides that web address above, but you can easily get it by trying to reset the password, and if everything is set up properly, you'll get an email saying that the sender email is not authorized yet.
  • We then were asked to install SPF and DKIM records, via our domain host (which is GoDaddy): https://support.smtp2go.com/hc/en-gb/articles/223086887-SPF-and-DKIM-Setup-for-GoDaddy
  • Finally, we tested again, and it worked. Password reset emailer functioned correctly!

Hope this helps!

UPDATE: To test and make it work on local host we also had to change this:

config.action_mailer_default_url_options= { host: 'localhost:3000' }

to this:

config.action_mailer.default_url_options = { host: "localhost", port: 3000 }

It doesn't actually send the email from localhost because of the security settings we set up on mailjet. But if you check your rails server log as soon as you request the password reset, you should see that the email was sent, as well as the subject and body of the email itself. And presumably, this will now also work on production.