ahoy_email 1.0.2 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e39b9c6d5b1c32cc0a7a1bcc5da1e08205d6187e8eb5aec1505295ac1de36c64
4
- data.tar.gz: c8f94cc014a6ab2cebe9c718a02989505fa9086d4b6bdbaed1e35a13bf269259
3
+ metadata.gz: 69eb9c77891a37c75ef7f7683211c90159cbb8aefd64fa14a0b1b35d2e16d0eb
4
+ data.tar.gz: a937ba8e9362d1c2551f5c193b9a3bbf1b4132f3df9ddb77f3f838f633fb2f07
5
5
  SHA512:
6
- metadata.gz: fc2721f83dc1eb2098d4d16166c3e78a07184007b61fd320ab4e50b26dc8dcc34583482baf8af1154d1b12e904c9113a69f4f3d24b18c1efc5dc26cf88e19aa2
7
- data.tar.gz: 20f100d9f5c34ed8553ef778e4330df5cf35458d50f1bcfb2a28cdf3e6b8750d59b65b1dc153b23c773db4959ae10e051a28828852b0da06064c18a10f8c685c
6
+ metadata.gz: 4b12c970be432d7db95fdb8eaade5766f69fc7826a94f41474ba5c2a35da1ea85b6317f83250cb1c8f41c7fe876028b1377958709d2c84ff9bd303926ac8ab5a
7
+ data.tar.gz: 96dcc647ee3777e27b14d7628025d96ea92efce7160d36da0b066b72d9dc5aac8196008699a93673d81d0fdcb909aa69874b349dffdbaf0e32e4d7511a32df5a
data/CHANGELOG.md CHANGED
@@ -1,13 +1,48 @@
1
- ## 1.0.2
1
+ ## 2.0.1 (2021-03-08)
2
+
3
+ - Added database subscriber
4
+
5
+ ## 2.0.0 (2021-03-06)
6
+
7
+ - Made `to` field encrypted by default for new installations
8
+ - Added click analytics for Redis
9
+ - Added send events to subscribers
10
+ - Removed support for Rails < 5.2
11
+
12
+ Breaking changes
13
+
14
+ - The `track` method has been broken into `has_history` for message history, `utm_params` for UTM tagging, and `track_clicks` for click analytics
15
+ - Message history is no longer enabled by default
16
+ - Open tracking has been removed
17
+ - `:message` is no longer included in click events
18
+ - 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
19
+
20
+ ## 1.1.1 (2021-03-06)
21
+
22
+ - Added support for classes for subscribers
23
+ - Use `datetime` type in migration
24
+
25
+ ## 1.1.0 (2019-07-15)
26
+
27
+ - Made `opened_at` optional with click tracking
28
+ - Fixed secret token for environment variables
29
+ - Removed support for Rails 4.2
30
+
31
+ ## 1.0.3 (2019-02-18)
32
+
33
+ - Fixed custom message model
34
+ - Fixed `message` option with proc
35
+
36
+ ## 1.0.2 (2018-10-02)
2
37
 
3
38
  - Fixed error with Ruby < 2.5
4
39
  - Fixed UTM parameters storage on model
5
40
 
6
- ## 1.0.1
41
+ ## 1.0.1 (2018-09-27)
7
42
 
8
43
  - Use observer instead of interceptor
9
44
 
10
- ## 1.0.0
45
+ ## 1.0.0 (2018-09-27)
11
46
 
12
47
  - Removed support for Rails < 4.2
13
48
 
@@ -20,91 +55,91 @@ Breaking changes
20
55
  - `AhoyEmail.track` was removed in favor of `AhoyEmail.default_options`
21
56
  - The `heuristic_parse` option was removed and is now the default
22
57
 
23
- ## 0.5.2
58
+ ## 0.5.2 (2018-04-26)
24
59
 
25
60
  - Fixed secret token for Rails 5.2
26
61
  - Added `heuristic_parse` option
27
62
 
28
- ## 0.5.1
63
+ ## 0.5.1 (2018-04-19)
29
64
 
30
65
  - Fixed deprecation warning in Rails 5.2
31
66
  - Added `unsubscribe_links` option
