Friday, November 20, 2015

Using SendGrid Categories in Rails Action Mailer


I wanted to start using the categories feature on SendgriD
in my Rails app but they didn't document a way to do that in Rails.
So here's how I ended up implementing the categories, hopefully this will save someone some time.


Let's say you want to track clicks and opens for each and every email you send out through Rails, and let's also assume you are using SendGrid.
SendGrid has a feature called "categories" that was designed for this purpose.

First off go to your SendGrid settings and under the "Tracking" tab make sure you have clicks and opens enabled.


After that's done we can start changing our Rails code.


Simple Way:

If you only have a couple of emails in your app then there is no need to over complicate things
and you're in luck
add this line to your method, before the mail call:

headers['X-SMTPAPI'] = '{"category": "User welcome"}'

This will add the X-SMTPAPI header that SendGrid is expecting. 
The category key can actually except an array incase you want to use multiple categories per email. 

You'll end up getting something like this:


class UserMailer < ActionMailer::Base
    def my_message(name, email)
       @name = name
       @email = email
       headers['X-SMTPAPI'] = '{"category": "User welcome"}'

       mail(:to => @email,
            :from => me@me.com,
            :subject => "Welcome!")
    end
end

And that's it! you're done!

But... if you're anything like me you probably have several mailers and a growing amounts of emails. It will really get annoying to have to remember to always add that header line just so you'll have statistics for that email.

Generic Way:

If you have multiple mailers I recommend starting off by creating a base class like:

class BaseMailer < ActionMailer::Base

end

Then simply make all your mailers inherit this new class

class UserMailer < BaseMailer

end

After you have this setup the categories solution is in reach.
Create a before filter in the base class,
get the method's name,
add the header with that name

* note: If you're not on Rails 4 but on Rails 3 you'll have to add:
include AbstractController::Callbacks
To your base in order to have support for callbacks.

class BaseMailer < ActionMailer::Base
  include AbstractController::Callbacks # only for Rails 3

   before_filter :add_sendgrid_header

  def add_sendgrid_header
     category_name = action_name.gsub("_", " ").capitalize
     headers['X-SMTPAPI'] = {category: category_name}.to_json
  end
end

And that's it, the name of the actions will be sent as the category and you won't have to worry incase you add more emails.



Not using SendGrid and need email analytics for Rails?

checkout this cool gem:

https://github.com/ankane/ahoy_email