📮 Simple, powerful email tracking for Rails
You get:
- A history of emails sent to each user
- Easy UTM tagging
- Open and click tracking
Works with any email service.
🚄 To manage unsubscribes, check out Mailkick
🔥 To track visits and events, check out Ahoy
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
rails db:migrateAhoy creates an Ahoy::Message every time an email is sent by default.
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 < ApplicationMailer
def welcome_email(user)
# ...
track user: user
mail to: user.email
end
endThe user association is polymorphic, so use it with any model.
To get all messages sent to a user, add an association:
class User < ApplicationRecord
has_many :messages, class_name: "Ahoy::Message", as: :user
endAnd run:
user.messagesUTM 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>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.
A redirect is added to links to track clicks in HTML emails.
https://chartkick.com
becomes
https://yoursite.com/ahoy/messages/rAnDoMtOkEn/click?url=https%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>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
endThen use:
track extra: {campaign_id: 1}Skip tracking of attributes by removing them from your model. You can safely remove:
- to
- mailer
- subject
- content
There are 3 places to set options. Here’s the order of precedence.
class UserMailer < ApplicationMailer
def welcome_email(user)
# ...
track user: user
mail to: user.email
end
endclass UserMailer < ApplicationMailer
track utm_campaign: "boom"
endAhoyEmail.track open: falseSubscribe 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.newHere’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.newYou can use a Proc for any option.
track utm_campaign: ->(message, mailer) { mailer.action_name + Time.now.year }Disable tracking for an email
track message: falseOr specific actions
track only: [:welcome_email]
track except: [:welcome_email]Or by default
AhoyEmail.track message: falseCustomize domain
track url_options: {host: "mydomain.com"}By default, unsubscribe links are excluded from tracking. To change this, use:
track unsubscribe_links: trueUse a different model
AhoyEmail.message_model = -> { UserMessage }Optionally, you can store UTM parameters by adding utm_source, utm_medium, and utm_campaign columns to your message model.
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features