mailkick 0.3.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -18
  3. data/LICENSE.txt +1 -1
  4. data/README.md +153 -85
  5. data/app/controllers/mailkick/subscriptions_controller.rb +38 -20
  6. data/app/models/mailkick/opt_out.rb +1 -1
  7. data/app/models/mailkick/subscription.rb +9 -0
  8. data/app/views/mailkick/subscriptions/show.html.erb +1 -1
  9. data/lib/generators/mailkick/install_generator.rb +4 -21
  10. data/lib/generators/mailkick/templates/install.rb.tt +11 -0
  11. data/lib/mailkick.rb +23 -69
  12. data/lib/mailkick/engine.rb +0 -4
  13. data/lib/mailkick/legacy.rb +70 -0
  14. data/lib/mailkick/model.rb +11 -21
  15. data/lib/mailkick/service.rb +1 -16
  16. data/lib/mailkick/service/aws_ses.rb +47 -0
  17. data/lib/mailkick/service/postmark.rb +41 -0
  18. data/lib/mailkick/service/sendgrid.rb +4 -1
  19. data/lib/mailkick/service/sendgrid_v2.rb +52 -0
  20. data/lib/mailkick/url_helper.rb +8 -0
  21. data/lib/mailkick/version.rb +1 -1
  22. metadata +20 -184
  23. data/.gitignore +0 -25
  24. data/.travis.yml +0 -16
  25. data/Gemfile +0 -6
  26. data/Rakefile +0 -9
  27. data/app/helpers/mailkick/url_helper.rb +0 -15
  28. data/lib/generators/mailkick/templates/install.rb +0 -14
  29. data/mailkick.gemspec +0 -32
  30. data/test/gemfiles/actionmailer42.gemfile +0 -6
  31. data/test/gemfiles/actionmailer50.gemfile +0 -6
  32. data/test/gemfiles/actionmailer51.gemfile +0 -6
  33. data/test/internal/app/mailers/user_mailer.rb +0 -7
  34. data/test/internal/app/models/user.rb +0 -3
  35. data/test/internal/app/views/user_mailer/welcome.html.erb +0 -1
  36. data/test/internal/app/views/user_mailer/welcome.text.erb +0 -1
  37. data/test/internal/config/database.yml +0 -3
  38. data/test/internal/db/schema.rb +0 -16
  39. data/test/mailkick_test.rb +0 -29
  40. data/test/test_helper.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a36d760e07c5d02d2a0a685c4ced2e9075eb0e272f7814b08fd477fd282a9a0
4
- data.tar.gz: 6038e41c31a36c14fd7438fc870531773fb6098d0932e72b4d187dc9c51ef634
3
+ metadata.gz: 2ff139814252a1c4ec153cc81f311dd5d8c1745a4970aaab8cb2164df4d4692d
4
+ data.tar.gz: 1e4700dc2dbb96dcb09c4c79c00a837de387c8712db72c3bc13150ea94355da2
5
5
  SHA512:
6
- metadata.gz: f1f4229e0f2191437d1cda0ef791683908cbc9d5a98519ba8fd00f9250b6f64f9aa0f9ec0df8be05c62506bf6d7e407bf610643d7f2faf979c066d8e977f7efc
7
- data.tar.gz: b2801fbe7e9bb5de9d3eda275e7b162b68ccf5ff3ad352cb5b4462a3e617edb44cae177652d3c7ecda70f7dd35abc2755cc958219e761510270f32605f7eae91
6
+ metadata.gz: f28ec4a1bb1fa022ad4bd9a250a45650562db467a7c6d14f0150e5f9c8137cd766376a605c0304092ff7036d2efca22ae95e3d61e5693d40f616205b54aedb72
7
+ data.tar.gz: 5eb0a1544b00da879c77c2919501c2b21f6c4916e7bc1b710ad271c33ba6cd9cd6607d5d8c06f64380ce825f11187ff841deb21c58cd9ee4a8af3536ff3f594b
data/CHANGELOG.md CHANGED
@@ -1,79 +1,102 @@
1
- ## 0.3.1
1
+ ## 1.0.0 (2021-06-03)
2
+
3
+ - Switched from opt-outs to subscriptions
4
+
5
+ ## 0.4.3 (2020-11-01)
6
+
7
+ - Added support for AWS SES
8
+
9
+ ## 0.4.2 (2020-04-06)
10
+
11
+ - Added support for official SendGrid gem
12
+ - Fixed deprecation warning
13
+
14
+ ## 0.4.1 (2019-10-27)
15
+
16
+ - Added Postmark support
17
+
18
+ ## 0.4.0 (2019-07-15)
19
+
20
+ - Fixed error with model methods and `email_key` option
21
+ - Fixed bug with `opted_out` scope
22
+ - Dropped support for Action Mailer 4.2
23
+
24
+ ## 0.3.1 (2018-04-21)
2
25
 