32
67
  - Allow `message_model` to accept a proc
33
68
  - Use `references` in migration
34
69
 
35
- ## 0.5.0
70
+ ## 0.5.0 (2017-05-01)
36
71
 
37
72
  - Added support for Rails 5.1
38
73
  - Added `invalid_redirect_url`
39
74
 
40
- ## 0.4.0
75
+ ## 0.4.0 (2016-09-01)
41
76
 
42
77
  - Fixed `belongs_to` error in Rails 5
43
78
  - Include `safely_block` gem without polluting global namespace
44
79
 
45
- ## 0.3.2
80
+ ## 0.3.2 (2016-07-27)
46
81
 
47
82
  - Fixed deprecation warning for Rails 5
48
83
  - Do not track content by default on fresh installations
49
84
 
50
- ## 0.3.1
85
+ ## 0.3.1 (2016-05-11)
51
86
 
52
87
  - Fixed deprecation warnings
53
88
  - Fixed `stack level too deep` error
54
89
 
55
- ## 0.3.0
90
+ ## 0.3.0 (2015-12-16)
56
91
 
57
92
  - Added safely for error reporting
58
93
  - Fixed error with `to`
59
94
  - Prevent duplicate records when mail called multiple times
60
95
 
61
- ## 0.2.4
96
+ ## 0.2.4 (2015-07-29)
62
97
 
63
98
  - Added `extra` option for extra attributes
64
99
 
65
- ## 0.2.3
100
+ ## 0.2.3 (2015-03-22)
66
101
 
67
102
  - Save utm parameters
68
103
  - Added `url_options`
69
104
  - Skip tracking for `mailto` links
70
105
  - Only set secret token if not already set
71
106
 
72
- ## 0.2.2
107
+ ## 0.2.2 (2014-08-31)
73
108
 
74
109
  - Fixed secret token for Rails 4.1
75
110
  - Fixed links with href
76
111
  - Fixed message id for Rails 3.1
77
112
 
78
- ## 0.2.1
113
+ ## 0.2.1 (2014-05-26)
79
114
 
80
115
  - Added `only` and `except` options
81
116
 
82
- ## 0.2.0
117
+ ## 0.2.0 (2014-05-10)
83
118
 
84
119
  - Enable tracking when track is called by default
85
120
 
86
- ## 0.1.5
121
+ ## 0.1.5 (2014-05-09)
87
122
 
88
123
  - Rails 3 fix
89
124
 
90
- ## 0.1.4
125
+ ## 0.1.4 (2014-05-04)
91
126
 
92
127
  - Try not to rewrite unsubscribe links
93
128
 
94
- ## 0.1.3
129
+ ## 0.1.3 (2014-05-03)
95
130
 
96
131
  - Added `to` and `mailer` fields
97
132
  - Added subscribers for open and click events
98
133
 
99
- ## 0.1.2
134
+ ## 0.1.2 (2014-05-01)
100
135
 
101
136
  - Added `AhoyEmail.track` (fix)
102
137
 
103
- ## 0.1.1
138
+ ## 0.1.1 (2014-04-30)
104
139
 
105
140
  - Use secure compare for signature verification
106
141
  - Fixed deprecation warnings
107
142
 
108
- ## 0.1.0
143
+ ## 0.1.0 (2014-04-29)
109
144
 
110
145
  - First major release
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2018 Andrew Kane
1
+ Copyright (c) 2014-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,20 +1,14 @@
1
1
  # Ahoy Email
2
2
 
3
- :postbox: Email analytics for Rails
3
+ First-party email analytics for Rails
4
4
 
