mailkick 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +21 -32
- data/app/controllers/mailkick/subscriptions_controller.rb +3 -28
- data/lib/mailkick/model.rb +7 -28
- data/lib/mailkick/service.rb +6 -7
- data/lib/mailkick/version.rb +1 -1
- data/lib/mailkick.rb +64 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58457207d32f0dd9a131524e0a6461133c0fb702
|
4
|
+
data.tar.gz: ef4854e607a9a99da6513dfa823bb23b2c2f0162
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 253736c9f9387dd4703188189ace226a6aab066591a2a0091cfdc81e9dacc3d078219551b8a088974d0c6376e1ab472d9267a588a4951b463a38abb68b2b9264
|
7
|
+
data.tar.gz: 800b46251c5dc872ff2ae6eb95a437eb9dfe5ccc5fec8a23751d3f0a23fbc6b484b7ebea813eafbba2928821e64a2306278a74d86bdedb6c242d73f49ebe38b1
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -54,7 +54,7 @@ which copies the view into `app/views/mailkick`.
|
|
54
54
|
|
55
55
|
Before sending marketing emails, make sure the user has not opted out.
|
56
56
|
|
57
|
-
Add the following
|
57
|
+
Add the following method to models with email addresses.
|
58
58
|
|
59
59
|
```ruby
|
60
60
|
class User < ActiveRecord::Base
|
@@ -68,7 +68,7 @@ Get all users who have opted out
|
|
68
68
|
User.opted_out
|
69
69
|
```
|
70
70
|
|
71
|
-
And those who have not
|
71
|
+
And those who have not - send to these people
|
72
72
|
|
73
73
|
```ruby
|
74
74
|
User.not_opted_out
|
@@ -80,18 +80,6 @@ Check one user
|
|
80
80
|
user.opted_out?
|
81
81
|
```
|
82
82
|
|
83
|
-
Unsubscribe
|
84
|
-
|
85
|
-
```ruby
|
86
|
-
user.opt_out
|
87
|
-
```
|
88
|
-
|
89
|
-
Resubscribe
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
user.opt_in
|
93
|
-
```
|
94
|
-
|
95
83
|
## Bounces and Spam Reports
|
96
84
|
|
97
85
|
Fetch bounces, spam reports, and unsubscribes from your email service.
|
@@ -161,23 +149,8 @@ end
|
|
161
149
|
Pass the `list` option to methods.
|
162
150
|
|
163
151
|
```ruby
|
164
|
-
# scopes
|
165
152
|
User.opted_out(list: "order_reminders")
|
166
153
|
User.not_opted_out(list: "order_reminders")
|
167
|
-
|
168
|
-
# instance methods
|
169
|
-
user.opted_out?(list: "order_reminders")
|
170
|
-
user.opt_out(list: "order_reminders")
|
171
|
-
user.opt_in(list: "order_reminders")
|
172
|
-
```
|
173
|
-
|
174
|
-
Omitting list (`nil` list) means all lists - including future lists (think “Unsubscribe All”).
|
175
|
-
|
176
|
-
```ruby
|
177
|
-
# opted out of all lists?
|
178
|
-
user.opted_out?
|
179
|
-
|
180
|
-
# opted out of the order reminder list *or* all lists?
|
181
154
|
user.opted_out?(list: "order_reminders")
|
182
155
|
```
|
183
156
|
|
@@ -185,17 +158,15 @@ user.opted_out?(list: "order_reminders")
|
|
185
158
|
|
186
159
|
For opt-in lists, you’ll need to manage the subscribers yourself.
|
187
160
|
|
188
|
-
|
161
|
+
Check opt-ins against the opt-outs
|
189
162
|
|
190
163
|
```ruby
|
191
|
-
# opt-ins minus opt-outs
|
192
164
|
User.where(send_me_sales: true).not_opted_out(list: "sales")
|
193
165
|
```
|
194
166
|
|
195
167
|
Check one user
|
196
168
|
|
197
169
|
```ruby
|
198
|
-
# opted in and didn't opt out
|
199
170
|
user.send_me_sales && !user.opted_out?(list: "sales")
|
200
171
|
```
|
201
172
|
|
@@ -214,6 +185,24 @@ Change how the user is determined
|
|
214
185
|
Mailkick.user_method = proc {|email| User.where(email: email).first }
|
215
186
|
```
|
216
187
|
|
188
|
+
Use a different email field
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
mailkick_user email_key: :email_address
|
192
|
+
```
|
193
|
+
|
194
|
+
Unsubscribe
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
user.opt_out
|
198
|
+
```
|
199
|
+
|
200
|
+
Resubscribe
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
user.opt_in
|
204
|
+
```
|
205
|
+
|
217
206
|
## History
|
218
207
|
|
219
208
|
View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
|
@@ -6,27 +6,12 @@ module Mailkick
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def unsubscribe
|
9
|
-
|
10
|
-
Mailkick::OptOut.create! do |o|
|
11
|
-
o.email = @email
|
12
|
-
o.user = @user
|
13
|
-
o.reason = "unsubscribe"
|
14
|
-
o.list = @list
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
9
|
+
Mailkick.opt_out(email: @email, user: @user, list: @list)
|
18
10
|
redirect_to subscription_path(params[:id])
|
19
11
|
end
|
20
12
|
|
21
13
|
def subscribe
|
22
|
-
Mailkick
|
23
|
-
opt_out.active = false
|
24
|
-
opt_out.save!
|
25
|
-
end
|
26
|
-
if @user and @user.respond_to?(:opt_in)
|
27
|
-
@user.opt_in(@options)
|
28
|
-
end
|
29
|
-
|
14
|
+
Mailkick.opt_in(email: @email, user: @user, list: @list)
|
30
15
|
redirect_to subscription_path(params[:id])
|
31
16
|
end
|
32
17
|
|
@@ -48,17 +33,7 @@ module Mailkick
|
|
48
33
|
end
|
49
34
|
|
50
35
|
def opted_out?(options = {})
|
51
|
-
|
52
|
-
if @user and @user.respond_to?(:opted_out?)
|
53
|
-
@user.opted_out?(options)
|
54
|
-
else
|
55
|
-
relation = Mailkick::OptOut.where(email: @email, active: true)
|
56
|
-
if options[:list]
|
57
|
-
relation.where("list IS NULL OR list = ?", options[:list])
|
58
|
-
else
|
59
|
-
relation.where("list IS NULL")
|
60
|
-
end.any?
|
61
|
-
end
|
36
|
+
Mailkick.opted_out?(@options.merge(options))
|
62
37
|
end
|
63
38
|
helper_method :opted_out?
|
64
39
|
|
data/lib/mailkick/model.rb
CHANGED
@@ -2,53 +2,32 @@ module Mailkick
|
|
2
2
|
module Model
|
3
3
|
|
4
4
|
def mailkick_user(options = {})
|
5
|
+
email_key = options[:email_key] || :email
|
5
6
|
class_eval do
|
6
7
|
scope :opted_out, proc {|options = {}|
|
7
8
|
binds = [self.class.name, true]
|
8
9
|
if options[:list]
|
9
|
-
query = "(list IS NULL OR list = ?)"
|
10
|
+
query = "(mailkick_opt_outs.list IS NULL OR mailkick_opt_outs.list = ?)"
|
10
11
|
binds << options[:list]
|
11
12
|
else
|
12
|
-
query = "list IS NULL"
|
13
|
+
query = "mailkick_opt_outs.list IS NULL"
|
13
14
|
end
|
14
|
-
where("#{options[:not] ? "NOT " : ""}EXISTS(SELECT * FROM mailkick_opt_outs WHERE (#{table_name}
|
15
|
+
where("#{options[:not] ? "NOT " : ""}EXISTS(SELECT * FROM mailkick_opt_outs WHERE (#{table_name}.#{email_key} = mailkick_opt_outs.email OR (#{table_name}.#{primary_key} = mailkick_opt_outs.user_id AND mailkick_opt_outs.user_type = ?)) AND mailkick_opt_outs.active = ? AND #{query})", *binds)
|
15
16
|
}
|
16
17
|
scope :not_opted_out, proc {|options = {}|
|
17
18
|
opted_out(options.merge(not: true))
|
18
19
|
}
|
19
20
|
|
20
|
-
def opt_outs(options = {})
|
21
|
-
relation = Mailkick::OptOut.where("email = ? OR (user_id = ? AND user_type = ?)", email, id, self.class.name)
|
22
|
-
if options[:list]
|
23
|
-
relation.where("list IS NULL OR list = ?", options[:list])
|
24
|
-
else
|
25
|
-
relation.where(list: nil)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
21
|
def opted_out?(options = {})
|
30
|
-
|
22
|
+
Mailkick.opted_out?({email: email, user: self}.merge(options))
|
31
23
|
end
|
32
24
|
|
33
25
|
def opt_out(options = {})
|
34
|
-
|
35
|
-
OptOut.create! do |o|
|
36
|
-
o.email = email
|
37
|
-
o.user = self
|
38
|
-
o.reason = "unsubscribe"
|
39
|
-
o.list = options[:list]
|
40
|
-
o.save!
|
41
|
-
end
|
42
|
-
end
|
43
|
-
true
|
26
|
+
Mailkick.opt_out({email: email, user: self}.merge(options))
|
44
27
|
end
|
45
28
|
|
46
29
|
def opt_in(options = {})
|
47
|
-
|
48
|
-
opt_out.active = false
|
49
|
-
opt_out.save!
|
50
|
-
end
|
51
|
-
true
|
30
|
+
Mailkick.opt_in({email: email, user: self}.merge(options))
|
52
31
|
end
|
53
32
|
|
54
33
|
end
|
data/lib/mailkick/service.rb
CHANGED
@@ -8,13 +8,12 @@ module Mailkick
|
|
8
8
|
|
9
9
|
opt_out = Mailkick::OptOut.where(email: email).order("updated_at desc").first
|
10
10
|
if !opt_out or (time > opt_out.updated_at and !opt_out.active)
|
11
|
-
Mailkick
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
11
|
+
Mailkick.opt_out(
|
12
|
+
email: email,
|
13
|
+
user: Mailkick.user_method ? Mailkick.user_method.call(email) : nil,
|
14
|
+
reason: api_data[:reason],
|
15
|
+
time: time
|
16
|
+
)
|
18
17
|
end
|
19
18
|
end
|
20
19
|
true
|
data/lib/mailkick/version.rb
CHANGED
data/lib/mailkick.rb
CHANGED
@@ -7,6 +7,7 @@ require "mailkick/service"
|
|
7
7
|
require "mailkick/service/mailchimp"
|
8
8
|
require "mailkick/service/mandrill"
|
9
9
|
require "mailkick/service/sendgrid"
|
10
|
+
require "set"
|
10
11
|
|
11
12
|
module Mailkick
|
12
13
|
mattr_accessor :services, :user_method, :secret_token
|
@@ -27,6 +28,69 @@ module Mailkick
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def self.opted_out?(options)
|
32
|
+
opt_outs(options).any?
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.opt_out(options)
|
36
|
+
if !opted_out?(options)
|
37
|
+
time = options[:time] || Time.now
|
38
|
+
Mailkick::OptOut.create! do |o|
|
39
|
+
o.email = options[:email]
|
40
|
+
o.user = options[:user]
|
41
|
+
o.reason = options[:reason] || "unsubscribe"
|
42
|
+
o.list = options[:list]
|
43
|
+
o.created_at = time
|
44
|
+
o.updated_at = time
|
45
|
+
end
|
46
|
+
end
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.opt_in(options)
|
51
|
+
opt_outs(options).each do |opt_out|
|
52
|
+
opt_out.active = false
|
53
|
+
opt_out.save!
|
54
|
+
end
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.opt_outs(options = {})
|
59
|
+
relation = Mailkick::OptOut.where(active: true)
|
60
|
+
|
61
|
+
parts = []
|
62
|
+
binds = []
|
63
|
+
if (email = options[:email])
|
64
|
+
parts << "email = ?"
|
65
|
+
binds << email
|
66
|
+
end
|
67
|
+
if (user = options[:user])
|
68
|
+
parts << "user_id = ? and user_type = ?"
|
69
|
+
binds.concat [user.id, user.class.name]
|
70
|
+
end
|
71
|
+
if parts.any?
|
72
|
+
relation = relation.where(parts.join(" OR "), *binds)
|
73
|
+
end
|
74
|
+
|
75
|
+
relation =
|
76
|
+
if options[:list]
|
77
|
+
relation.where("list IS NULL OR list = ?", options[:list])
|
78
|
+
else
|
79
|
+
relation.where("list IS NULL")
|
80
|
+
end
|
81
|
+
|
82
|
+
relation
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.opted_out_emails(options = {})
|
86
|
+
Set.new(opt_outs(options).where("email IS NOT NULL").uniq.pluck(:email))
|
87
|
+
end
|
88
|
+
|
89
|
+
# does not take into account emails
|
90
|
+
def self.opted_out_users(options = {})
|
91
|
+
Set.new(opt_outs(options).where("user_id IS NOT NULL").map(&:user))
|
92
|
+
end
|
93
|
+
|
30
94
|
end
|
31
95
|
|
32
96
|
ActionMailer::Base.send :include, Mailkick::Mailer
|