ahoy_email 1.1.1 → 2.0.0

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: 2998bcf65131bcbb1ae5d6b5c2d0e1bf21496571a8c8c3e96230f21c9b3b2a74
4
- data.tar.gz: 4e0291a50f134fcc95cdf8626aaf368bf2cb7c4ce763bbc008691d88421abba3
3
+ metadata.gz: d178d2bd4a2631bad0bce962cd35daecc019034270530f350596d14172e46ca0
4
+ data.tar.gz: af5eb88ec75a4100c5215a71e39fb825d7c7e4823fd601c3cd6473b7409db3dd
5
5
  SHA512:
6
- metadata.gz: 9fd0fd7d531e72f1c4d930cf35d398747ec7052b3f940597f80010e07f45d37c70ddb52f9d60d2c3b9bdb49a6760ed28a353e381f87e8849c57f7a5a6b6f8871
7
- data.tar.gz: 04616042077a12cea5b86dd682339f91104c201bc0ce35a95716a45bf71cad4e80c964b0b57d813090d464d7cf66e7f4edc4f2c214c00723214342e00c9eccfd
6
+ metadata.gz: bcc3ac25d9a8323a4da3a4331a338ca377a375033886c9e447945654897ea3b89e178ffe7a4e02336838ba27e1b8f8dda0aef0f5261f1adb8c66167dbe758f98
7
+ data.tar.gz: b433434716662eb90d9309c6dfdefe61752496777206e43d1d1d9ddadfee9aa664cf1daa1272d4df62a393d6e979e62932194829dd68b84720fd47661fada6e0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 2.0.0 (2021-03-06)
2
+
3
+ - Made `to` field encrypted by default for new installations
4
+ - Added click analytics for Redis
5
+ - Added send events to subscribers
6
+ - Removed support for Rails < 5.2
7
+
8
+ Breaking changes
9
+
10
+ - The `track` method has been broken into `has_history` for message history, `utm_params` for UTM tagging, and `track_clicks` for click analytics
11
+ - Message history is no longer enabled by default
12
+ - Open tracking has been removed
13
+ - `:message` is no longer included in click events
14
+ - Users are shown a link expired page when signature verification fails instead of being redirected to the homepage when `AhoyEmail.invalid_redirect_url` is not set
15
+
1
16
  ## 1.1.1 (2021-03-06)
2
17
 
3
18
  - Added support for classes for subscribers
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  First-party email analytics for Rails
4
4
 