3
26
  - Fixed `Secret should not be nil` error in Rails 5.2
4
27
  - Gracefully handle missing email
5
28
  - Added `user` option to `mailkick_unsubscribe_url`
6
29
 
7
- ## 0.3.0
30
+ ## 0.3.0 (2018-04-20)
8
31
 
9
32
  - Improved performance
10
33
  - Fixed `Subscription not found` for Rails 5.2
11
34
  - Use `references` in migration
12
35
  - Use `smtp_settings[:domain]` for Mailgun
13
- - Dropped support for ActionMailer < 4.2
36
+ - Dropped support for Action Mailer < 4.2
14
37
 
15
- ## 0.2.1
38
+ ## 0.2.1 (2017-10-30)
16
39
 
17
40
  - Fixed errors with Rails 5+
18
41
  - Fixed errors with the latest version of Gibbon
19
42
 
20
- ## 0.2.0
43
+ ## 0.2.0 (2017-05-01)
21
44
 
22
45
  - Added support for Rails 5.1
23
46
 
24
- ## 0.1.6
47
+ ## 0.1.6 (2017-01-10)
25
48
 
26
49
  - Fixed error with frozen strings
27
50
 
28
- ## 0.1.5
51
+ ## 0.1.5 (2016-12-06)
29
52
 
30
53
  - Use `safely`
31
54
  - Only discover services if not manually set
32
55
  - Added `mount` option
33
56
 
34
- ## 0.1.4
57
+ ## 0.1.4 (2016-02-20)
35
58
 
36
59
  - Use `Module#prepend` instead of `alias_method_chain`
37
60
 
38
- ## 0.1.3
61
+ ## 0.1.3 (2015-06-29)
39
62
 
40
63
  - Fixed issue with double escaping tokens
41
64
 
42
- ## 0.1.2
65
+ ## 0.1.2 (2015-06-07)
43
66
 
44
67
  - Added support for Mailgun
45
68
 
46
- ## 0.1.1
69
+ ## 0.1.1 (2015-01-31)
47
70
 
48
71
  - Fixed tokens with `+` in them
49
72
 
50
- ## 0.1.0
73
+ ## 0.1.0 (2014-08-31)
51
74
 
52
75
  - Fixed secret token for Rails 4.1
53
76
 
54
- ## 0.0.6
77
+ ## 0.0.6 (2014-05-09)
55
78
 
56
79
  - Rails 3 fix
57
80
 
58
- ## 0.0.5
81
+ ## 0.0.5 (2014-05-05)
59
82
 
60
83
  - Fixed bug with subscriptions page
61
84
 
62
- ## 0.0.4
85
+ ## 0.0.4 (2014-05-05)
63
86
 
64
87
  - Added `email_key` option to `mailkick_user`
65
88
 
66
- ## 0.0.3
89
+ ## 0.0.3 (2014-05-04)
67
90
 
68
91
  - Added support for multiple lists
