README.md in mailkick-0.4.3 vs README.md in mailkick-1.0.0

- old
+ new

@@ -1,93 +1,113 @@ # Mailkick -Email unsubscribes for Rails +Email subscriptions for Rails - Add one-click unsubscribe links to your emails - Fetch bounces and spam reports from your email service -- Gracefully handles email address changes +**Mailkick 1.0 was recently released** - see [how to upgrade](#upgrading) + :postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for analytics -[![Build Status](https://travis-ci.org/ankane/mailkick.svg?branch=master)](https://travis-ci.org/ankane/mailkick) +[![Build Status](https://github.com/ankane/mailkick/workflows/build/badge.svg?branch=master)](https://github.com/ankane/mailkick/actions) ## Installation Add this line to your application’s Gemfile: ```ruby gem 'mailkick' ``` -And run the generator. This creates a model to store opt-outs. +And run the generator. This creates a table to store subscriptions. ```sh +bundle install rails generate mailkick:install rails db:migrate ``` -## How It Works +## Getting Started -Add an unsubscribe link to your emails. +Add `has_subscriptions` to your user model: -#### Text - -```erb -Unsubscribe: <%= mailkick_unsubscribe_url %> +```ruby +class User < ApplicationRecord + has_subscriptions +end ``` -#### HTML +Subscribe to a list -```erb -<%= link_to "Unsubscribe", mailkick_unsubscribe_url %> +```ruby +user.subscribe("sales") ``` -When a user unsubscribes, he or she is taken to a mobile-friendly page and given the option to resubscribe. +Unsubscribe from a list -To customize the view, run: - -```sh -rails generate mailkick:views +```ruby +user.unsubscribe("sales") ``` -which copies the view into `app/views/mailkick`. +Check if subscribed -## Sending Emails +```ruby +user.subscribed?("sales") +``` -Before sending marketing emails, make sure the user has not opted out. +Get subscribers for a list (use this for sending emails) -Add the following method to models with email addresses. - ```ruby -class User < ApplicationRecord - mailkick_user -end +User.subscribed("sales") ``` -Get all users who have opted out +## Unsubscribe Links -```ruby -User.opted_out +Add an unsubscribe link to your emails. For HTML emails, use: + +```erb +<%= link_to "Unsubscribe", mailkick_unsubscribe_url(@user, "sales") %> ``` -And those who have not - send to these people +For text emails, use: -```ruby -User.not_opted_out +```erb +Unsubscribe: <%= mailkick_unsubscribe_url(@user, "sales") %> ``` -Check one user +When a user unsubscribes, they are taken to a mobile-friendly page and given the option to resubscribe. To customize the view, run: -```ruby -user.opted_out? +```sh +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. +Fetch bounces, spam reports, and unsubscribes from your email service. Create `config/initializers/mailkick.rb` with a method to handle opt outs. ```ruby +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.updated_at < opt_out[:time] + end + end +end +``` + +And run: + +```ruby Mailkick.fetch_opt_outs ``` The following services are supported: @@ -108,10 +128,12 @@ gem 'aws-sdk-sesv2' ``` And [configure your AWS credentials](https://github.com/aws/aws-sdk-ruby#configuration). Requires `ses:ListSuppressedDestinations` permission. +If you started using Amazon SES [before November 25, 2019](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email-suppression-list.html#sending-email-suppression-list-considerations), you have to manually [enable account-level suppression list feature](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_PutAccountSuppressionAttributes.html). + #### Mailchimp Add the gem ```ruby @@ -169,79 +191,77 @@ Mailkick::Service::SendGridV2.new(api_key: "API_KEY"), Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID") ] ``` -## Multiple Lists +## Reference -You may want to split your emails into multiple categories, like sale emails and order reminders. Set the list in the url: +Access the subscription model directly ```ruby -mailkick_unsubscribe_url(list: "order_reminders") +Mailkick::Subscription.all ``` -Pass the `list` option to methods. +## Upgrading -```ruby -User.opted_out(list: "order_reminders") -User.not_opted_out(list: "order_reminders") -user.opted_out?(list: "order_reminders") -``` +### 1.0 -### Opt-In Lists +Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate: -For opt-in lists, you’ll need to manage the subscribers yourself. +1. Add a table to store subscriptions -Check opt-ins against the opt-outs - -```ruby -User.where(send_me_sales: true).not_opted_out(list: "sales") +```sh +rails generate mailkick:install +rails db:migrate ``` -Check one user +2. Change the following methods in your code: -```ruby -user.send_me_sales && !user.opted_out?(list: "sales") -``` +- `mailkick_user` to `has_subscriptions` +- `User.not_opted_out` to `User.subscribed(list)` +- `opt_in` to `subscribe(list)` +- `opt_out` to `unsubscribe(list)` -## Bonus +3. Add a user and list to `mailkick_unsubscribe_url` -More great gems for email - -- [Roadie](https://github.com/Mange/roadie) - inline CSS -- [Letter Opener](https://github.com/ryanb/letter_opener) - preview email in development - -## Reference - -Change how the user is determined - ```ruby -Mailkick.user_method = ->(email) { User.find_by(email: email) } +mailkick_unsubscribe_url(user, list) ``` -Use a different email field +4. Migrate data for each of your lists ```ruby -mailkick_user email_key: :email_address -``` +opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil) +opted_out_users = Mailkick::Legacy.opted_out_users(list: nil) -Unsubscribe +User.find_in_batches do |users| + users.reject! { |u| opted_out_emails.include?(u.email) } + users.reject! { |u| opted_out_users.include?(u) } -```ruby -user.opt_out -``` + 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 -Resubscribe - -```ruby -user.opt_in + # use create! for Active Record < 6 + Mailkick::Subscription.insert_all!(records) +end ``` -Access the opt-out model directly +5. Drop the `mailkick_opt_outs` table ```ruby -Mailkick::OptOut.all +drop_table :mailkick_opt_outs ``` + +Also, if you use `Mailkick.fetch_opt_outs`, [add a method](#bounces-and-spam-reports) to handle opt outs. ## History View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)