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)