Home

Awesome

Deprecated as of June 6, 2024

Griddler has been deprecated in favor of ActionMailbox since this is built into Rails now.

Griddler

Receive emails in your Rails app

Griddler is a Rails engine that provides an endpoint for services that convert incoming emails to HTTP POST requests. It parses these POSTs and hands off a built email object to a class implemented by you.

Tutorials

Installation

  1. Add griddler and an adapter gem to your application's Gemfile and run bundle install.

  2. A route is needed for the endpoint which receives POST messages. To add the route, in config/routes.rb you may either use the provided routing method mount_griddler or set the route explicitly. Examples:

    # config/routes.rb
    
    # mount using default path: /email_processor
    mount_griddler
    
    # mount using a custom path
    mount_griddler('/email/incoming')
    
    # the DIY approach:
    post '/email_processor' => 'griddler/emails#create'
    

Configuration Options

An initializer can be created to control some of the options in Griddler. Defaults are shown below with sample overrides following. In config/initializers/griddler.rb:

Griddler.configure do |config|
  config.processor_class = EmailProcessor # CommentViaEmail
  config.email_class = Griddler::Email # MyEmail
  config.processor_method = :process # :create_comment (A method on CommentViaEmail)
  config.reply_delimiter = '-- REPLY ABOVE THIS LINE --'
  config.email_service = :sendgrid # :cloudmailin, :postmark, :mandrill, :mailgun
end
OptionMeaning
processor_classThe class Griddler will use to handle your incoming emails.
email_classThe class Griddler will use to represent an incoming e-mail. It must support an initializer that receives a hash as the only argument. We recommend inheriting it from Griddler::Email or checking this class to see all the methods it responds to.
processor_methodThe method Griddler will call on the processor class when handling your incoming emails.
reply_delimiterThe string searched for that will split your body. You can also supply an array of string - useful if you need translated versions of the delimiter
email_serviceTells Griddler which email service you are using. The supported email service options are :sendgrid (the default), :cloudmailin (expects multipart format), :postmark, :mandrill and :mailgun. You will also need to have an appropriate adapter gem included in your Gemfile.

By default Griddler will look for a class named EmailProcessor. The class is initialized with a Griddler::Email instance representing the incoming email, and has a process method to actually process the email. For example, in ./lib/email_processor.rb:

class EmailProcessor
  def initialize(email)
    @email = email
  end

  def process
    # all of your application-specific code here - creating models,
    # processing reports, etc

    # here's an example of model creation
    user = User.find_by_email(@email.from[:email])
    user.posts.create!(
      subject: @email.subject,
      body: @email.body
    )
  end
end

Griddler::Email attributes

AttributeDescription
#toAn array of hashes containing recipient address information. See Email Addresses for more information.
#fromA hash containing the sender address information.
#ccAn array of hashes containing cc email address information.
#subjectThe subject of the email message.
#bodyThe full contents of the email body unless there is a line in the email containing the string -- REPLY ABOVE THIS LINE --. In that case .body will contain everything before that line.
#raw_textThe raw text part of the body.
#raw_htmlThe raw html part of the body.
#raw_bodyThe raw body information provided by the email service.
#attachmentsAn array of File objects containing any attachments.
#headersA hash of headers parsed by Mail::Header, unless they are already formatted as a hash when received from the adapter in which case the original hash is returned.
#raw_headersThe raw headers included in the message.
#to_hA hash of the above attributes.

Email Addresses

Gridder::Email provides email addresses as hashes. Each hash will have the following information of each recipient:

KeyValue
:tokenAll the text before the email's "@". We've found that this is the most often used portion of the email address and consider it to be the token we'll key off of for interaction with our application.
:hostAll the text after the email's "@". This is important to filter the recipients sent to the application vs emails to other domains. More info below on the Upgrading to 0.5.0 section.
:emailThe email address of the recipient.
:fullThe whole recipient field (e.g., Some User <hello@example.com>).
:nameThe name of the recipient (e.g., Some User).

Testing In Your App

You may want to create a factory for when testing the integration of Griddler into your application. If you're using factory_girl this can be accomplished with the following sample factory:

factory :email, class: OpenStruct do
  # Assumes Griddler.configure.to is :hash (default)
  to { [{ full: 'to_user@email.com', email: 'to_user@email.com', token: 'to_user', host: 'email.com', name: nil }] }
  from { { token: 'from_user', host: 'email.com', email: 'from_email@email.com', full: 'From User <from_user@email.com>', name: 'From User' } }
  subject { 'email subject' }
  body { 'Hello!' }
  attachments { '0' }

  trait :with_attachment do
    attachments {[
      ActionDispatch::Http::UploadedFile.new({
        filename: 'img.png',
        type: 'image/png',
        tempfile: File.new("#{File.expand_path(File.dirname(__FILE__))}/fixtures/img.png")
      })
    ]}
  end
end

Bear in mind, if you plan on using the :with_attachment trait, that this example assumes your factories are in spec/factories.rb and you have an image file in spec/fixtures/.

To use it in your tests, build with email = build(:email) or email = build(:email, :with_attachment).

Adapters

Depending on the service you want to use Griddler with, you'll need to add an adapter gem in addition to griddler.

ServiceAdapter
sendgridgriddler-sendgrid
cloudmailingriddler-cloudmailin
mandrillgriddler-mandrill
mailgungriddler-mailgun
postmarkgriddler-postmark
sparkpostgriddler-sparkpost
ses (amazon)griddler-amazon_ses

Writing an Adapter

Griddler can theoretically work with any email => POST service. In order to work correctly, adapters need to have their POST parameters restructured.

Griddler::Email expects certain parameters to be in place for proper parsing to occur. When writing an adapter, ensure that the normalized_params method of your adapter returns a hash with these keys:

ParameterContents
:toThe recipient field
:fromThe sender field
:subjectEmail subject
:textThe text body of the email
:htmlThe html body of the email, or an empty string
:attachmentsArray of attachments to the email. Can be an empty array.
:headersThe raw headers of the email. Optional.
:charsetsA JSON string containing the character sets of the fields extracted from the message. Optional.

All keys are required unless otherwise stated.

Adapters should be provided as gems. If you write an adapter, let us know and we will add it to this README. See griddler-sendgrid for an example implementation.

Credits

Griddler was written by Caleb Hearth and Joel Oliveira.

Thanks to our contributors!

<!-- START /templates/footer.md -->

About thoughtbot

thoughtbot

This repo is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software! See our other projects. We are available for hire.

<!-- END /templates/footer.md -->