Sendgrid API for Ruby on Rails

Michael Lee picture Michael Lee · Apr 5, 2016 · Viewed 7k times · Source

I can't seem to find a step by step tutorial on how to integrate the Sendgrid web API in to a Ruby on Rails application. I'm pretty new to this so maybe I'm missing something obvious.

I would like to use the Sendgrid web API instead of the smtp delivery method (mailgun talks about the benefits of the web API over the SMTP method here: https://documentation.mailgun.com/quickstart-sending.html, and I was thinking that Sendgrid would either have the same benefits or I would potentially switch to mailgun later).

After installing the sendgrid gem (https://github.com/sendgrid/sendgrid-ruby), the documentation tells me to "Create a new client with your SendGrid API Key", and that I can do it 2 ways:

require 'sendgrid-ruby'

# As a hash
client = SendGrid::Client.new(api_key: 'YOUR_SENDGRID_APIKEY')

# Or as a block
client = SendGrid::Client.new do |c|
  c.api_key = 'YOUR_SENDGRID_APIKEY'
end

Where specifically in my application am I supposed to put this code? Should I put this in my mailer, my application mailer or in the config/environments/production.rb file?

I took a look at this tutorial that walks through how to set up the Mailgun API: https://launchschool.com/blog/handling-emails-in-rails

According to this tutorial it looks like the line client = SendGrid::Client.new(api_key: 'YOUR_SENDGRID_APIKEY') should actually go in to the mailer method itself. See below for the launchschool.com example (presumably replacing the mailgun specific info with the sendgrid info):

class ExampleMailer < ActionMailer::Base

      def sample_email(user)
    @user = user
    mg_client = Mailgun::Client.new ENV['api_key']
    message_params = {:from    => ENV['gmail_username'],
                      :to      => @user.email,
                      :subject => 'Sample Mail using Mailgun API',
                      :text    => 'This mail is sent using Mailgun API via mailgun-ruby'}
    mg_client.send_message ENV['domain'], message_params
  end
end

Additionally, how do I get my mailer method to send a mailer view instead of simple text as outlined in the launchschool example? For example, instead of sending the text 'This mail is sent using...' I would like to send a mailer view (something like account_activation.html.erb).

Finally, I am using Devise in my application, and I would like to have Devise use the web API to send emails (ie password reset, etc). Does this mean I need to create a custom mailer for Devise? If so, how do I do that?

According to Devise (https://github.com/plataformatec/devise/wiki/How-To:-Use-custom-mailer), I should "create a class that extends Devise::Mailer". Does that mean I simply make a file within my mailer folder with the info laid out in the docs? Do I need a separate mailer for Devise or can I have an existing mailer inherit from the Devise mailer? Finally, how do I tell devise to use the sendgrid web api to send emails (instead of the simple smtp method)?

Sorry for the long question, but hopefully others find it useful.

Thanks!

Answer

NoNonsense picture NoNonsense · Aug 22, 2017

I would create a mailer class to do this

class SendgridWebMailer < ActionMailer::Base
  include Sendgrid

  def initialize
    @client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client
  end

  def send_some_email(record, token)
    mail = Mail.new
    // do your mail setup here
    mail = Mail.new
    mail.from = Email.new(email: YOUR_EMAIL_HERE)
    mail.subject = YOUR_SUBJECT

    // I personally use sendgrid templates, but if you would like to use html - 
    content = Content.new(
      type: 'text/html',
      value: ApplicationController.render(
        template: PATH_TO_TEMPLATE,
        layout: nil,
        assigns: IF_NEEDED || {}
      )
    mail.contents = content 

    personalization = Personalization.new
    personalization.to = Email.new(email: EMAIL, name: NAME)
    personalization.subject = SUBJECT

    mail.personalizations = personalization
    @client.mail._('send').post(request_body: mail.to_json)
  end
end

Call it using

SendgridWebMailer.send_some_email(record, token).deliver_later

For Devise

 class MyDeviseMailer < Devise::Mailer
   helper :application # gives access to all helpers defined within `application_helper`.
   include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`

   def reset_password_instructions(record, token, opts={})

      SendgridWebMailer.send_some_email(record, token).deliver_later
   end
end

in config/devise.rb

# Configure the class responsible to send e-mails.
  config.mailer = 'MyDeviseMailer'