Skip to content

ankane/mailkick

Repository files navigation

Mailkick

Email subscriptions for Rails

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

📮 Check out Ahoy Email for analytics

Build Status

Installation

Add this line to your application’s Gemfile:

gem "mailkick"

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

Subscribe to a list

user.subscribe("sales")

Unsubscribe from a list

user.unsubscribe("sales")

Check if subscribed

user.subscribed?("sales")

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

User.subscribed("sales")

Unsubscribe Links

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

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

For text emails, use:

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.

Unsubscribe Headers

For one-click unsubscribe headers (RFC 8058), create config/initializers/mailkick.rb with:

Mailkick.headers = true

Headers will automatically be added to emails that call mailkick_unsubscribe_url.

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

And run:

Mailkick.fetch_opt_outs

The following services are supported:

Will gladly accept pull requests for others.

AWS SES

Add the gem

gem "aws-sdk-sesv2"

And configure your AWS credentials. Requires ses:ListSuppressedDestinations permission.

If you started using Amazon SES before November 25, 2019, you have to manually enable account-level suppression list feature.

Mailchimp

Add the gem

gem "gibbon", ">= 2"

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

Mailgun

Add the gem

gem "mailgun-ruby"

And set ENV["MAILGUN_API_KEY"].

Mandrill

Add the gem

gem "mandrill-api"

And set ENV["MANDRILL_APIKEY"].

Postmark

Add the gem

gem "postmark"

And set ENV["POSTMARK_API_KEY"].

SendGrid

Add the gem

gem "sendgrid-ruby"

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

History

View the changelog

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