Project

sg_mailer

0.0
No commit activity in last 3 years
No release in over 3 years
Action Mailer-like framework for SendGrid transactional mails
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 1.13
~> 5.0
~> 10.0
 Project Readme

SGMailer

SG Mailer is a mailing framework with similar to Action Mailer interface for SendGrid transactional emails.

Installation

Add this line to your application's Gemfile:

gem 'sg_mailer'

Usage

To start using the framework, you need to configure it first. It requires a SendGrid API KEY, which you can setup like this:

SGMailer.configure(api_key: ENV['SENDGRID_API_KEY')

Once setup, you can use SG Mailer alongside or as a replacement to Action Mailer. Creating a base mailer (a class like ApplicationMailer) is a good starting point.

# app/mailers/sendgrid_mailer.rb

class SendGridMailer < SGMailer::Base
  # you may wanna include helper modules here, as they are not automgically
  # included like in action mailer.
end

Having the base mailer around, you may start introducing specific ones.

class SubscriptionMailer < SendGridMailer
  def successful_subscription_mail(parent, kid)
    template_id = 'd6c0eb74-b280-4d25-a835-479818a450e8'

    substitutions = {
      'KIDNAME' => kid.name
      'PARENTTYPE' => parent.gender
    }

    mail from: 'charlie@bp.com', to: parent.email,
         template_id: template_id, substitutions : substitutions
  end
end

Working with transaction emails, you are quite likely to use templates for them. Since this is so common, there is nice interface for annotating the emails with the template id.

class SubscriptionMailer < SendGridMailer
  template_id 'd6c0eb74-b280-4d25-a835-479818a450e8'
  def successful_subscription_mail(parent, kid)
    substitutions = {
      'KIDNAME' => kid.name
      'PARENTTYPE' => parent.gender
    }

    mail from: 'charlie@bp.com', to: parent.email,
         substitutions : substitutions
  end
end

You can also extract the common sender into a default value like so:

class SubscriptionMailer < SendGridMailer
  default from: { name: 'Charlie Brown', email: 'charlie@bp.com' }

  template_id 'd6c0eb74-b280-4d25-a835-479818a450e8'
  def successful_subscription_mail(parent, kid)
    substitutions = {
      'KIDNAME' => kid.name
      'PARENTTYPE' => parent.gender
    }

    mail to: parent.email, substitutions : substitutions
  end
end

In fact the base mailer (SendGridMailer) is a good place to define such defaults.

# app/mailers/sendgrid_mailer.rb

class SendGridMailer < SGMailer::Base
  default from: { name: 'Charlie Brown', email: 'charlie@bp.com' }
end

We were able to clean a lot of cruft from the mailers above, however, can we do something about the substitutions. They do seem to have noisy API. Let's think about Ruby instance variables. The Rails controller to view integration uses them as an API and it works pretty well.

# app/mailers/sendgrid_mailer.rb

class SendGridMailer < SGMailer::Base
  default from: { name: 'Charlie Brown', email: 'charlie@bp.com' }

  private

  # This is the hook that processes the options given to `SGMailer::Base#mail`.
  # Don't forget to call super and return a Hash in here.
  def normalize_options(options)
    automatic_substitutions = instance_values.transform_keys do |key|
      "#{key.to_s.remove('_').upcase}"
    end

    super.deep_merge(substitutions: automatic_substitutions)
  end
end

With the code above the mails can look pretty tidy.

class SubscriptionMailer < SendGridMailer
  template_id 'd6c0eb74-b280-4d25-a835-479818a450e8'
  def successful_subscription_mail(parent, kid)
    @kid_name = kid.name
    @parent_type = parent.gender

    mail to: parent.email
  end
end

We don't conventionalize the substitutions, because their format varies from team to team. When you settle on one, you can easily turn your instance variables into proper substitutions, should you want to.

Until now, we only defined mails, but how to send them?

# To deliver the mail now.
SubscriptionMailer.successful_subscription_mail.deliver_now

# To deliver the mail later on, with ActionJob, if installed.
SubscriptionMailer.successful_subscription_mail.deliver_later

The interface should be pretty familiar to you, if you have used Action Mailer before.

License

The gem is available as open source under the terms of the MIT License.