5
- You get:
5
+ **Ahoy Email 2.0 was recently released** - see [how to upgrade](#upgrading)
6
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)
7
+ :fire: For web and native app analytics, check out [Ahoy](https://github.com/ankane/ahoy)
12
8
 
13
9
  :bullettrain_side: To manage unsubscribes, check out [Mailkick](https://github.com/ankane/mailkick)
14
10
 
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)
11
+ [![Build Status](https://github.com/ankane/ahoy_email/workflows/build/badge.svg?branch=master)](https://github.com/ankane/ahoy_email/actions)
18
12
 
19
13
  ## Installation
20
14
 
@@ -24,42 +18,65 @@ Add this line to your application’s Gemfile:
24
18
  gem 'ahoy_email'
25
19
  ```
26
20
 
27
- And run the generator. This creates a model to store messages.
21
+ ## Getting Started
22
+
23
+ There are three main features, which can be used independently:
24
+
25
+ - [Message history](#message-history)
26
+ - [UTM tagging](#utm-tagging)
27
+ - [Click analytics](#click-analytics)
28
+
29
+ ## Message History
30
+
31
+ To encrypt email addresses, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
28
32
 
29
33
  ```sh
30
- rails generate ahoy_email:install
34
+ rails generate ahoy:messages
31
35
  rails db:migrate
32
36
  ```
33
37
 
34
- ## How It Works
38
+ If you prefer not to encrypt data, run:
35
39
 
36
- ### Message History
40
+ ```sh
41
+ rails generate ahoy:messages --unencrypted
42
+ rails db:migrate
43
+ ```
37
44
 
38
- Ahoy creates an `Ahoy::Message` record for each email sent by default. You can disable history for a mailer:
45
+ Then, add to mailers:
39
46
 
40
47
  ```ruby
41
48
  class CouponMailer < ApplicationMailer
42
- track message: false # use only/except to limit actions
49
+ has_history
43
50
  end
44
51
  ```
45
52
 
46
- Or by default:
53
+ Use the `Ahoy::Message` model to query messages:
47
54
 
48
55
  ```ruby
49
- AhoyEmail.default_options[:message] = false
56
+ Ahoy::Message.last
50
57
  ```
51
58
 
52
- ### Users
59
+ Use only and except to limit actions
60
+
61
+ ```ruby
62
+ class CouponMailer < ApplicationMailer
63
+ has_history only: [:welcome]
64
+ end
65
+ ```
53
66
 
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.
67
+ To store history for all mailers, create `config/initializers/ahoy_email.rb` with:
68
+
69
+ ```ruby
70
+ AhoyEmail.default_options[:message] = true
71
+ ```
55
72
 
56
- By default, Ahoy tries `@user` then `params[:user]` then `User.find_by(email: message.to.first)` to find the user.
73
+ ### Users
57
74
 
58
- 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:
59
76
 
60
77
  ```ruby
61
78
  class CouponMailer < ApplicationMailer
62
- track user: -> { params[:some_user] }
79
+ has_history user: -> { params[:some_user] }
63
80
  end
64
81
  ```
65
82
 
@@ -79,25 +96,23 @@ And run:
79
96
  user.messages
80
97
  ```
81
98
 
82
- ### Extra Attributes
83
-
84
- Record extra attributes on the `Ahoy::Message` model.
99
+ ### Extra Data
85
100
 
86
- Create a migration to add extra attributes to the `ahoy_messages` table. For example:
101
+ Add extra data to messages. Create a migration like:
87
102
 
88
103
  ```ruby
89
- class AddCouponIdToAhoyMessages < ActiveRecord::Migration[5.2]
104
+ class AddCouponIdToAhoyMessages < ActiveRecord::Migration[6.1]
90
105
  def change
91
106
  add_column :ahoy_messages, :coupon_id, :integer
92
107
  end
93
108
  end
94
109
  ```
95
110
 
96
- Then use:
111
+ And use:
97
112
 
98
113
  ```ruby
99
114
  class CouponMailer < ApplicationMailer
100
- track extra: {coupon_id: 1}
115
+ has_history extra: {coupon_id: 1}
101
116
  end
102
117
  ```
103
118
 
@@ -105,213 +120,244 @@ You can use a proc as well.
105
120
 
106
121
  ```ruby
107
122
  class CouponMailer < ApplicationMailer
108
- track extra: -> { {coupon_id: params[:coupon].id} }
123
+ has_history extra: -> { {coupon_id: params[:coupon].id} }
109
124
  end
110
125
  ```
111
126
 
112
- ### UTM Tagging
127
+ ### Options
113
128
 
114
- Automatically add UTM parameters to links.
129
+ Set global options
115
130
 
116
131
  ```ruby
117
- class CouponMailer < ApplicationMailer
118
- track utm_params: true # use only/except to limit actions
119
- end
132
+ AhoyEmail.default_options[:user] = -> { params[:admin] }
120
133
  ```
121
134
 
122
- The defaults are:
135
+ Use a different model
123
136
 
124
- - `utm_medium` - `email`
125
- - `utm_source` - the mailer name like `coupon_mailer`
126
- - `utm_campaign` - the mailer action like `offer`
137
+ ```ruby
138
+ AhoyEmail.message_model = -> { UserMessage }
139
+ ```
127
140
 
128
- You can customize them with:
141
+ Or fully customize how messages are tracked
129
142
 
130
143
  ```ruby
131
- class CouponMailer < ApplicationMailer
132
- track utm_params: true, utm_campaign: -> { "coupon#{params[:coupon].id}" }
144
+ AhoyEmail.track_method = lambda do |data|
145
+ # your code
133
146
  end
134
147
  ```
135
148
 
136
- Skip specific links with:
149
+ ### Data Retention
137
150
 
138
- ```erb
139
- <%= link_to "Go", some_url, data: {skip_utm_params: true} %>
151
+ Delete older data with:
152
+
153
+ ```ruby
154
+ Ahoy::Message.where("created_at < ?", 1.year.ago).in_batches.delete_all
140
155
  ```
141
156
 
142
- ### Opens & Clicks
157
+ Delete data for a specific user with:
143
158
 
144
- #### Setup
159
+ ```ruby
160
+ Ahoy::Message.where(user_id: 1).in_batches.delete_all
161
+ ```
145
162
 
146
- Additional setup is required to track opens and clicks.
163
+ ## UTM Tagging
147
164
 
148
- Create a migration with:
165
+ Use UTM tagging to attribute visits or conversions to an email campaign. Add UTM parameters to links with:
149
166
 
150
167
  ```ruby
151
- class AddTokenToAhoyMessages < ActiveRecord::Migration[5.2]
152
- def change
153
- add_column :ahoy_messages, :token, :string
154
- add_column :ahoy_messages, :opened_at, :timestamp
155
- add_column :ahoy_messages, :clicked_at, :timestamp
156
-
157
- add_index :ahoy_messages, :token
158
- end
168
+ class CouponMailer < ApplicationMailer
169
+ utm_params
159
170
  end
160
171
  ```
161
172
 
162
- Create an initializer `config/initializers/ahoy_email.rb` with:
173
+ The defaults are:
174
+
175
+ - `utm_medium` - `email`
176
+ - `utm_source` - the mailer name like `coupon_mailer`
177
+ - `utm_campaign` - the mailer action like `offer`
178
+
179
+ You can customize them with:
163
180
 
164
181
  ```ruby
165
- AhoyEmail.api = true
182
+ class CouponMailer < ApplicationMailer
183
+ utm_params utm_campaign: -> { "coupon#{params[:coupon].id}" }
184
+ end
166
185
  ```
167
186
 
168
- And add to mailers you want to track:
187
+ Use only and except to limit actions
169
188
 
170
189
  ```ruby
171
190
  class CouponMailer < ApplicationMailer
172
- track open: true, click: true # use only/except to limit actions
191
+ utm_params only: [:welcome]
173
192
  end
174
193
  ```
175
194
 
176
- #### How It Works
195
+ Skip specific links with:
177
196
 
178
- 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.
197
+ ```erb
198
+ <%= link_to "Go", some_url, data: {skip_utm_params: true} %>
199
+ ```
179
200
 
180
- For clicks, a redirect is added to links to track clicks in HTML emails.
201
+ ## Click Analytics
181
202
 
182
- ```
183
- https://chartkick.com
184
- ```
203
+ You can track click-through rate to see how well campaigns are performing. Stats can be stored in your database, Redis, or any other data store.
185
204
 
186
- becomes
205
+ #### Database
187
206
 
188
- ```
189
- https://yoursite.com/ahoy/messages/rAnDoMtOkEn/click?url=https%3A%2F%2Fchartkick.com&signature=...
190
- ```
207
+ Run:
191
208
 
192
- A signature is added to prevent [open redirects](https://www.owasp.org/index.php/Open_redirect).
209
+ ```sh
210
+ rails generate ahoy:clicks
211
+ rails db:migrate
212
+ ```
193
213
 
194
- Skip specific links with:
214
+ And create `config/initializers/ahoy_email.rb` with:
195
215
 
196
- ```erb
197
- <%= link_to "Go", some_url, data: {skip_click: true} %>
216
+ ```ruby
217
+ AhoyEmail.subscribers << AhoyEmail::DatabaseSubscriber
218
+ AhoyEmail.api = true
198
219
  ```
199
220
 
200
- By default, unsubscribe links are excluded. To change this, use:
221
+ #### Redis
222
+
223
+ Add this line to your application’s Gemfile:
201
224
 
202
225
  ```ruby
203
- AhoyEmail.default_options[:unsubscribe_links] = true
226
+ gem 'redis'
204
227
  ```
205
228
 
206
- You can specify the domain to use with:
229
+ And create `config/initializers/ahoy_email.rb` with:
207
230
 
208
231
  ```ruby
209
- AhoyEmail.default_options[:url_options] = {host: "mydomain.com"}
232
+ # pass your Redis client if you already have one
233
+ AhoyEmail.subscribers << AhoyEmail::RedisSubscriber.new(redis: Redis.new)
234
+ AhoyEmail.api = true
210
235
  ```
211
236
 
212
- #### Events
237
+ #### Other
213
238
 
214
- Subscribe to open and click events by adding to the initializer:
239
+ Create `config/initializers/ahoy_email.rb` with:
215
240
 
216
241
  ```ruby
217
242
  class EmailSubscriber
218
- def open(event)
243
+ def track_send(data)
219
244
  # your code
220
245
  end
221
246
 
222
- def click(event)
247
+ def track_click(data)
223
248
  # your code
224
249
  end
250
+
251
+ def stats(campaign)
252
+ # optional, for AhoyEmail.stats
253
+ end
225
254
  end
226
255
 
227
- AhoyEmail.subscribers << EmailSubscriber.new
228
- ```
256
+ AhoyEmail.subscribers << EmailSubscriber
257
+ AhoyEmail.api = true
258
+ ````
229
259
 
230
- Here’s an example if you use [Ahoy](https://github.com/ankane/ahoy) to track visits and events:
260
+ ### Usage
231
261
 
232
- ```ruby
233
- class EmailSubscriber
234
- def open(event)
235
- event[:controller].ahoy.track "Email opened", message_id: event[:message].id
236
- end
262
+ Add to mailers you want to track
237
263
 
238
- def click(event)
239
- event[:controller].ahoy.track "Email clicked", message_id: event[:message].id, url: event[:url]
240
- end
264
+ ```ruby
265
+ class CouponMailer < ApplicationMailer
266
+ track_clicks campaign: "my-campaign"
241
267
  end
242
-
243
- AhoyEmail.subscribers << EmailSubscriber.new
244
268
  ```
245
269
 
246
- ## Reference
270
+ If storing stats in the database, the mailer should also use `has_history`
247
271
 
248
- Set global options
272
+ Use only and except to limit actions
249
273
 
250
274
  ```ruby
251
- AhoyEmail.default_options[:user] = -> { params[:admin] }
275
+ class CouponMailer < ApplicationMailer
276
+ track_clicks campaign: "my-campaign", only: [:welcome]
277
+ end
252
278
  ```
253
279
 
254
- Use a different model
280
+ Or make it conditional
255
281
 
256
282
  ```ruby
257
- AhoyEmail.message_model = -> { UserMessage }
283
+ class CouponMailer < ApplicationMailer
284
+ track_clicks campaign: "my-campaign", if: -> { params[:user].opted_in? }
285
+ end
258
286
  ```
259
287
 
260
- Or fully customize how messages are tracked
288
+ Skip specific links with:
261
289
 
262
- ```ruby
263
- AhoyEmail.track_method = lambda do |data|
264
- # your code
265
- end
290
+ ```erb
291
+ <%= link_to "Go", some_url, data: {skip_click: true} %>
266
292
  ```
267
293
 
268
- ## Mongoid
294
+ By default, unsubscribe links are excluded. To change this, use:
269
295
 
270
- If you prefer to use Mongoid instead of ActiveRecord, create `app/models/ahoy/message.rb` with:
296
+ ```ruby
297
+ AhoyEmail.default_options[:unsubscribe_links] = true
298
+ ```
299
+
300
+ You can specify the domain to use with:
271
301
 
272
302
  ```ruby
273
- class Ahoy::Message
274
- include Mongoid::Document
303
+ AhoyEmail.default_options[:url_options] = {host: "mydomain.com"}
304
+ ```
275
305
 
276
- belongs_to :user, polymorphic: true, optional: true, index: true
306
+ ### Stats
277
307
 
278
- field :to, type: String
279
- field :mailer, type: String
280
- field :subject, type: String
281
- field :sent_at, type: Time
282
- end
308
+ Get stats for a campaign
309
+
310
+ ```ruby
311
+ AhoyEmail.stats("my-campaign")
283
312
  ```
284
313
 
285
314
  ## Upgrading
286
315
 
287
- ### 1.0
316
+ ### 2.0
317
+
318
+ Ahoy Email 2.0 brings a number of changes. Here are a few to be aware of:
288
319
 
289
- Breaking changes
320
+ - 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).
290
321
 
291
- - UTM tagging, open tracking, and click tracking are no longer enabled by default. To enable, create an initializer with:
322
+ For the model, create `app/models/ahoy/message.rb` with:
292
323
 
293
324
  ```ruby
294
- AhoyEmail.api = true
325
+ class Ahoy::Message < ActiveRecord::Base
326
+ self.table_name = "ahoy_messages"
295
327
 
296
- AhoyEmail.default_options[:open] = true
297
- AhoyEmail.default_options[:click] = true
298
- AhoyEmail.default_options[:utm_params] = true
328
+ belongs_to :user, polymorphic: true, optional: true
329
+
330
+ encrypts :to, migrating: true
331
+ blind_index :to, migrating: true
332
+ end
299
333
  ```
300
334
 
301
- - Only sent emails are recorded
302
- - Proc options are now executed in the context of the mailer and take no arguments
335
+ - The `track` method has been broken into:
336
+
337
+ - `has_history` for message history
338
+ - `utm_params` for UTM tagging
339
+ - `track_clicks` for click analytics
340
+
341
+ - Message history is no longer enabled by default. Add `has_history` to individual mailers, or create an initializer with:
303
342
 
304
343
  ```ruby
305
- # old
306
- user: ->(mailer, message) { User.find_by(email: message.to.first) }
344
+ AhoyEmail.default_options[:message] = true
345
+ ```
346
+
347
+ - For privacy, open tracking has been removed.
307
348
 
308
- # new
309
- user: -> { User.find_by(email: message.to.first) }
349
+ - 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.
350
+
351
+ To keep individual analytics, use `has_history` and `track_clicks campaign: false` and create an initializer with:
352
+
353
+ ```ruby
354
+ AhoyEmail.save_token = true
355
+ AhoyEmail.subscribers << AhoyEmail::MessageSubscriber
310
356
  ```
311
357
 
312
- - Invalid options now throw an `ArgumentError`
313
- - `AhoyEmail.track` was removed in favor of `AhoyEmail.default_options`
314
- - The `heuristic_parse` option was removed and is now the default
358
+ If you use a custom subscriber, `:message` is no longer included in click events. You can use `:token` to query the message if needed.
359
+
360
+ - 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
315
361
 
316
362
  ## History
317
363
 
@@ -325,3 +371,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
325
371
  - Fix bugs and [submit pull requests](https://github.com/ankane/ahoy_email/pulls)
326
372
  - Write, clarify, or fix documentation
327
373
  - Suggest or add new features
374
+
375
+ To get started with development:
376
+
377
+ ```sh
378
+ git clone https://github.com/ankane/ahoy_email.git
379
+ cd ahoy_email
380
+ bundle install
381
+ bundle exec rake test
382
+ ```