69
92
  - Changed `mailkick_user` method names - sorry early adopters :(
70
93
 
71
- ## 0.0.2
94
+ ## 0.0.2 (2014-05-04)
72
95
 
73
96
  - Added Mailchimp service
74
97
  - Fixed Mandrill service
75
98
  - Added `uniq` to `subscribed` scope
76
99
 
77
- ## 0.0.1
100
+ ## 0.0.1 (2014-05-04)
78
101
 
79
102
  - First release
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Andrew Kane
1
+ Copyright (c) 2014-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # Mailkick
2
2
 
3
- Email subscriptions made easy
3
+ Email subscriptions for Rails
4
4
 
5
5
  - Add one-click unsubscribe links to your emails
6
6
  - Fetch bounces and spam reports from your email service
7
- - Gracefully handles email address changes
7
+
8
+ **Mailkick 1.0 was recently released** - see [how to upgrade](#upgrading)
8
9
 
9
10
  :postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for analytics
10
11
 
11
- [![Build Status](https://travis-ci.org/ankane/mailkick.svg?branch=master)](https://travis-ci.org/ankane/mailkick)
12
+ [![Build Status](https://github.com/ankane/mailkick/workflows/build/badge.svg?branch=master)](https://github.com/ankane/mailkick/actions)
12
13
 
13
14
  ## Installation
14
15
 
@@ -18,191 +19,249 @@ Add this line to your application’s Gemfile:
18
19
  gem 'mailkick'
19
20
  ```
20
21
 
21
- And run the generator. This creates a model to store opt-outs.
22
+ And run the generator. This creates a table to store subscriptions.
22
23
 
23
24
  ```sh
25
+ bundle install
24
26
  rails generate mailkick:install
25
27
  rails db:migrate
26
28
  ```
27
29
 
28
- ## How It Works
29
-
30
- Add an unsubscribe link to your emails.
30
+ ## Getting Started
31
31
 
32
- #### Text
32
+ Add `has_subscriptions` to your user model:
33
33
 
34
- ```erb
35
- Unsubscribe: <%= mailkick_unsubscribe_url %>
34
+ ```ruby
35
+ class User < ApplicationRecord
36
+ has_subscriptions
37
+ end
36
38
  ```
37
39
 
38
- #### HTML
40
+ Subscribe to a list
39
41
 
40
- ```erb
41
- <%= link_to "Unsubscribe", mailkick_unsubscribe_url %>
42
+ ```ruby
43
+ user.subscribe("sales")
42
44
  ```
43
45
 
44
- When a user unsubscribes, he or she is taken to a mobile-friendly page and given the option to resubscribe.
46
+ Unsubscribe from a list
45
47
 
46
- To customize the view, run:
47
-
48
- ```sh
49
- rails generate mailkick:views
48
+ ```ruby
49
+ user.unsubscribe("sales")
50
50
  ```
51
51
 
52
- which copies the view into `app/views/mailkick`.
52
+ Check if subscribed
53
53
 
54
- ## Sending Emails
55
-
56
- Before sending marketing emails, make sure the user has not opted out.
54
+ ```ruby
55
+ user.subscribed?("sales")
56
+ ```
57
57
 
58
- Add the following method to models with email addresses.
58
+ Get subscribers for a list (use this for sending emails)
59
59
 
60
60
  ```ruby
61
- class User < ApplicationRecord
62
- mailkick_user
63
- end
61
+ User.subscribed("sales")
64
62
  ```
65
63
 
66
- Get all users who have opted out
64
+ ## Unsubscribe Links
67
65
 
68
- ```ruby
69
- User.opted_out
66
+ Add an unsubscribe link to your emails. For HTML emails, use:
67
+
68
+ ```erb
69
+ <%= link_to "Unsubscribe", mailkick_unsubscribe_url(@user, "sales") %>
70
70
  ```
71
71
 
72
- And those who have not - send to these people
72
+ For text emails, use:
73
73
 
74
- ```ruby
75
- User.not_opted_out
74
+ ```erb
75
+ Unsubscribe: <%= mailkick_unsubscribe_url(@user, "sales") %>
76
76
  ```
77
77
 
78
- Check one user
78
+ When a user unsubscribes, they are taken to a mobile-friendly page and given the option to resubscribe. To customize the view, run:
79
79
 
80
- ```ruby
81
- user.opted_out?
80
+ ```sh
81
+ rails generate mailkick:views
82
82
  ```
83
83
 
84
+ which copies the view into `app/views/mailkick`.
85
+
84
86
  ## Bounces and Spam Reports
85
87
 
86
- Fetch bounces, spam reports, and unsubscribes from your email service.
88
+ Fetch bounces, spam reports, and unsubscribes from your email service. Create `config/initializers/mailkick.rb` with a method to handle opt outs.
87
89
 
88
90
  ```ruby
89
- Mailkick.fetch_opt_outs
91
+ Mailkick.process_opt_outs_method = lambda do |opt_outs|
92
+ emails = opt_outs.map { |v| v[:email] }
93
+ subscribers = User.includes(:mailkick_subscriptions).where(email: emails).index_by(&:email)
94
+
95
+ opt_outs.each do |opt_out|
96
+ subscriber = subscribers[opt_out[:email]]
97
+ next unless subscriber
98
+
99
+ subscriber.mailkick_subscriptions.each do |subscription|
100
+ subscription.destroy if subscription.updated_at < opt_out[:time]
101
+ end
102
+ end
103
+ end
90
104
  ```
91
105
 
92
- #### Sendgrid
93
-
94
- Add the gem
106
+ And run:
95
107
 
96
108
  ```ruby
97
- gem 'sendgrid_toolkit'
109
+ Mailkick.fetch_opt_outs
98
110
  ```
99
111
 
100
- Be sure `ENV["SENDGRID_USERNAME"]` and `ENV["SENDGRID_PASSWORD"]` are set.
112
+ The following services are supported:
101
113
 
102
- #### Mandrill
114
+ - [AWS SES](#aws-ses)
115
+ - [Mailchimp](#mailchimp)
116
+ - [Mailgun](#mailgun)
117
+ - [Mandrill](#mandrill)
118
+ - [Postmark](#postmark)
119
+ - [SendGrid](#sendgrid)
120
+
121
+ Will gladly accept pull requests for others.
122
+
123
+ #### AWS SES
124
+
125
+ Add the gem
103
126
 
104
127
  ```ruby
105
- gem 'mandrill-api'
128
+ gem 'aws-sdk-sesv2'
106
129
  ```
107
130
 
108
- Be sure `ENV["MANDRILL_APIKEY"]` is set.
131
+ And [configure your AWS credentials](https://github.com/aws/aws-sdk-ruby#configuration). Requires `ses:ListSuppressedDestinations` permission.
132
+
133
+ 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).
109
134
 
110
135
  #### Mailchimp
111
136
 
137
+ Add the gem
138
+
112
139
  ```ruby
113
140
  gem 'gibbon', '>= 2'
114
141
  ```
115
142
 
116
- Be sure `ENV["MAILCHIMP_API_KEY"]` and `ENV["MAILCHIMP_LIST_ID"]` are set.
143
+ And set `ENV["MAILCHIMP_API_KEY"]` and `ENV["MAILCHIMP_LIST_ID"]`.
117
144
 
118
145
  #### Mailgun
119
146
 
147
+ Add the gem
148
+
120
149
  ```ruby
121
150
  gem 'mailgun-ruby'
122
151
  ```
123
152
 
124
- Be sure `ENV["MAILGUN_API_KEY"]` is set.
153
+ And set `ENV["MAILGUN_API_KEY"]`.
125
154
 
126
- #### Other
127
-
128
- Will gladly accept pull requests.
129
-
130
- ### Advanced
155
+ #### Mandrill
131
156
 
132
- For more control over services, set them by hand.
157
+ Add the gem
133
158
 
134
159
  ```ruby
135
- Mailkick.services = [
136
- Mailkick::Service::Sendgrid.new(api_key: "API_KEY"),
137
- Mailkick::Service::Mandrill.new(api_key: "API_KEY")
138
- ]
160
+ gem 'mandrill-api'
139
161
  ```
140
162
 
141
- ## Multiple Lists
163
+ And set `ENV["MANDRILL_APIKEY"]`.
164
+
165
+ #### Postmark
142
166
 
143
- You may want to split your emails into multiple categories, like sale emails and order reminders. Set the list in the url:
167
+ Add the gem
144
168
 
145
169
  ```ruby
146
- mailkick_unsubscribe_url(list: "order_reminders")
170
+ gem 'postmark'
147
171
  ```
148
172
 
149
- Pass the `list` option to methods.
173
+ And set `ENV["POSTMARK_API_KEY"]`.
174
+
175
+ #### SendGrid
176
+
177
+ Add the gem
150
178
 
151
179
  ```ruby
152
- User.opted_out(list: "order_reminders")
153
- User.not_opted_out(list: "order_reminders")
154
- user.opted_out?(list: "order_reminders")
180
+ gem 'sendgrid-ruby'
155
181
  ```
156
182
 
157
- ### Opt-In Lists
183
+ And set `ENV["SENDGRID_API_KEY"]`. The API key requires only the `Suppressions` permission.
158
184
 
159
- For opt-in lists, you’ll need to manage the subscribers yourself.
185
+ ### Advanced
160
186
 
161
- Check opt-ins against the opt-outs
187
+ For more control over services, set them by hand.
162
188
 
163
189
  ```ruby
164
- User.where(send_me_sales: true).not_opted_out(list: "sales")
190
+ Mailkick.services = [
191
+ Mailkick::Service::SendGridV2.new(api_key: "API_KEY"),
192
+ Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID")
193
+ ]
165
194
  ```
166
195
 
167
- Check one user
196
+ ## Reference
197
+
198
+ Access the subscription model directly
168
199
 
169
200
  ```ruby
170
- user.send_me_sales && !user.opted_out?(list: "sales")
201
+ Mailkick::Subscription.all
171
202
  ```
172
203
 
173
- ## Bonus
204
+ ## Upgrading
174
205
 
175
- More great gems for email
206
+ ### 1.0
176
207
 
177
- - [Roadie](https://github.com/Mange/roadie) - inline CSS
178
- - [Letter Opener](https://github.com/ryanb/letter_opener) - preview email in development
208
+ Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate:
179
209
 
180
- ## Reference
181
-
182
- Change how the user is determined
210
+ 1. Add a table to store subscriptions
183
211
 
184
- ```ruby
185
- Mailkick.user_method = ->(email) { User.find_by(email: email) }
212
+ ```sh
213
+ rails generate mailkick:install
214
+ rails db:migrate
186
215
  ```
187
216
 
188
- Use a different email field
217
+ 2. Change the following methods in your code:
218
+
219
+ - `mailkick_user` to `has_subscriptions`
220
+ - `User.not_opted_out` to `User.subscribed(list)`
221
+ - `opt_in` to `subscribe(list)`
222
+ - `opt_out` to `unsubscribe(list)`
223
+
224
+ 3. Add a user and list to `mailkick_unsubscribe_url`
189
225
 
190
226
  ```ruby
191
- mailkick_user email_key: :email_address
227
+ mailkick_unsubscribe_url(user, list)
192
228
  ```
193
229
 
194
- Unsubscribe
230
+ 4. Migrate data for each of your lists
195
231
 
196
232
  ```ruby
197
- user.opt_out
233
+ opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil)
234
+ opted_out_users = Mailkick::Legacy.opted_out_users(list: nil)
235
+
236
+ User.find_in_batches do |users|
237
+ users.reject! { |u| opted_out_emails.include?(u.email) }
238
+ users.reject! { |u| opted_out_users.include?(u) }
239
+
240
+ now = Time.now
241
+ records =
242
+ users.map do |user|
243
+ {
244
+ subscriber_type: user.class.name,
245
+ subscriber_id: user.id,
246
+ list: "sales",
247
+ created_at: now,
248
+ updated_at: now
249
+ }
250
+ end
251
+
252
+ # use create! for Active Record < 6
253
+ Mailkick::Subscription.insert_all!(records)
254
+ end
198
255
  ```
199
256
 
200
- Resubscribe
257
+ 5. Drop the `mailkick_opt_outs` table
201
258
 
202
259
  ```ruby
203
- user.opt_in
260
+ drop_table :mailkick_opt_outs
204
261
  ```
205
262
 
263
+ Also, if you use `Mailkick.fetch_opt_outs`, [add a method](#bounces-and-spam-reports) to handle opt outs.
264
+
206
265
  ## History
207
266
 
208
267
  View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
@@ -215,3 +274,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
215
274
  - Fix bugs and [submit pull requests](https://github.com/ankane/mailkick/pulls)
216
275
  - Write, clarify, or fix documentation
217
276
  - Suggest or add new features
277
+
278
+ To get started with development and testing:
279
+
280
+ ```sh
281
+ git clone https://github.com/ankane/mailkick.git
282
+ cd mailkick
283
+ bundle install
284
+ bundle exec rake test
285
+ ```