Securely Send Emails From Rails App With Action Mailer and Figaro Gem

Ben Aron Davis
Analytics Vidhya
Published in
7 min readApr 24, 2020
Photo by Diana Akhmetianova on Unsplash

Ruby on Rails provides Action Mailer to facilitate email communication from your app. Email capability seems like a complex feature, but with the help of Action Mailer, I had it working with my application in a couple of hours. Not only was it working, but it was also coded responsibly to keep my email credentials private using Figaro.

First, I’ll explain the project and how email capability adds to the experience. Then, we’ll walk through the process of adding email capability step by step, including creating a Gmail app password to ensure access and hiding our sensitive Gmail information in environment variables using the Figaro gem.

Email Adds to the User Experience

My “GroupStory” application allows users to crowdsource stories, writing them one chapter at a time. Once users have contributed five total chapters, a story is considered finished and finally ready to showcase in its entirety. Contributing users have the option to provide their email address, so we can notify them once the story to which they contributed is finished. In the email, we provide a link to the page where they can view the finished story. Here, our email capabilities provide a convenience for the user, so they don’t have to check the application over and over to see if their story has been finished.

How It’s Done

Here we’re going to take a look at each step in the process. Let’s assume I’ve already created a gmail account I’d like to use for myapp. Unfortunately, ‘groupstory@gmail.com’ was already taken, so I had to settle for ‘groupstoryapp@gmail.com’.

Hide Username and App Password Using Figaro

Figaro is a Ruby gem that makes it easy for us to create environment variables that will be hidden from our repositories. I added the line gem 'figaro' to my Gemfile. When I ran $ bundle install in the command line, I received an error which recommended I run $ bundle update instead, which I did. Once that worked successfully, I ran $ bundle exec figaro install in the command line. That command created a file config/application.yml and appended a file .gitignore. The .gitignore file now included a line, which said to ignore the config/application.yml file.

In config/application.yml, I created the environment variables to hold the values of my gmail username and my app password. Before I could do that, I needed an app password. I went to my Google account page, clicked on the “Security” tab on the left side of the page, and made sure 2-Step Verification was “On”. Finally, I selected “App Passwords” right beneath “2-Step Verification”, and generated a new one at the bottom. A window popped up with my new app password for me to copy. Make sure to copy it right away, because you won’t be able to access it again. Below is a video that shows exactly how it looks:

Registering an App Password

Once I had my app password created, I set my Gmail username and app password as environment variables in the config/application.yml file.

Now I could access my username and password in any other file with the variables ENV[“GMAIL_USERNAME”] and ENV[“GMAIL_PASSWORD”] respectively. Let’s take a look where I used those variables.

Configure Rails App with Gmail

In config/environments/production.rb, I provided the app with the information necessary for it to send emails from the Gmail account. Here’s where I used my environment variables ENV[“GMAIL_USERNAME”] and ENV[“GMAIL_PASSWORD”]. My Rails server runs on ‘http://localhost:3000/’, so you’ll notice that served as my host in the configuration. All together, the code I added to config/environments/production.rb looks like this:

In config/environments/production.rb

Once I had my Rails app configured with my Gmail account, I could start using Action Mailer.

Generate Mailer

Rails provides commands that automatically create the right files in the right places for us. It’s important here to know which controller you’ll be using with this mailer. For me, I knew that my mailer would work in cooperation with my “ChaptersController”, so I entered rails generate mailer ChapterMailer in the command line. This command created four new files for me, two of which I would used.

The first file I used was app/mailers/chapter_mailer.rb. This file is where we can create actions to use in the controller. Before I messed with that file, I had to make an adjustment in another file in the same folder (app/mailers/application_mailer.rb). In this file, I added my environment variable holding my Gmail username as the default address emails come from. Here’s what my app/mailers/application_mailer.rb file looks like:

Mailer Actions

Once I knew my emails were coming from the right address, I could create an action in the ChapterMailer to send emails. Since I wanted to send out emails once a story is finished, I called my action finished_story_email. Inside the action, I created an instance variable using a param that I passed from ChaptersController (I’ll show you where I do that later). This instance variable would be a specific Story instance. I iterate through each one of this story’s chapters, and if there’s an email attribute for the chapter, the action sends an email to them.

ChapterMailer action

Right now you might have a few questions:

  1. When do we call this finished_story_email action?
  2. Where do we get this params[:story]?
  3. Where do we program what this email looks like that we’re sending out?

Let’s answer the first two questions by taking a look at how I used ChapterMailer in my ChaptersController.

Controller Calls the Mailer

I wanted to send emails once a story was finished. I needed to figure out where in my backend I could find when exactly a story is finished. It happened to be in the ‘create’ action of my ChaptersController. If the chapter being created belongs to a story that has 5 chapters, that chapter’s story has just been finished. Therefore, it’s time to send out emails! Inside a conditional statement, I called my ChapterMailer action with chapter.story as my story param, which I then use in ChapterMailer to set my @story instance variable.

Now that we know when I call the ChapterMailer action, and where ChapterMailer gets its params from, it’s time I coded the content of the email in the views folder.

Format Emails in Views

As I mentioned earlier, the command rails generate mailer ChapterMailer created two files that I would use. That second file I used is actually a folder (app/views/chapter_mailer) inside of which I created two files. One view file is an html file, and the other is a text file in case the html file doesn’t work properly. The name of these view files had to match the action in ChapterMailer that uses them. So my html view file was app/views/chapter_mailer/finished_story_email.html.erb, and there I could use erb tags alongside html tags. I kept my email content very simple, so I just wanted it to say “<Story Title> is now finished!” with a link to view the story’s show page. Notice how my erb tags make use of the @story instance variable.

app/views/chapter_mailer/finished_story_email.html.erb

Once that was taken care of, it was time to test it out. I added five chapters to a story with my personal email included, and upon submission of the fifth chapter I received an email from ‘groupstoryapp@gmail.com’ with that specific story title and a link to view the page.

Success!

This was one specific way of sending emails through a Rails app. Know that you can create environment variables without Figaro, and you can send emails from a non-Gmail account. That will simply require a little more research on your end.

Check out these links to see where I gathered my understanding of how this all works.

--

--