Setting up mail with Mailgun - StanfordBioinformatics/pulsar_lims GitHub Wiki

Overview

Pulsar LIMS uses email verification when a new user signs up. Heroku hosts several mail service addons, and Pulsar expects the Mailgun addon by default to be in use, however, any other mail service addon can be preferentially selected, in which case some mailer configuration variables need to be changed.

The Devise Rails engine handles the logic to send out an email for us behind the scenes when a user signs up and verify new users, since the "confirmable" module from Devise is in use. Devise is a modular Rails engine (installed as a gem), meaning that it contains its own controllers and views. When building an app that uses devise, the developer picks and chooses which modules to incorporate, and "confirmable" is one of them used within Pulsar.

In order for an email to actually be sent out though, one must specify a mail service to use. Puslar is configured to use Mailgun in the production and development environments, which Heroku hosts as an addon. So the first thing to do is install the addon.

Installing the Mailgun addon

We'll select the starter plan (see plan details here), which is free.

heroku addons:create mailgun:starter

This will automatically set up several MAILGUN_* environment variables, including

  • MAILGUN_API_KEY
  • MAILGUN_DOMAIN
  • MAILGUN_PUBLIC_KEY
  • MAILGUN_SMTP_LOGIN
  • MAILGUN_SMTP_PASSWORD
  • MAILGUN_SMTP_PORT
  • MAILGUN_SMTP_SERVER

A closer look at email configuration in Pulsar

ActionMailer, the layer of Rails that wraps around email logic, has been configured to use Mailgun in both production and development enviornments via custom settings in the files config/environments/production.rb and config/environments/development.rb. This is where we let ActionMailer know how to send an email by employing the environment variables that Heroku automatically sets for Mailgun when added, as listed earlier. In production.rb, the relevant code block is:

    ActionMailer::Base.delivery_method = :smtp

    host = ENV["APP_HOST_NAME"]

    ActionMailer::Base.smtp_settings = { 
      port: ENV['MAILGUN_SMTP_PORT'],
      address: ENV['MAILGUN_SMTP_SERVER'],
      user_name: ENV['MAILGUN_SMTP_LOGIN'],
      password: ENV['MAILGUN_SMTP_PASSWORD'],
      domain: host,
      authentication: :plain,
    }   

    #specify default URL for links that are sent in the emails (i.e confirmation email)
    config.action_mailer.default_url_options = { 
    host: host
    }

Note that for the host setting, we refer to the environment variable APP_HOST_NAME. If you haven't yet defined this, you should go ahead and do so, for example heroku config:set APP_HOST_NAME=pulsar-encode.herokuapp.com. Change the definition of host to be equal to the domain name of your Heroku application by changing the part that says "pulsar-encode" to whatever app name you chose on Heroku. Then, in development.rb, set the host value to host = "localhost:5000". This setting is appropriate if you're working in your development environment locally. The port is set to 5000 since Pulsar is setup to use the Puma web server in both production and development environments.

Adding a custom domain

The sandbox domain that comes with your Mailgun account is limited to testing purposes. For example, you can only send email to no more than 5 authorized recipients, whom you designate in the sandbox domain configuration in Mailgun. In production, you'll need to have your own mail domain set up and verified with Mailgun.

Create a new domain

You'll first need a domain to register with Mailgun. You could request your networking team to set you up with a subdomain (as you need it to be named) within your company's domain. For example, I chose pulsar-encode to be a subdomain name of stanford.edu. If you don't have a company domain to piggy-back on, you can always purchase your own domain with a small yearly fee through a DNS provider. Once you have a domain issued, you can go onto the next step.

Create a domain entry in Mailgun

Follow the instructions at https://documentation.mailgun.com/en/latest/user_manual.html#verifying-your-domain to create a new domain entry. This will provide you with the DNS keys to that you or your networking team will need to add to your domain's DNS. Once the DNS keys are added, Mailgun will verify the new domain; once that happens, you can go ahead and try sending out a test email. You can use a variety of test methods, and below I'll demonstrate with curl.

Update the MAILGUN configuration in Heroku

When you initially added Mailgun to your Heroku application as an add-on, the default configuration variables that were set up pointed to your sandbox domain. You'll need to update three of these variables before your application can start using your new domain. These three variables are:

  1. MAILGUN_DOMAIN
  2. MAILGUN_SMTP_LOGIN
  3. MAILGUN_SMTP_PASSWORD

You can find out what to set these to in the Mailgun user interface by selecting your custom domain and perusing the "Domain Information" section. Use the command heroku config:set to update their values. Also, don't forget to update the .env file within your application's home directory on your local workstation, so that the changes can be picked up when running in development mode via the heroku local command.

Sending a test email

First, go to your Mailgun user interface and click on the "Domains" tab. You should see two entries - the default sandbox domain that comes with your Mailgun account, and your custom domain. Select your custom domain. Under the "Domain Information" section, you'll see properties about your domain that are registered with Mailgun. There, you'll find your API Key and API Base URL. Note that the domain name I created and registered with Heroku is pulsar-encode.stanford.edu. The API Base URL for Pulsar ENCODE is https://api.mailgun.net/v3/pulsar-encode.stanford.edu; thus, it is composed of a Mailgun prefix URL and suffixed with my custom domain name. In order to keep my API Key secret,let's assume that its value is key-mysecret. With those two bits of information, I can now build my test email command using curl like so:

curl --user 'api:key-mysecret'  https://api.mailgun.net/v3/pulsar-encode.stanford.edu/messages -F from='[email protected]' -F to='[email protected]' -F subject='Hello' -F text='Mailgun test email' 

This curl command is imitating the submission of a form to an API endpoint. The Mailgun documentation, where they also demonstrate using curl to send out a test email, reveals that the API endpoint to use is formulated by appending "/messages" to the API Base URL. Also, note that in the from form field I specified [email protected]. The user part (before the '@') is arbitrary. I didn't have to set it to pulsar-encode, but it makes sense to since that is my application name on Heroku. I could have set it to sunny-day, had I felt like it!

Setting the APP_EMAIL_ADDR environment variable

Pulsar is configured to use the APP_EMAIL_ADDR environment variable, which Pulsar uses when sending out emails to users and the email shouldn't be responded to, i.e. (email registration sign-up, password resets, ...). This is referenced in app/mailers/user_mailer.rb to set the from address. Thus, you'll need to create this environment variable using heroku config:set, setting it to the name of your Heroku application, or some other value that your prefer.