5
+ **Ahoy Email 2.0 was recently released** - see [how to upgrade](#upgrading)
6
+
5
7
  :fire: For web and native app analytics, check out [Ahoy](https://github.com/ankane/ahoy)
6
8
 
7
9
  :bullettrain_side: To manage unsubscribes, check out [Mailkick](https://github.com/ankane/mailkick)
@@ -16,48 +18,65 @@ Add this line to your application’s Gemfile:
16
18
  gem 'ahoy_email'
17
19
  ```
18
20
 
19
- And run the generator. This creates a model to store messages.
20
-
21
- ```sh
22
- rails generate ahoy_email:install
23
- rails db:migrate
24
- ```
25
-
26
21
  ## Getting Started
27
22
 
28
- There are three main features:
23
+ There are three main features, which can be used independently:
29
24
 
30
25
  - [Message history](#message-history)
31
26
  - [UTM tagging](#utm-tagging)
32
- - [Open & click analytics](#open--click-analytics)
27
+ - [Click analytics](#click-analytics)
33
28
 
34
29
  ## Message History
35
30
 
36
- Ahoy Email creates an `Ahoy::Message` record for each email sent by default. You can disable history for a mailer:
31
+ To encrypt email addresses, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
32
+
33
+ ```sh
34
+ rails generate ahoy:messages
35
+ rails db:migrate
36
+ ```
37
+
38
+ If you prefer not to encrypt data, run:
39
+
40
+ ```sh
41
+ rails generate ahoy:messages --unencrypted
42
+ rails db:migrate
43
+ ```
44
+
45
+ Then, add to mailers:
37
46
 
38
47
  ```ruby
39
48
  class CouponMailer < ApplicationMailer
40
- track message: false # use only/except to limit actions
49
+ has_history
41
50
  end
42
51
  ```
43
52
 
44
- Or by default:
53
+ Use the `Ahoy::Message` model to query messages:
45
54
 
46
55
  ```ruby
47
- AhoyEmail.default_options[:message] = false
56
+ Ahoy::Message.last
48
57
  ```
49
58
 
50
- ### Users
59
+ Use only and except to limit actions
60
+
61
+ ```ruby
62
+ class CouponMailer < ApplicationMailer
63
+ has_history only: [:welcome]
64
+ end
65
+ ```
66
+
67
+ To store history for all mailers, create `config/initializers/ahoy_email.rb` with:
51
68
 
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.
69
+ ```ruby
70
+ AhoyEmail.default_options[:message] = true
71
+ ```
53
72
 
54
- By default, Ahoy tries `@user` then `params[:user]` then `User.find_by(email: message.to)` to find the user.
73
+ ### Users
55
74
 
56
- You can pass a specific user with:
75
+ By default, Ahoy Email tries `@user` then `params[:user]` then `User.find_by(email: message.to)` to find the user. You can pass a specific user with:
57
76
 
58
77
  ```ruby
59
78
  class CouponMailer < ApplicationMailer
60
- track user: -> { params[:some_user] }
79
+ has_history user: -> { params[:some_user] }
61
80
  end
62
81
  ```
63
82
 
@@ -77,11 +96,9 @@ And run:
77
96
  user.messages
78
97
  ```
79
98
 
80
- ### Extra Attributes
99
+ ### Extra Data
81
100
 
82
- Record extra attributes on the `Ahoy::Message` model.
83
-
84
- Create a migration to add extra attributes to the `ahoy_messages` table. For example:
101
+ Add extra data to messages. Create a migration like:
85
102
 
86
103
  ```ruby
87
104
  class AddCouponIdToAhoyMessages < ActiveRecord::Migration[6.1]
@@ -91,11 +108,11 @@ class AddCouponIdToAhoyMessages < ActiveRecord::Migration[6.1]
91
108
  end
92
109
  ```
93
110
 
94
- Then use:
111
+ And use:
95
112
 
96
113
  ```ruby
97
114
  class CouponMailer < ApplicationMailer
98
- track extra: {coupon_id: 1}
115
+ has_history extra: {coupon_id: 1}
99
116
  end
100
117
  ```
101
118
 
@@ -103,23 +120,53 @@ You can use a proc as well.
103
120
 
104
121
  ```ruby
105
122
  class CouponMailer < ApplicationMailer
106
- track extra: -> { {coupon_id: params[:coupon].id} }
123
+ has_history extra: -> { {coupon_id: params[:coupon].id} }
107
124
  end
108
125
  ```
109
126
 
110
- ## UTM Tagging
127
+ ### Options
111
128
 
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:
129
+ Set global options
113
130
 
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))
131
+ ```ruby
132
+ AhoyEmail.default_options[:user] = -> { params[:admin] }
133
+ ```
117
134
 
118
- Add UTM parameters to links with:
135
+ Use a different model
136
+
137
+ ```ruby
138
+ AhoyEmail.message_model = -> { UserMessage }
139
+ ```
140
+
141
+ Or fully customize how messages are tracked
142
+
143
+ ```ruby
144
+ AhoyEmail.track_method = lambda do |data|
145
+ # your code
146
+ end
147
+ ```
148
+
149
+ ### Data Retention
150
+
151
+ Delete older data with:
152
+
153
+ ```ruby
154
+ Ahoy::Message.where("created_at < ?", 1.year.ago).in_batches.delete_all
155
+ ```
156
+
157
+ Delete data for a specific user with:
158
+
159
+ ```ruby
160
+ Ahoy::Message.where(user_id: 1).in_batches.delete_all
161
+ ```
162
+
163
+ ## UTM Tagging
164
+
165
+ Use UTM tagging to attribute visits or conversions to an email campaign. Add UTM parameters to links with:
119
166
 
120
167
  ```ruby
121
168
  class CouponMailer < ApplicationMailer
122
- track utm_params: true # use only/except to limit actions
169
+ utm_params
123
170
  end
124
171
  ```
125
172
 
@@ -133,7 +180,15 @@ You can customize them with:
133
180
 
134
181
  ```ruby
135
182
  class CouponMailer < ApplicationMailer
136
- track utm_params: true, utm_campaign: -> { "coupon#{params[:coupon].id}" }
183
+ utm_params utm_campaign: -> { "coupon#{params[:coupon].id}" }
184
+ end
185
+ ```
186
+
187
+ Use only and except to limit actions
188
+
189
+ ```ruby
190
+ class CouponMailer < ApplicationMailer
191
+ utm_params only: [:welcome]
137
192
  end
138
193
  ```
139
194
 
@@ -143,40 +198,56 @@ Skip specific links with:
143
198
  <%= link_to "Go", some_url, data: {skip_utm_params: true} %>
144
199
  ```
145
200
 
146
- ## Open & Click Analytics
201
+ ## Click Analytics
147
202
 
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.
203
+ You can track click-through rate to see how well campaigns are performing. Stats can be stored in any data store, and there’s a built-in integration with Redis.
149
204
 
150
- ### Setup
205
+ #### Redis
151
206
 
152
- Create a migration with:
207
+ Add this line to your application’s Gemfile:
153
208
 
154
209
  ```ruby
155
- class AddTokenToAhoyMessages < ActiveRecord::Migration[6.1]
156
- def change
157
- add_column :ahoy_messages, :token, :string
158
- add_index :ahoy_messages, :token
210
+ gem 'redis'
211
+ ```
159
212
 
160
- # for opens
161
- add_column :ahoy_messages, :opened_at, :timestamp
213
+ And create `config/initializers/ahoy_email.rb` with:
162
214
 
163
- # for clicks
164
- add_column :ahoy_messages, :clicked_at, :timestamp
165
- end
166
- end
215
+ ```ruby
216
+ # pass your Redis client if you already have one
217
+ AhoyEmail.subscribers << AhoyEmail::RedisSubscriber.new(redis: Redis.new)
218
+ AhoyEmail.api = true
167
219
  ```
168
220
 
169
- Create an initializer `config/initializers/ahoy_email.rb` with:
221
+ #### Other
222
+
223
+ Create `config/initializers/ahoy_email.rb` with:
170
224
 
171
225
  ```ruby
226
+ class EmailSubscriber
227
+ def track_send(data)
228
+ # your code
229
+ end
230
+
231
+ def track_click(data)
232
+ # your code
233
+ end
234
+
235
+ def stats(campaign = nil)
236
+ # optional, for AhoyEmail.stats
237
+ end
238
+ end
239
+
240
+ AhoyEmail.subscribers << EmailSubscriber
172
241
  AhoyEmail.api = true
173
- ```
242
+ ````
174
243
 
175
- And add to mailers you want to track:
244
+ ### Setup
245
+
246
+ Add to mailers you want to track
176
247
 
177
248
  ```ruby
178
249
  class CouponMailer < ApplicationMailer
179
- track open: true, click: true
250
+ track_clicks campaign: "my-campaign"
180
251
  end
181
252
  ```
182
253
 
@@ -184,7 +255,7 @@ Use only and except to limit actions
184
255
 
185
256
  ```ruby
186
257
  class CouponMailer < ApplicationMailer
187
- track click: true, only: [:welcome]
258
+ track_clicks campaign: "my-campaign", only: [:welcome]
188
259
  end
189
260
  ```
190
261
 
@@ -192,28 +263,10 @@ Or make it conditional
192
263
 
193
264
  ```ruby
194
265
  class CouponMailer < ApplicationMailer
195
- track click: -> { params[:user].opted_in? }
266
+ track_clicks campaign: "my-campaign", if: -> { params[:user].opted_in? }
196
267
  end
197
268
  ```
198
269
 
199
- ### How It Works
200
-
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.
202
-
203
- For clicks, a redirect is added to links to track clicks in HTML emails.
204
-
205
- ```
206
- https://chartkick.com
207
- ```
208
-
209
- becomes
210
-
211
- ```
212
- https://yoursite.com/ahoy/messages/rAnDoMtOkEn/click?url=https%3A%2F%2Fchartkick.com&signature=...
213
- ```
214
-
215
- A signature is added to prevent [open redirects](https://www.owasp.org/index.php/Open_redirect).
216
-
217
270
  Skip specific links with:
218
271
 
219
272
  ```erb
@@ -232,108 +285,67 @@ You can specify the domain to use with:
232
285
  AhoyEmail.default_options[:url_options] = {host: "mydomain.com"}
233
286
  ```
234
287
 
235
- ### Events
288
+ ### Stats
236
289
 
237
- Subscribe to open and click events by adding to the initializer:
290
+ Get stats for all campaigns
238
291
 
239
292
  ```ruby
240
- class EmailSubscriber
241
- def open(event)
242
- # your code
243
- end
244
-
245
- def click(event)
246
- # your code
247
- end
248
- end
249
-
250
- AhoyEmail.subscribers << EmailSubscriber.new
293
+ AhoyEmail.stats
251
294
  ```
252
295
 
253
- Here’s an example if you use [Ahoy](https://github.com/ankane/ahoy) to track visits and events:
296
+ Get stats for a specific campaign
254
297
 
255
298
  ```ruby
256
- class EmailSubscriber
257
- def open(event)
258
- event[:controller].ahoy.track "Email opened", message_id: event[:message].id
259
- end
260
-
261
- def click(event)
262
- event[:controller].ahoy.track "Email clicked", message_id: event[:message].id, url: event[:url]
263
- end
264
- end
265
-
266
- AhoyEmail.subscribers << EmailSubscriber.new
299
+ AhoyEmail.stats("my-campaign")
267
300
  ```
268
301
 
269
- ## Data Protection
270
-
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.
302
+ ## Upgrading
272
303
 
273
- Create `app/models/ahoy/message.rb` with:
304
+ ### 2.0
274
305
 
275
- ```ruby
276
- class Ahoy::Message < ApplicationRecord
277
- self.table_name = "ahoy_messages"
278
- belongs_to :user, polymorphic: true, optional: true
306
+ Ahoy Email 2.0 brings a number of changes. Here are a few to be aware of:
279
307
 
280
- encrypts :to
281
- blind_index :to
282
- end
283
- ```
308
+ - The `to` field is encrypted by default for new installations. If you’d like to encrypt an existing installation, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and follow the Lockbox instructions for [migrating existing data](https://github.com/ankane/lockbox#migrating-existing-data).
284
309
 
285
- ## Data Retention
286
-
287
- Delete older data with:
310
+ For the model, create `app/models/ahoy/message.rb` with:
288
311
 
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
- ```
312
+ ```ruby
313
+ class Ahoy::Message < ActiveRecord::Base
314
+ self.table_name = "ahoy_messages"
298
315
 
299
- ## Reference
316
+ belongs_to :user, polymorphic: true, optional: true
300
317
 
301
- Set global options
318
+ encrypts :to, migrating: true
319
+ blind_index :to, migrating: true
320
+ end
321
+ ```
302
322
 
303
- ```ruby
304
- AhoyEmail.default_options[:user] = -> { params[:admin] }
305
- ```
323
+ - The `track` method has been broken into:
306
324
 
307
- Use a different model
325
+ - `has_history` for message history
326
+ - `utm_params` for UTM tagging
327
+ - `track_clicks` for click analytics
308
328
 
309
- ```ruby
310
- AhoyEmail.message_model = -> { UserMessage }
311
- ```
329
+ - Message history is no longer enabled by default. Add `has_history` to individual mailers, or create an initializer with:
312
330
 
313
- Or fully customize how messages are tracked
331
+ ```ruby
332
+ AhoyEmail.default_options[:message] = true
333
+ ```
314
334
 
315
- ```ruby
316
- AhoyEmail.track_method = lambda do |data|
317
- # your code
318
- end
319
- ```
335
+ - For privacy, open tracking has been removed.
320
336
 
321
- ## Mongoid
337
+ - For clicks, we encourage you to try [aggregate analytics](#click-analytics) to measure the performance of campaigns. You can use a library like [Rollup](https://github.com/ankane/rollup) to aggregate existing data, then drop the `token` and `clicked_at` columns.
322
338
 
323
- If you prefer to use Mongoid instead of Active Record, create `app/models/ahoy/message.rb` with:
339
+ To keep individual analytics, use `has_history` and `track_clicks campaign: false` and create an initializer with:
324
340
 
325
- ```ruby
326
- class Ahoy::Message
327
- include Mongoid::Document
341
+ ```ruby
342
+ AhoyEmail.save_token = true
343
+ AhoyEmail.subscribers << AhoyEmail::MessageSubscriber
344
+ ```
328
345
 
329
- belongs_to :user, polymorphic: true, optional: true, index: true
346
+ If you use a custom subscriber, `:message` is no longer included in click events. You can use `:token` to query the message if needed.
330
347
 
331
- field :to, type: String
332
- field :mailer, type: String
333
- field :subject, type: String
334
- field :sent_at, type: Time
335
- end
336
- ```
348
+ - Users are shown a link expired page when signature verification fails instead of being redirected to the homepage when `AhoyEmail.invalid_redirect_url` is not set
337
349
 
338
350
  ## History
339
351