Displaying: Email subscriptions for Rails

Mailkick

Email subscriptions for Rails

  • Add one-click unsubscribe links to your emails
  • Fetch bounces and spam reports from your email service

Build Status

Installation

Add this line to your application’s Gemfile:

And run the generator. This creates a table to store subscriptions.

bundle install
rails generate mailkick:install
rails db:migrate

Getting Started

Add has_subscriptions to your user model:

class User < ApplicationRecord
  has_subscriptions
end

user.unsubscribe("sales")

user.subscribed?("sales")

Get subscribers for a list (use this for sending emails)

Unsubscribe Links

Add an unsubscribe link to your emails. For HTML emails, use:

<%= link_to "Unsubscribe", mailkick_unsubscribe_url(@user, "sales") %>

Unsubscribe: <%= mailkick_unsubscribe_url(@user, "sales") %>

When a user unsubscribes, they are taken to a mobile-friendly page and given the option to resubscribe. To customize the view, run:

rails generate mailkick:views

which copies the view into app/views/mailkick.

Bounces and Spam Reports

Fetch bounces, spam reports, and unsubscribes from your email service. Create config/initializers/mailkick.rb with a method to handle opt outs.

Mailkick.process_opt_outs_method = lambda do |opt_outs|
  emails = opt_outs.map { |v| v[:email] }
  subscribers = User.includes(:mailkick_subscriptions).where(email: emails).index_by(&:email)

  opt_outs.each do |opt_out|
    subscriber = subscribers[opt_out[:email]]
    next unless subscriber

    subscriber.mailkick_subscriptions.each do |subscription|
      subscription.destroy if subscription.created_at < opt_out[:time]
    end
  end
end

The following services are supported:

Will gladly accept pull requests for others.

AWS SES

Mailchimp

And set ENV["MAILCHIMP_API_KEY"] and ENV["MAILCHIMP_LIST_ID"].

Mailgun

And set ENV["MAILGUN_API_KEY"].

Mandrill

And set ENV["MANDRILL_APIKEY"].

Postmark

And set ENV["POSTMARK_API_KEY"].

SendGrid

And set ENV["SENDGRID_API_KEY"]. The API key requires only the Suppressions permission.

Advanced

For more control over services, set them by hand.

Mailkick.services = [
  Mailkick::Service::SendGridV2.new(api_key: "API_KEY"),
  Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID")
]

Reference

Access the subscription model directly

Mailkick::Subscription.all

Upgrading

1.0

Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate:

  1. Add a table to store subscriptions

rails generate mailkick:install
rails db:migrate

  1. Change the following methods in your code:
  • mailkick_user to has_subscriptions
  • User.not_opted_out to User.subscribed(list)
  • opt_in to subscribe(list)
  • opt_out to unsubscribe(list)
  • opted_out? to !subscribed?(list)
  1. Add a user and list to mailkick_unsubscribe_url

mailkick_unsubscribe_url(user, list)

  1. Migrate data for each of your lists

opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil)
opted_out_users = Mailkick::Legacy.opted_out_users(list: nil)

User.find_in_batches do |users|
  users.reject! { |u| opted_out_emails.include?(u.email) }
  users.reject! { |u| opted_out_users.include?(u) }

  now = Time.now
  records =
    users.map do |user|
      {
        subscriber_type: user.class.name,
        subscriber_id: user.id,
        list: "sales",
        created_at: now,
        updated_at: now
      }
    end

  # use create! for Active Record < 6
  Mailkick::Subscription.insert_all!(records)
end

  1. Drop the mailkick_opt_outs table

drop_table :mailkick_opt_outs

Also, if you use Mailkick.fetch_opt_outs, add a method to handle opt outs.

History

Contributing

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

To get started with development and testing:

git clone https://github.com/ankane/mailkick.git
cd mailkick
bundle install
bundle exec rake test