ahoy_email 1.1.0 → 1.1.1

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
  SHA256:
3
- metadata.gz: c056fb39ad0a8774c23582f8a37fbea9f460d903f4f05565e31b5670b0ce615d
4
- data.tar.gz: 5b489942efd5cb224f068d06d06fdd9e9e68f65d256ded15be359ccdfc4190ec
3
+ metadata.gz: 2998bcf65131bcbb1ae5d6b5c2d0e1bf21496571a8c8c3e96230f21c9b3b2a74
4
+ data.tar.gz: 4e0291a50f134fcc95cdf8626aaf368bf2cb7c4ce763bbc008691d88421abba3
5
5
  SHA512:
6
- metadata.gz: 55a1a58246738297be5e07198ef58014a13596fa372cf8127a4b4670ddfb7465c09371250ff269306cfc03ef7704ec28bc716669857eb6bc40fbe3132c94564a
7
- data.tar.gz: b58a064519fb0ef57a255db8a57c4b0101f0fbf029e3110f1ece205e927bb13a8e4c3d5f95888e36be41f25eed6f0dc73ee995ff546d27771604c6b4058fd392
6
+ metadata.gz: 9fd0fd7d531e72f1c4d930cf35d398747ec7052b3f940597f80010e07f45d37c70ddb52f9d60d2c3b9bdb49a6760ed28a353e381f87e8849c57f7a5a6b6f8871
7
+ data.tar.gz: 04616042077a12cea5b86dd682339f91104c201bc0ce35a95716a45bf71cad4e80c964b0b57d813090d464d7cf66e7f4edc4f2c214c00723214342e00c9eccfd
data/CHANGELOG.md CHANGED
@@ -1,24 +1,29 @@
1
- ## 1.1.0
1
+ ## 1.1.1 (2021-03-06)
2
+
3
+ - Added support for classes for subscribers
4
+ - Use `datetime` type in migration
5
+
6
+ ## 1.1.0 (2019-07-15)
2
7
 
3
8
  - Made `opened_at` optional with click tracking
4
9
  - Fixed secret token for environment variables
5
10
  - Removed support for Rails 4.2
6
11
 
7
- ## 1.0.3
12
+ ## 1.0.3 (2019-02-18)
8
13
 
9
14
  - Fixed custom message model
10
15
  - Fixed `message` option with proc
11
16
 
12
- ## 1.0.2
17
+ ## 1.0.2 (2018-10-02)
13
18
 
14
19
  - Fixed error with Ruby < 2.5
15
20
  - Fixed UTM parameters storage on model
16
21
 
17
- ## 1.0.1
22
+ ## 1.0.1 (2018-09-27)
18
23
 
19
24
  - Use observer instead of interceptor
20
25
 
21
- ## 1.0.0
26
+ ## 1.0.0 (2018-09-27)
22
27
 
23
28
  - Removed support for Rails < 4.2
24
29
 
@@ -31,91 +36,91 @@ Breaking changes
31
36
  - `AhoyEmail.track` was removed in favor of `AhoyEmail.default_options`
32
37
  - The `heuristic_parse` option was removed and is now the default
33
38
 
34
- ## 0.5.2
39
+ ## 0.5.2 (2018-04-26)
35
40
 
36
41
  - Fixed secret token for Rails 5.2
37
42
  - Added `heuristic_parse` option
38
43
 
39
- ## 0.5.1
44
+ ## 0.5.1 (2018-04-19)
40
45
 
41
46
  - Fixed deprecation warning in Rails 5.2
42
47
  - Added `unsubscribe_links` option
43
48
  - Allow `message_model` to accept a proc
44
49
  - Use `references` in migration
45
50
 
46
- ## 0.5.0
51
+ ## 0.5.0 (2017-05-01)
47
52
 
48
53
  - Added support for Rails 5.1
49
54
  - Added `invalid_redirect_url`
50
55
 
51
- ## 0.4.0
56
+ ## 0.4.0 (2016-09-01)
52
57
 
53
58
  - Fixed `belongs_to` error in Rails 5
54
59
  - Include `safely_block` gem without polluting global namespace
55
60
 
56
- ## 0.3.2
61
+ ## 0.3.2 (2016-07-27)
57
62
 
58
63
  - Fixed deprecation warning for Rails 5
59
64
  - Do not track content by default on fresh installations
60
65
 
61
- ## 0.3.1
66
+ ## 0.3.1 (2016-05-11)
62
67
 
63
68
  - Fixed deprecation warnings
64
69
  - Fixed `stack level too deep` error
65
70
 
66
- ## 0.3.0
71
+ ## 0.3.0 (2015-12-16)
67
72
 
68
73
  - Added safely for error reporting
69
74
  - Fixed error with `to`
70
75
  - Prevent duplicate records when mail called multiple times
71
76
 
72
- ## 0.2.4
77
+ ## 0.2.4 (2015-07-29)
73
78
 
74
79
  - Added `extra` option for extra attributes
75
80
 
76
- ## 0.2.3
81
+ ## 0.2.3 (2015-03-22)
77
82
 
78
83
  - Save utm parameters
79
84
  - Added `url_options`
80
85
  - Skip tracking for `mailto` links
81
86
  - Only set secret token if not already set
82
87
 
83
- ## 0.2.2
88
+ ## 0.2.2 (2014-08-31)
84
89
 
85
90
  - Fixed secret token for Rails 4.1
86
91
  - Fixed links with href
87
92
  - Fixed message id for Rails 3.1
88
93
 
89
- ## 0.2.1
94
+ ## 0.2.1 (2014-05-26)
90
95
 
91
96
  - Added `only` and `except` options
92
97
 
93
- ## 0.2.0
98
+ ## 0.2.0 (2014-05-10)
94
99
 
95
100
  - Enable tracking when track is called by default
96
101
 
97
- ## 0.1.5
102
+ ## 0.1.5 (2014-05-09)
98
103
 
99
104
  - Rails 3 fix
100
105
 
101
- ## 0.1.4
106
+ ## 0.1.4 (2014-05-04)
102
107
 
103
108
  - Try not to rewrite unsubscribe links
104
109
 
105
- ## 0.1.3
110
+ ## 0.1.3 (2014-05-03)
106
111
 
107
112
  - Added `to` and `mailer` fields
108
113
  - Added subscribers for open and click events
109
114
 
110
- ## 0.1.2
115
+ ## 0.1.2 (2014-05-01)
111
116
 
112
117
  - Added `AhoyEmail.track` (fix)
113
118
 
114
- ## 0.1.1
119
+ ## 0.1.1 (2014-04-30)
115
120
 
116
121
  - Use secure compare for signature verification
117
122
  - Fixed deprecation warnings
118
123
 
119
- ## 0.1.0
124
+ ## 0.1.0 (2014-04-29)
120
125
 
121
126
  - First major release
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2019 Andrew Kane
1
+ Copyright (c) 2014-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,20 +1,12 @@
1
1
  # Ahoy Email
2
2
 
3
- :postbox: Email analytics for Rails
3
+ First-party email analytics for Rails
4
4
 
5
- You get:
6
-
7
- - A history of emails sent to each user
8
- - Easy UTM tagging
9
- - Optional open and click tracking
10
-
11
- **Ahoy Email 1.0 was recently released!** See [how to upgrade](#upgrading)
5
+ :fire: For web and native app analytics, check out [Ahoy](https://github.com/ankane/ahoy)
12
6
 
13
7
  :bullettrain_side: To manage unsubscribes, check out [Mailkick](https://github.com/ankane/mailkick)
14
8
 
15
- :fire: To track visits and events, check out [Ahoy](https://github.com/ankane/ahoy)
16
-
17
- [![Build Status](https://travis-ci.org/ankane/ahoy_email.svg?branch=master)](https://travis-ci.org/ankane/ahoy_email)
9
+ [![Build Status](https://github.com/ankane/ahoy_email/workflows/build/badge.svg?branch=master)](https://github.com/ankane/ahoy_email/actions)
18
10
 
19
11
  ## Installation
20
12
 
@@ -31,11 +23,17 @@ rails generate ahoy_email:install
31
23
  rails db:migrate
32
24
  ```
33
25
 
34
- ## How It Works
26
+ ## Getting Started
35
27
 
36
- ### Message History
28
+ There are three main features:
37
29
 
38
- Ahoy creates an `Ahoy::Message` record for each email sent by default. You can disable history for a mailer:
30
+ - [Message history](#message-history)
31
+ - [UTM tagging](#utm-tagging)
32
+ - [Open & click analytics](#open--click-analytics)
33
+
34
+ ## Message History
35
+
36
+ Ahoy Email creates an `Ahoy::Message` record for each email sent by default. You can disable history for a mailer:
39
37
 
40
38
  ```ruby
41
39
  class CouponMailer < ApplicationMailer
@@ -51,7 +49,7 @@ AhoyEmail.default_options[:message] = false
51
49
 
52
50
  ### Users
53
51
 
54
- Ahoy records the user a message is sent to - not just the email address. This gives you a full history of messages for each user, even if he or she changes addresses.
52
+ Ahoy Email records the user a message is sent to - not just the email address. This gives you a history of messages for each user, even if they change addresses.
55
53
 
56
54
  By default, Ahoy tries `@user` then `params[:user]` then `User.find_by(email: message.to)` to find the user.
57
55
 
@@ -86,7 +84,7 @@ Record extra attributes on the `Ahoy::Message` model.
86
84
  Create a migration to add extra attributes to the `ahoy_messages` table. For example:
87
85
 
88
86
  ```ruby
89
- class AddCouponIdToAhoyMessages < ActiveRecord::Migration[5.2]
87
+ class AddCouponIdToAhoyMessages < ActiveRecord::Migration[6.1]
90
88
  def change
91
89
  add_column :ahoy_messages, :coupon_id, :integer
92
90
  end
@@ -109,9 +107,15 @@ class CouponMailer < ApplicationMailer
109
107
  end
110
108
  ```
111
109
 
112
- ### UTM Tagging
110
+ ## UTM Tagging
111
+
112
+ Use UTM tagging to attribute a conversion (like an order) to an email campaign. If you use [Ahoy](https://github.com/ankane/ahoy) for web analytics:
113
113
 
114
- Automatically add UTM parameters to links.
114
+ 1. Send an email with UTM parameters
115
+ 2. When a user visits the site, Ahoy will create a visit with the UTM parameters
116
+ 3. When a user orders, the visit will be associated with the order (if [configured](https://github.com/ankane/ahoy#associated-models))
117
+
118
+ Add UTM parameters to links with:
115
119
 
116
120
  ```ruby
117
121
  class CouponMailer < ApplicationMailer
@@ -139,22 +143,25 @@ Skip specific links with:
139
143
  <%= link_to "Go", some_url, data: {skip_utm_params: true} %>
140
144
  ```
141
145
 
142
- ### Opens & Clicks
146
+ ## Open & Click Analytics
143
147
 
144
- #### Setup
148
+ While it’s nice to get feedback on the performance of your emails, we discourage the use of open tracking. If you do decide to use open or click tracking, be sure to get consent from your users and consider a short retention period. Check out [this article](https://www.eff.org/deeplinks/2019/01/stop-tracking-my-emails) for more best practices.
145
149
 
146
- Additional setup is required to track opens and clicks.
150
+ ### Setup
147
151
 
148
152
  Create a migration with:
149
153
 
150
154
  ```ruby
151
- class AddTokenToAhoyMessages < ActiveRecord::Migration[5.2]
155
+ class AddTokenToAhoyMessages < ActiveRecord::Migration[6.1]
152
156
  def change
153
157
  add_column :ahoy_messages, :token, :string
158
+ add_index :ahoy_messages, :token
159
+
160
+ # for opens
154
161
  add_column :ahoy_messages, :opened_at, :timestamp
155
- add_column :ahoy_messages, :clicked_at, :timestamp
156
162
 
157
- add_index :ahoy_messages, :token
163
+ # for clicks
164
+ add_column :ahoy_messages, :clicked_at, :timestamp
158
165
  end
159
166
  end
160
167
  ```
@@ -169,11 +176,27 @@ And add to mailers you want to track:
169
176
 
170
177
  ```ruby
171
178
  class CouponMailer < ApplicationMailer
172
- track open: true, click: true # use only/except to limit actions
179
+ track open: true, click: true
173
180
  end
174
181
  ```
175
182
 
176
- #### How It Works
183
+ Use only and except to limit actions
184
+
185
+ ```ruby
186
+ class CouponMailer < ApplicationMailer
187
+ track click: true, only: [:welcome]
188
+ end
189
+ ```
190
+
191
+ Or make it conditional
192
+
193
+ ```ruby
194
+ class CouponMailer < ApplicationMailer
195
+ track click: -> { params[:user].opted_in? }
196
+ end
197
+ ```
198
+
199
+ ### How It Works
177
200
 
178
201
  For opens, an invisible pixel is added right before the `</body>` tag in HTML emails. If the recipient has images enabled in their email client, the pixel is loaded and the open time recorded.
179
202
 
@@ -209,7 +232,7 @@ You can specify the domain to use with:
209
232
  AhoyEmail.default_options[:url_options] = {host: "mydomain.com"}
210
233
  ```
211
234
 
212
- #### Events
235
+ ### Events
213
236
 
214
237
  Subscribe to open and click events by adding to the initializer:
215
238
 
@@ -245,7 +268,7 @@ AhoyEmail.subscribers << EmailSubscriber.new
245
268
 
246
269
  ## Data Protection
247
270
 
248
- Protect the privacy of your users by encrypting the `to` field. [attr_encrypted](https://github.com/attr-encrypted/attr_encrypted) is great for this. Use [blind_index](https://github.com/ankane/blind_index) if you need to query by the `to` field.
271
+ We recommend encrypting the `to` field (as well as the `subject` if it’s sensitive). [Lockbox](https://github.com/ankane/lockbox) is great for this. Use [Blind Index](https://github.com/ankane/blind_index) if you need to query by the `to` field.
249
272
 
250
273
  Create `app/models/ahoy/message.rb` with:
251
274
 
@@ -254,11 +277,25 @@ class Ahoy::Message < ApplicationRecord
254
277
  self.table_name = "ahoy_messages"
255
278
  belongs_to :user, polymorphic: true, optional: true
256
279
 
257
- attr_encrypted :to, key: ...
258
- blind_index :to, key: ...
280
+ encrypts :to
281
+ blind_index :to
259
282
  end
260
283
  ```
261
284
 
285
+ ## Data Retention
286
+
287
+ Delete older data with:
288
+
289
+ ```ruby
290
+ Ahoy::Message.where("created_at < ?", 1.year.ago).in_batches.delete_all
291
+ ```
292
+
293
+ Delete data for a specific user with:
294
+
295
+ ```ruby
296
+ Ahoy::Message.where(user_id: 1).in_batches.delete_all
297
+ ```
298
+
262
299
  ## Reference
263
300
 
264
301
  Set global options
@@ -283,7 +320,7 @@ end
283
320
 
284
321
  ## Mongoid
285
322
 
286
- If you prefer to use Mongoid instead of ActiveRecord, create `app/models/ahoy/message.rb` with:
323
+ If you prefer to use Mongoid instead of Active Record, create `app/models/ahoy/message.rb` with:
287
324
 
288
325
  ```ruby
289
326
  class Ahoy::Message
@@ -298,37 +335,6 @@ class Ahoy::Message
298
335
  end
299
336
  ```
300
337
 
301
- ## Upgrading
302
-
303
- ### 1.0
304
-
305
- Breaking changes
306
-
307
- - UTM tagging, open tracking, and click tracking are no longer enabled by default. To enable, create an initializer with:
308
-
309
- ```ruby
310
- AhoyEmail.api = true
311
-
312
- AhoyEmail.default_options[:open] = true
313
- AhoyEmail.default_options[:click] = true
314
- AhoyEmail.default_options[:utm_params] = true
315
- ```
316
-
317
- - Only sent emails are recorded
318
- - Proc options are now executed in the context of the mailer and take no arguments
319
-
320
- ```ruby
321
- # old
322
- user: ->(mailer, message) { User.find_by(email: message.to) }
323
-
324
- # new
325
- user: -> { User.find_by(email: message.to) }
326
- ```
327
-
328
- - Invalid options now throw an `ArgumentError`
329
- - `AhoyEmail.track` was removed in favor of `AhoyEmail.default_options`
330
- - The `heuristic_parse` option was removed and is now the default
331
-
332
338
  ## History
333
339
 
334
340
  View the [changelog](https://github.com/ankane/ahoy_email/blob/master/CHANGELOG.md)
@@ -342,11 +348,11 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
342
348
  - Write, clarify, or fix documentation
343
349
  - Suggest or add new features
344
350
 
345
- To get started with development and testing:
351
+ To get started with development:
346
352
 
347
353
  ```sh
348
354
  git clone https://github.com/ankane/ahoy_email.git
349
355
  cd ahoy_email
350
356
  bundle install
351
- rake test
357
+ bundle exec rake test
352
358
  ```
@@ -8,6 +8,7 @@ module Ahoy
8
8
  before_action :set_message
9
9
 
10
10
  def open
11
+ # TODO move to MessageSubscriber in 2.0
11
12
  if @message && !@message.opened_at
12
13
  @message.opened_at = Time.now
13
14
  @message.save!
@@ -19,6 +20,7 @@ module Ahoy
19
20
  end
20
21
 
21
22
  def click
23
+ # TODO move to MessageSubscriber in 2.0
22
24
  if @message && !@message.clicked_at
23
25
  @message.clicked_at = Time.now
24
26
  @message.opened_at ||= @message.clicked_at if @message.respond_to?(:opened_at=)
@@ -37,6 +39,7 @@ module Ahoy
37
39
 
38
40
  redirect_to url
39
41
  else
42
+ # TODO show link expired page with link to invalid redirect url in 2.0
40
43
  redirect_to AhoyEmail.invalid_redirect_url || main_app.root_url
41
44
  end
42
45
  end
@@ -44,14 +47,22 @@ module Ahoy
44
47
  protected
45
48
 
46
49
  def set_message
47
- @message = AhoyEmail.message_model.where(token: params[:id]).first
50
+ @token = params[:id]
51
+
52
+ model = AhoyEmail.message_model
53
+
54
+ return if model.respond_to?(:column_names) && !model.column_names.include?("token")
55
+
56
+ @message = model.where(token: @token).first
48
57
  end
49
58
 
50
59
  def publish(name, event = {})
51
60
  AhoyEmail.subscribers.each do |subscriber|
61
+ subscriber = subscriber.new if subscriber.is_a?(Class) && !subscriber.respond_to?(name)
52
62
  if subscriber.respond_to?(name)
53
63
  event[:message] = @message
54
64
  event[:controller] = self
65
+ event[:token] = @token
55
66
  subscriber.send name, event
56
67
  end
57
68
  end
data/lib/ahoy_email.rb CHANGED
@@ -29,7 +29,7 @@ module AhoyEmail
29
29
  utm_term: nil,
30
30
  utm_content: nil,
31
31
  utm_campaign: -> { action_name },
32
- user: -> { @user || (respond_to?(:params) && params && params[:user]) || (message.to.try(:size) == 1 ? (User.find_by(email: message.to.first) rescue nil) : nil) },
32
+ user: -> { (defined?(@user) && @user) || (respond_to?(:params) && params && params[:user]) || (message.to.try(:size) == 1 ? (User.find_by(email: message.to.first) rescue nil) : nil) },
33
33
  mailer: -> { "#{self.class.name}##{action_name}" },
34
34
  url_options: {},
35
35
  extra: {},
@@ -84,6 +84,7 @@ module AhoyEmail
84
84
  if html_part?
85
85
  part = message.html_part || message
86
86
 
87
+ # TODO use Nokogiri::HTML::DocumentFragment.parse in 2.0
87
88
  doc = Nokogiri::HTML(part.body.raw_source)
88
89
  doc.css("a[href]").each do |link|
89
90
  uri = parse_uri(link["href"])
@@ -115,6 +116,12 @@ module AhoyEmail
115
116
  end
116
117
  end
117
118
 
119
+ # ampersands converted to &amp;
120
+ # https://github.com/sparklemotion/nokogiri/issues/1127
121
+ # not ideal, but should be equivalent in html5
122
+ # https://stackoverflow.com/questions/15776556/whats-the-difference-between-and-amp-in-html5
123
+ # escaping technically required before html5
124
+ # https://stackoverflow.com/questions/3705591/do-i-encode-ampersands-in-a-href
118
125
  part.body = doc.to_s
119
126
  end
120
127
  end
@@ -1,3 +1,3 @@
1
1
  module AhoyEmail
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -5,7 +5,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
5
5
  t.text :to
6
6
  t.string :mailer
7
7
  t.text :subject
8
- t.timestamp :sent_at
8
+ t.datetime :sent_at
9
9
  end
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-16 00:00:00.000000000 Z
11
+ date: 2021-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -150,8 +150,8 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
- description:
154
- email: andrew@chartkick.com
153
+ description:
154
+ email: andrew@ankane.org
155
155
  executables: []
156
156
  extensions: []
157
157
  extra_rdoc_files: []
@@ -176,7 +176,7 @@ homepage: https://github.com/ankane/ahoy_email
176
176
  licenses:
177
177
  - MIT
178
178
  metadata: {}
179
- post_install_message:
179
+ post_install_message:
180
180
  rdoc_options: []
181
181
  require_paths:
182
182
  - lib
@@ -191,8 +191,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
191
  - !ruby/object:Gem::Version
192
192
  version: '0'
193
193
  requirements: []
194
- rubygems_version: 3.0.4
195
- signing_key:
194
+ rubygems_version: 3.2.3
195
+ signing_key:
196
196
  specification_version: 4
197
- summary: Email analytics for Rails
197
+ summary: First-party email analytics for Rails
198
198
  test_files: []