mailkick 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 902719cffa741b74a8efa92f326e98c5d359d610
4
- data.tar.gz: 0a15d25bf9ea0201eabc5eeace46cba06b878596
3
+ metadata.gz: c06634c652c84b39afb65d63e54e58a57d212699
4
+ data.tar.gz: 30073ad89e0d42b83844a46822678058ca3b1bf2
5
5
  SHA512:
6
- metadata.gz: b9e635f1f60c3eb5043450aea43133e6a9feb3cccaa1116ca4dfc769c73e1d0f51ecd7dec73d7fc5793f2893e08c4b66f8d774774ac5e2fd8326d890286a9b8b
7
- data.tar.gz: f21ad8fed634b2e4bec5801df0a5d8b305656e4ff4922894461df36700fedb5f2f8704ad00c42e6b11ee2f2b6cd2f85affd3235038e0ff1ef2cd5a9600ceb1c2
6
+ metadata.gz: 018f990ddd1c587e4fcb791fc99b3d6767aeeb8b2eae51aa9e00017432172688bba7bc1adfab45071c540ad626953ccc6216513f4a6e74a7383858b06faebb2f
7
+ data.tar.gz: 62cd53b3f3395af21bf18086cf131d91b8625a4cd71a889792e7f053a96722b337928dbd0160b495d459717003dfdf50760d1484eb821b57cb22b3adb901d08a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.0.3
2
+
3
+ - Added support for multiple lists
4
+ - Changed `mailkick_user` method names - sorry early adopters :(
5
+
1
6
  ## 0.0.2
2
7
 
3
8
  - Added Mailchimp service
data/README.md CHANGED
@@ -62,33 +62,39 @@ class User < ActiveRecord::Base
62
62
  end
63
63
  ```
64
64
 
65
- Get all users who have not unsubscribed
65
+ Get all users who have opted out
66
66
 
67
67
  ```ruby
68
- User.subscribed
68
+ User.opted_out
69
+ ```
70
+
71
+ And those who have not (send to these people)
72
+
73
+ ```ruby
74
+ User.not_opted_out
69
75
  ```
70
76
 
71
77
  Check one user
72
78
 
73
79
  ```ruby
74
- user.subscribed?
80
+ user.opted_out?
75
81
  ```
76
82
 
77
83
  Unsubscribe
78
84
 
79
85
  ```ruby
80
- user.unsubscribe
86
+ user.opt_out
81
87
  ```
82
88
 
83
- Subscribe
89
+ Resubscribe
84
90
 
85
91
  ```ruby
86
- user.subscribe
92
+ user.opt_in
87
93
  ```
88
94
 
89
95
  ## Bounces and Spam Reports
90
96
 
91
- Pull bounces, spam reports, and unsubscribes from your email service.
97
+ Fetch bounces, spam reports, and unsubscribes from your email service.
92
98
 
93
99
  ```ruby
94
100
  Mailkick.fetch_opt_outs
@@ -126,7 +132,7 @@ Will gladly accept pull requests.
126
132
 
127
133
  ### Advanced
128
134
 
129
- For more control over the services, set them by hand.
135
+ For more control over services, set them by hand.
130
136
 
131
137
  ```ruby
132
138
  Mailkick.services = [
@@ -137,7 +143,61 @@ Mailkick.services = [
137
143
 
138
144
  ## Multiple Lists
139
145
 
140
- Coming soon
146
+ You may want to split your emails into multiple categories, like sale emails and order reminders.
147
+
148
+ Set the list in the mailer.
149
+
150
+ ```ruby
151
+ class UserMailer < ActionMailer::Base
152
+
153
+ def order_reminder(user)
154
+ header[:mailkick_list] = "order_reminders"
155
+ # ...
156
+ end
157
+
158
+ end
159
+ ```
160
+
161
+ Pass the `list` option to methods.
162
+
163
+ ```ruby
164
+ # scopes
165
+ User.opted_out(list: "order_reminders")
166
+ 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
+ user.opted_out?(list: "order_reminders")
182
+ ```
183
+
184
+ ### Opt-In Lists
185
+
186
+ For opt-in lists, you’ll need to manage the subscribers yourself.
187
+
188
+ Mailkick stores opt-outs, which you can combine with opt-ins.
189
+
190
+ ```ruby
191
+ # opt-ins minus opt-outs
192
+ User.where(send_me_sales: true).not_opted_out(list: "sales")
193
+ ```
194
+
195
+ Check one user
196
+
197
+ ```ruby
198
+ # opted in and didn't opt out
199
+ user.send_me_sales && !user.opted_out?(list: "sales")
200
+ ```
141
201
 
142
202
  ## Bonus
143
203
 
@@ -6,11 +6,12 @@ module Mailkick
6
6
  end
7
7
 
8
8
  def unsubscribe
9
- if subscribed?
9
+ if !opted_out?
10
10
  Mailkick::OptOut.create! do |o|
11
11
  o.email = @email
12
12
  o.user = @user
13
13
  o.reason = "unsubscribe"
14
+ o.list = @list
14
15
  end
15
16
  end
16
17
 
@@ -22,8 +23,8 @@ module Mailkick
22
23
  opt_out.active = false
23
24
  opt_out.save!
24
25
  end
25
- if @user and @user.respond_to?(:subscribe)
26
- @user.subscribe
26
+ if @user and @user.respond_to?(:opt_in)
27
+ @user.opt_in(@options)
27
28
  end
28
29
 
29
30
  redirect_to subscription_path(params[:id])
@@ -34,24 +35,32 @@ module Mailkick
34
35
  def set_email
35
36
  verifier = ActiveSupport::MessageVerifier.new(Mailkick.secret_token)
36
37
  begin
37
- @email, user_id, user_type = verifier.verify(params[:id])
38
+ @email, user_id, user_type, @list = verifier.verify(params[:id])
38
39
  if user_type
39
40
  # on the unprobabilistic chance user_type is compromised, not much damage
40
41
  @user = user_type.constantize.find(user_id)
41
42
  end
43
+ @options = {}
44
+ @options[:list] = @list if @list
42
45
  rescue ActiveSupport::MessageVerifier::InvalidSignature
43
46
  render text: "Subscription not found", status: :bad_request
44
47
  end
45
48
  end
46
49
 
47
- def subscribed?
48
- if @user and @user.respond_to?(:subscribed?)
49
- @user.subscribed?
50
+ def opted_out?(options = {})
51
+ options = @options.merge(options)
52
+ if @user and @user.respond_to?(:opted_out?)
53
+ @user.opted_out?(options)
50
54
  else
51
- Mailkick::OptOut.where(email: @email, active: true).empty?
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?
52
61
  end
53
62
  end
54
- helper_method :subscribed?
63
+ helper_method :opted_out?
55
64
 
56
65
  def subscribe_url(options = {})
57
66
  subscribe_subscription_path(params[:id], options)
@@ -24,12 +24,12 @@
24
24
  </head>
25
25
  <body>
26
26
  <div class="container">
27
- <% if subscribed? %>
28
- <p>You are subscribed.</p>
29
- <p><%= link_to "Unsubscribe", unsubscribe_url %></p>
30
- <% else %>
27
+ <% if opted_out? %>
31
28
  <p>You are unsubscribed.</p>
32
29
  <p><%= link_to "Resubscribe", subscribe_url %></p>
30
+ <% else %>
31
+ <p>You are subscribed.</p>
32
+ <p><%= link_to "Unsubscribe", unsubscribe_url %></p>
33
33
  <% end %>
34
34
  </div>
35
35
  </body>
@@ -6,6 +6,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration
6
6
  t.string :user_type
7
7
  t.boolean :active, null: false, default: true
8
8
  t.string :reason
9
+ t.string :list
9
10
  t.timestamps
10
11
  end
11
12
 
@@ -3,36 +3,54 @@ module Mailkick
3
3
 
4
4
  def mailkick_user(options = {})
5
5
  class_eval do
6
- scope :subscribed, proc{ joins(sanitize_sql_array(["LEFT JOIN mailkick_opt_outs ON #{table_name}.email = mailkick_opt_outs.email OR (#{table_name}.id = mailkick_opt_outs.user_id AND mailkick_opt_outs.user_type = ?)", name])).where("active != ?", true).uniq }
7
-
8
- def opt_outs
9
- Mailkick::OptOut.where("email = ? OR (user_id = ? AND user_type = ?)", email, id, self.class.name)
10
- end
6
+ scope :opted_out, proc {|options = {}|
7
+ binds = [self.class.name, true]
8
+ if options[:list]
9
+ query = "(list IS NULL OR list = ?)"
10
+ binds << options[:list]
11
+ else
12
+ query = "list IS NULL"
13
+ end
14
+ where("#{options[:not] ? "NOT " : ""}EXISTS(SELECT * FROM mailkick_opt_outs WHERE (#{table_name}.email = mailkick_opt_outs.email OR (#{table_name}.id = mailkick_opt_outs.user_id AND mailkick_opt_outs.user_type = ?)) AND active = ? AND #{query})", *binds)
15
+ }
16
+ scope :not_opted_out, proc {|options = {}|
17
+ opted_out(options.merge(not: true))
18
+ }
11
19
 
12
- def subscribed?
13
- opt_outs.where(active: true).empty?
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
14
27
  end
15
28
 
16
- def subscribe
17
- opt_outs.where(active: true).each do |opt_out|
18
- opt_out.active = false
19
- opt_out.save!
20
- end
21
- true
29
+ def opted_out?(options = {})
30
+ opt_outs(options).where(active: true).any?
22
31
  end
23
32
 
24
- def unsubscribe
25
- if subscribed?
33
+ def opt_out(options = {})
34
+ if !opted_out?(options)
26
35
  OptOut.create! do |o|
27
36
  o.email = email
28
37
  o.user = self
29
38
  o.reason = "unsubscribe"
39
+ o.list = options[:list]
30
40
  o.save!
31
41
  end
32
42
  end
33
43
  true
34
44
  end
35
45
 
46
+ def opt_in(options = {})
47
+ opt_outs(options).where(active: true).each do |opt_out|
48
+ opt_out.active = false
49
+ opt_out.save!
50
+ end
51
+ true
52
+ end
53
+
36
54
  end
37
55
  end
38
56
 
@@ -9,9 +9,14 @@ module Mailkick
9
9
  def process
10
10
  email = message.to.first
11
11
  user = Mailkick.user_method.call(email) if Mailkick.user_method
12
+ list = message[:mailkick_list].try(:value)
13
+ if list
14
+ # remove header
15
+ message[:mailkick_list] = nil
16
+ end
12
17
 
13
18
  verifier = ActiveSupport::MessageVerifier.new(Mailkick.secret_token)
14
- token = verifier.generate([email, user.try(:id), user.try(:class).try(:name)])
19
+ token = verifier.generate([email, user.try(:id), user.try(:class).try(:name), list])
15
20
 
16
21
  parts = message.parts.any? ? message.parts : [message]
17
22
  parts.each do |part|
@@ -1,3 +1,3 @@
1
1
  module Mailkick
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
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: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-04 00:00:00.000000000 Z
11
+ date: 2014-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler