ahoy_email 1.0.2 → 2.0.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: 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
+ ```