Ahoy Email

:postbox: Simple, powerful email tracking for Rails

You get:

  • A history of emails sent to each user
  • Open and click tracking
  • Easy UTM tagging

Works with any email service.

:bullettrain_side: To manage unsubscribes, check out Mailkick

:fire: To track visits and events, check out Ahoy

Build Status

Installation

Add this line to your application’s Gemfile:

gem 'ahoy_email'

And run the generator. This creates a model to store messages.

rails generate ahoy_email:install
rake db:migrate

How It Works

Ahoy creates an Ahoy::Message every time an email is sent by default.

Users

Ahoy tracks the user a message is sent to - not just the email address. This gives you a full history of messages for each user, even if he or she changes addresses.

By default, Ahoy tries User.where(email: message.to.first).first to find the user.

You can pass a specific user with:

class UserMailer < ActionMailer::Base
  def welcome_email(user)
    # ...
    track user: user
    mail to: user.email
  end
end

The user association is polymorphic, so use it with any model.

To get all messages sent to a user, add an association:

class User < ActiveRecord::Base
  has_many :messages, class_name: "Ahoy::Message"
end

And run:

user.messages

Opens

An invisible pixel is added right before the </body> tag in HTML emails.

If the recipient has images enabled in his or her email client, the pixel is loaded and the open time recorded.

Use track open: false to skip this.

Clicks

A redirect is added to links to track clicks in HTML emails.

http://chartkick.com

becomes

http://you.io/ahoy/messages/rAnDoMtOkEn/click?url=http%3A%2F%2Fchartkick.com&signature=...

A signature is added to prevent open redirects.

Use track click: false to skip tracking, or skip specific links with:

<a data-skip-click="true" href="...">Can't touch this</a>

UTM Parameters

UTM parameters are added to links if they don’t already exist.

The defaults are:

  • utm_medium - email
  • utm_source - the mailer name like user_mailer
  • utm_campaign - the mailer action like welcome_email

Use track utm_params: false to skip tagging, or skip specific links with:

<a data-skip-utm-params="true" href="...">Break it down</a>

Extra Attributes

Create a migration to add extra attributes to the ahoy_messages table, for example:

class AddCampaignIdToAhoyMessages < ActiveRecord::Migration
  def change
    add_column :ahoy_messages, :campaign_id, :integer
  end
end

Then use:

track extra: {campaign_id: 1}

Customize

Tracking

Skip tracking of attributes by removing them from your model. You can safely remove:

  • to
  • mailer
  • subject
  • content

Configuration

There are 3 places to set options. Here’s the order of precedence.

Action

class UserMailer < ActionMailer::Base
  def welcome_email(user)
    # ...
    track user: user
    mail to: user.email
  end
end

Mailer

class UserMailer < ActionMailer::Base
  track utm_campaign: "boom"
end

Global

AhoyEmail.track open: false

Events

Subscribe to open and click events. Create an initializer config/initializers/ahoy_email.rb with:

class EmailSubscriber
  def open(event)
    # any code you want
  end

  def click(event)
    # any code you want
  end
end

AhoyEmail.subscribers << EmailSubscriber.new

Here’s an example if you use Ahoy to track visits and events:

class EmailSubscriber
  def open(event)
    event[:controller].ahoy.track "Email opened", message_id: event[:message].id
  end

  def click(event)
    event[:controller].ahoy.track "Email clicked", message_id: event[:message].id, url: event[:url]
  end
end

AhoyEmail.subscribers << EmailSubscriber.new

Reference

You can use a Proc for any option.

track utm_campaign: proc { |message, mailer| mailer.action_name + Time.now.year }

Disable tracking for an email

track message: false

Or specific actions

track only: [:welcome_email]
track except: [:welcome_email]

Or by default

AhoyEmail.track message: false

Customize domain

track url_options: {host: "mydomain.com"}

Use a different model

AhoyEmail.message_model = UserMessage

Upgrading

0.2.3

Optionally, you can store UTM parameters by adding utm_source, utm_medium, and utm_campaign columns to your message model.

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help: