mailkick 1.2.2 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +12 -64
- data/app/controllers/mailkick/subscriptions_controller.rb +8 -1
- data/config/routes.rb +1 -1
- data/lib/mailkick/engine.rb +1 -1
- data/lib/mailkick/model.rb +1 -1
- data/lib/mailkick/service/postmark.rb +1 -1
- data/lib/mailkick/url_helper.rb +6 -1
- data/lib/mailkick/version.rb +1 -1
- data/lib/mailkick.rb +2 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a9bd60adb2d9f1ce219b451369a4c5547f3dea808fa3123e31fb317fccfe843
|
4
|
+
data.tar.gz: 9fab1707325fdc093ddc9123c94d331d6c7b4b17ceaae1d5f8760cdb30b4f74b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f1160fff3f3ef81e4ff3d2ab9fae04076e84db93f95ab17f1655a99185331c22783c262dac0433484575371bebedc05750744a1434fdfa6f9d32cac87609050
|
7
|
+
data.tar.gz: f0cfecb317f7fc74848ec9479248f635f268194bfd9d4c38ecda06cb3ec9815eb9c17d8b9044ca38ca0dd459a5e3fe9d8acfefd3d7953ded84b132bb5286a9ff
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 1.3.1 (2024-09-09)
|
2
|
+
|
3
|
+
- Fixed deprecation warning with Rails 7.1
|
4
|
+
|
5
|
+
## 1.3.0 (2024-01-18)
|
6
|
+
|
7
|
+
- Added support for one-click unsubscribe headers (RFC 8058)
|
8
|
+
|
1
9
|
## 1.2.2 (2023-10-30)
|
2
10
|
|
3
11
|
- Fixed error when secret key base set with `SECRET_KEY_BASE_DUMMY`
|
data/README.md
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Email subscriptions for Rails
|
4
4
|
|
5
|
-
- Add one-click unsubscribe links to your emails
|
5
|
+
- Add one-click unsubscribe links and headers to your emails
|
6
6
|
- Fetch bounces and spam reports from your email service
|
7
7
|
|
8
8
|
:postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for analytics
|
9
9
|
|
10
|
-
[![Build Status](https://github.com/ankane/mailkick/workflows/build/badge.svg
|
10
|
+
[![Build Status](https://github.com/ankane/mailkick/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/mailkick/actions)
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -81,6 +81,16 @@ rails generate mailkick:views
|
|
81
81
|
|
82
82
|
which copies the view into `app/views/mailkick`.
|
83
83
|
|
84
|
+
## Unsubscribe Headers
|
85
|
+
|
86
|
+
For one-click unsubscribe headers ([RFC 8058](https://datatracker.ietf.org/doc/html/rfc8058)), create `config/initializers/mailkick.rb` with:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
Mailkick.headers = true
|
90
|
+
```
|
91
|
+
|
92
|
+
Headers will automatically be added to emails that call `mailkick_unsubscribe_url`.
|
93
|
+
|
84
94
|
## Bounces and Spam Reports
|
85
95
|
|
86
96
|
Fetch bounces, spam reports, and unsubscribes from your email service. Create `config/initializers/mailkick.rb` with a method to handle opt outs.
|
@@ -199,68 +209,6 @@ Access the subscription model directly
|
|
199
209
|
Mailkick::Subscription.all
|
200
210
|
```
|
201
211
|
|
202
|
-
## Upgrading
|
203
|
-
|
204
|
-
### 1.0
|
205
|
-
|
206
|
-
Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate:
|
207
|
-
|
208
|
-
1. Add a table to store subscriptions
|
209
|
-
|
210
|
-
```sh
|
211
|
-
rails generate mailkick:install
|
212
|
-
rails db:migrate
|
213
|
-
```
|
214
|
-
|
215
|
-
2. Change the following methods in your code:
|
216
|
-
|
217
|
-
- `mailkick_user` to `has_subscriptions`
|
218
|
-
- `User.not_opted_out` to `User.subscribed(list)`
|
219
|
-
- `opt_in` to `subscribe(list)`
|
220
|
-
- `opt_out` to `unsubscribe(list)`
|
221
|
-
- `opted_out?` to `!subscribed?(list)`
|
222
|
-
|
223
|
-
3. Add a user and list to `mailkick_unsubscribe_url`
|
224
|
-
|
225
|
-
```ruby
|
226
|
-
mailkick_unsubscribe_url(user, list)
|
227
|
-
```
|
228
|
-
|
229
|
-
4. Migrate data for each of your lists
|
230
|
-
|
231
|
-
```ruby
|
232
|
-
opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil)
|
233
|
-
opted_out_users = Mailkick::Legacy.opted_out_users(list: nil)
|
234
|
-
|
235
|
-
User.find_in_batches do |users|
|
236
|
-
users.reject! { |u| opted_out_emails.include?(u.email) }
|
237
|
-
users.reject! { |u| opted_out_users.include?(u) }
|
238
|
-
|
239
|
-
now = Time.now
|
240
|
-
records =
|
241
|
-
users.map do |user|
|
242
|
-
{
|
243
|
-
subscriber_type: user.class.name,
|
244
|
-
subscriber_id: user.id,
|
245
|
-
list: "sales",
|
246
|
-
created_at: now,
|
247
|
-
updated_at: now
|
248
|
-
}
|
249
|
-
end
|
250
|
-
|
251
|
-
# use create! for Active Record < 6
|
252
|
-
Mailkick::Subscription.insert_all!(records)
|
253
|
-
end
|
254
|
-
```
|
255
|
-
|
256
|
-
5. Drop the `mailkick_opt_outs` table
|
257
|
-
|
258
|
-
```ruby
|
259
|
-
drop_table :mailkick_opt_outs
|
260
|
-
```
|
261
|
-
|
262
|
-
Also, if you use `Mailkick.fetch_opt_outs`, [add a method](#bounces-and-spam-reports) to handle opt outs.
|
263
|
-
|
264
212
|
## History
|
265
213
|
|
266
214
|
View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Mailkick
|
2
2
|
class SubscriptionsController < ActionController::Base
|
3
3
|
protect_from_forgery with: :exception
|
4
|
+
skip_forgery_protection only: [:unsubscribe]
|
4
5
|
|
5
6
|
before_action :set_subscription
|
6
7
|
|
@@ -12,7 +13,13 @@ module Mailkick
|
|
12
13
|
|
13
14
|
Mailkick::Legacy.opt_out(legacy_options) if Mailkick::Legacy.opt_outs?
|
14
15
|
|
15
|
-
|
16
|
+
if request.post? && params["List-Unsubscribe"] == "One-Click"
|
17
|
+
# must not redirect according to RFC 8058
|
18
|
+
# could render show action instead
|
19
|
+
render plain: "Unsubscribe successful"
|
20
|
+
else
|
21
|
+
redirect_to subscription_path(params[:id])
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
25
|
def subscribe
|
data/config/routes.rb
CHANGED
data/lib/mailkick/engine.rb
CHANGED
@@ -13,7 +13,7 @@ module Mailkick
|
|
13
13
|
creds =
|
14
14
|
if app.respond_to?(:credentials) && app.credentials.secret_key_base
|
15
15
|
app.credentials
|
16
|
-
elsif app.respond_to?(:secrets)
|
16
|
+
elsif app.respond_to?(:secrets) && (Rails::VERSION::STRING.to_f < 7.1 || app.config.paths["config/secrets"].existent.any?)
|
17
17
|
app.secrets
|
18
18
|
else
|
19
19
|
app.config
|
data/lib/mailkick/model.rb
CHANGED
@@ -3,7 +3,7 @@ module Mailkick
|
|
3
3
|
def has_subscriptions
|
4
4
|
class_eval do
|
5
5
|
has_many :mailkick_subscriptions, class_name: "Mailkick::Subscription", as: :subscriber
|
6
|
-
scope :subscribed, ->
|
6
|
+
scope :subscribed, ->(list) { joins(:mailkick_subscriptions).where(mailkick_subscriptions: {list: list}) }
|
7
7
|
|
8
8
|
def subscribe(list)
|
9
9
|
mailkick_subscriptions.where(list: list).first_or_create!
|
data/lib/mailkick/url_helper.rb
CHANGED
@@ -2,7 +2,12 @@ module Mailkick
|
|
2
2
|
module UrlHelper
|
3
3
|
def mailkick_unsubscribe_url(subscriber, list, **options)
|
4
4
|
token = Mailkick.generate_token(subscriber, list)
|
5
|
-
mailkick.unsubscribe_subscription_url(token, **options)
|
5
|
+
url = mailkick.unsubscribe_subscription_url(token, **options)
|
6
|
+
if Mailkick.headers && headers["List-Unsubscribe"].nil?
|
7
|
+
headers["List-Unsubscribe-Post"] ||= "List-Unsubscribe=One-Click"
|
8
|
+
headers["List-Unsubscribe"] = "<#{url}>"
|
9
|
+
end
|
10
|
+
url
|
6
11
|
end
|
7
12
|
end
|
8
13
|
end
|
data/lib/mailkick/version.rb
CHANGED
data/lib/mailkick.rb
CHANGED
@@ -24,12 +24,13 @@ require_relative "mailkick/version"
|
|
24
24
|
require_relative "mailkick/engine" if defined?(Rails)
|
25
25
|
|
26
26
|
module Mailkick
|
27
|
-
mattr_accessor :services, :mount, :process_opt_outs_method
|
27
|
+
mattr_accessor :services, :mount, :process_opt_outs_method, :headers
|
28
28
|
mattr_reader :secret_token
|
29
29
|
mattr_writer :message_verifier
|
30
30
|
self.services = []
|
31
31
|
self.mount = true
|
32
32
|
self.process_opt_outs_method = ->(_) { raise "process_opt_outs_method not defined" }
|
33
|
+
self.headers = false
|
33
34
|
|
34
35
|
def self.fetch_opt_outs
|
35
36
|
services.each(&:fetch_opt_outs)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
78
|
+
rubygems_version: 3.5.16
|
79
79
|
signing_key:
|
80
80
|
specification_version: 4
|
81
81
|
summary: Email subscriptions for Rails
|