Mail Sending API perks over SMTP in Ruby on Rails using MailGun or SendGrid
Using Email APIs gives features like more probability of delivery, subscriber list, and dynamic email templates.

Mail sending in Ruby on Rails is simple method of SMTP settings. Just configure the SMTP settings available here: https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration.
The problem with SMTP is that you as ROR developer has to handle all about sending the emails from the application. There is also much less chance of delivery than the APIs. Furthermore, many APIs give many perks for developers to ease their life.
MailGun:
MailGun is one such API that also provide SMTP, but the API has many more features included.
For Ruby and Rails, MailGun has its gem available here.
Instead of SMTP, just add gem into rails and add the api key of mailgun account. And this will give at least more probable chance of delivery of email than SMTP.
config/environments/production.rb
:
config.action_mailer.default_url_options = {host: "xxxxxxxxxx"}
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
api_key: Rails.application.credentials.MAILGUN[:api_key],
domain: 'xxxxxxxxxx',
api_host: 'api.eu.mailgun.net' # Uncomment this line for EU region domains
}
Apart from sending the email, you can also get the stats about the sent emails in the application as well if this is the requirement in the application.
SendGrid:
SendGrid APIs provide much more functionality than mailgun.
For Ruby on Rails, SendGrid has its gem available here.
Newsletter Subscription
SendGrid has marketing solution, where we can create a subscriber list and send the marketing emails apart from just transactional emails.
So, using the same gem when a user signs in the application you can ask if it wants newsletter subscription then you can add to the list in sendgrid. So, to add to subscriber list a user call this job in user after create callback:
app/jobs/add_user_to_sendgrid_list_job
:
class AddUserToSendgridListJob < ApplicationJob
require 'sendgrid-ruby'
include SendGrid
queue_as :default
LIST_ID = 'abcdnbh-hbdfehbfjhbe-hbhefb'.freeze
def perform(user_id)
user = User.kept.find_by(id: user_id)
if user
# Add the user data
user_data = [{ email: user.email, first_name: user.name }]
# Add to list
list_ids = [WALLET_LIST_ID]
body = { list_ids: list_ids, contacts: user_data }
sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
response = sg.client.marketing.contacts.put(request_body: body)
# If not added then send error to sentry
unless ['202'].include? response.status_code
# Generate Error Here
end
response.parsed_body
end
end
end
This will add the user to your marketing list as well.
Email Templates:
SendGrid also gives Dynamic Email Templates for us developers so that we don’t have to convert the HTML template to erb for rails. Moreover, we don’t have to update every-time client asks us to update the template as because then client has to update the html in sendgrid, and we don’t have to do anything.
So to send an email through rails, you can user this job app/jobs/email_job.rb
:
require "sendgrid-ruby"
class EmailJob
include Sidekiq::Worker
include SendGrid
sidekiq_options queue: 'default', retry: 3
NOREPLY_FROM_EMAIL = "hello@world.com".freeze
NOREPLY_FROM_NAME = "Hello World"
def perform(user_id, subsitutions, template_id)
sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
user = User.kept.find_by(id: user_id)
if user
data = {
"personalizations": [{
"to": [{
"email": user.email,
"name": user.name
}],
"dynamic_template_data": subsitutions
}],
"from": {
"email": NOREPLY_FROM_EMAIL,
"name": NOREPLY_FROM_NAME
},
"template_id": template_id
}
response = sg.client.mail._("send").post(request_body: data)
unless ['200', '201', '202'].include? response.status_code
# Generate Error Here
end
end
end
end
Substitutions are the place where we will substitute user characteristics like name, link etc.
This job can be called as:
EmailJob.perform_async(id, { confirm_url: url, name: name }, ENV['CONFIRM_EMAIL_TEMPLATE'])
so, when email is sent then confirm_url
and name
in email is substituted with provided data.
Conclusion:
So, APIs providing email clients give more chance of email delivery with API than SMTP. Also, MailGun and SendGrid provide more good features using APIs. So please try them one time with API.