ahoy_email 0.5.2 → 1.1.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: 1bd419ac1420c0d404b6137e3804545193969ecd8aab0444c919e9f7b5e5fae4
4
- data.tar.gz: 3cce5d71d203a287992fc6560910f596f3cf74b0ef24861df8f5ed27ad9bd3b1
3
+ metadata.gz: c056fb39ad0a8774c23582f8a37fbea9f460d903f4f05565e31b5670b0ce615d
4
+ data.tar.gz: 5b489942efd5cb224f068d06d06fdd9e9e68f65d256ded15be359ccdfc4190ec
5
5
  SHA512:
6
- metadata.gz: b163a83c5a2f78e7a2576940f1d7d0bb25bb38fec0203571adf387ffa2e380c5ed164fff92ba12c00f81a30d7b43b39e41d7a68a1d94b86f2dfc27c48139eb16
7
- data.tar.gz: 816a961760e8fedf55efa9b5b59f38decdf0fdd12531dc5a52f83c09178bddf820e93eb375c47100e10bd4e9f2aba7b4c2efabde952ebfc589cf20d2d0418537
6
+ metadata.gz: 55a1a58246738297be5e07198ef58014a13596fa372cf8127a4b4670ddfb7465c09371250ff269306cfc03ef7704ec28bc716669857eb6bc40fbe3132c94564a
7
+ data.tar.gz: b58a064519fb0ef57a255db8a57c4b0101f0fbf029e3110f1ece205e927bb13a8e4c3d5f95888e36be41f25eed6f0dc73ee995ff546d27771604c6b4058fd392
data/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ ## 1.1.0
2
+
3
+ - Made `opened_at` optional with click tracking
4
+ - Fixed secret token for environment variables
5
+ - Removed support for Rails 4.2
6
+
7
+ ## 1.0.3
8
+
9
+ - Fixed custom message model
10
+ - Fixed `message` option with proc
11
+
12
+ ## 1.0.2
13
+
14
+ - Fixed error with Ruby < 2.5
15
+ - Fixed UTM parameters storage on model
16
+
17
+ ## 1.0.1
18
+
19
+ - Use observer instead of interceptor
20
+
21
+ ## 1.0.0
22
+
23
+ - Removed support for Rails < 4.2
24
+
25
+ Breaking changes
26
+
27
+ - UTM tagging, open tracking, and click tracking are no longer enabled by default
28
+ - Only sent emails are recorded
29
+ - Proc options are now executed in the context of the mailer and take no arguments
30
+ - Invalid options now throw an `ArgumentError`
31
+ - `AhoyEmail.track` was removed in favor of `AhoyEmail.default_options`
32
+ - The `heuristic_parse` option was removed and is now the default
33
+
1
34
  ## 0.5.2
2
35
 
3
36
  - Fixed secret token for Rails 5.2
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,47 @@
1
+ # Contributing
2
+
3
+ First, thanks for wanting to contribute. You’re awesome! :heart:
4
+
5
+ ## Help
6
+
7
+ We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
8
+
9
+ All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
10
+
11
+ ## Bugs
12
+
13
+ Think you’ve discovered a bug?
14
+
15
+ 1. Search existing issues to see if it’s been reported.
16
+ 2. Try the `master` branch to make sure it hasn’t been fixed.
17
+
18
+ ```rb
19
+ gem "ahoy_email", github: "ankane/ahoy_email"
20
+ ```
21
+
22
+ If the above steps don’t help, create an issue. Include:
23
+
24
+ - Detailed steps to reproduce
25
+ - Complete backtraces for exceptions
26
+
27
+ ## New Features
28
+
29
+ If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
30
+
31
+ ## Pull Requests
32
+
33
+ Fork the project and create a pull request. A few tips:
34
+
35
+ - Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
36
+ - Follow the existing style. The code should read like it’s written by a single person.
37
+ - Add one or more tests if possible. Make sure existing tests pass with:
38
+
39
+ ```sh
40
+ bundle exec rake test
41
+ ```
42
+
43
+ Feel free to open an issue to get feedback on your idea before spending too much time on it.
44
+
45
+ ---
46
+
47
+ This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Andrew Kane
1
+ Copyright (c) 2014-2019 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Ahoy Email
2
2
 
3
- :postbox: Simple, powerful email tracking for Rails
3
+ :postbox: Email analytics for Rails
4
4
 
5
5
  You get:
6
6
 
7
7
  - A history of emails sent to each user
8
8
  - Easy UTM tagging
9
- - Open and click tracking
9
+ - Optional open and click tracking
10
10
 
11
- Works with any email service.
11
+ **Ahoy Email 1.0 was recently released!** See [how to upgrade](#upgrading)
12
12
 
13
13
  :bullettrain_side: To manage unsubscribes, check out [Mailkick](https://github.com/ankane/mailkick)
14
14
 
@@ -33,27 +33,37 @@ rails db:migrate
33
33
 
34
34
  ## How It Works
35
35
 
36
- Ahoy creates an `Ahoy::Message` every time an email is sent by default.
36
+ ### Message History
37
+
38
+ Ahoy creates an `Ahoy::Message` record for each email sent by default. You can disable history for a mailer:
39
+
40
+ ```ruby
41
+ class CouponMailer < ApplicationMailer
42
+ track message: false # use only/except to limit actions
43
+ end
44
+ ```
45
+
46
+ Or by default:
47
+
48
+ ```ruby
49
+ AhoyEmail.default_options[:message] = false
50
+ ```
37
51
 
38
52
  ### Users
39
53
 
40
- Ahoy tracks 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.
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.
41
55
 
42
- By default, Ahoy tries `User.where(email: message.to.first).first` to find the user.
56
+ By default, Ahoy tries `@user` then `params[:user]` then `User.find_by(email: message.to)` to find the user.
43
57
 
44
58
  You can pass a specific user with:
45
59
 
46
60
  ```ruby
47
- class UserMailer < ApplicationMailer
48
- def welcome_email(user)
49
- # ...
50
- track user: user
51
- mail to: user.email
52
- end
61
+ class CouponMailer < ApplicationMailer
62
+ track user: -> { params[:some_user] }
53
63
  end
54
64
  ```
55
65
 
56
- The user association is [polymorphic](http://railscasts.com/episodes/154-polymorphic-association), so use it with any model.
66
+ The user association is [polymorphic](https://railscasts.com/episodes/154-polymorphic-association), so use it with any model.
57
67
 
58
68
  To get all messages sent to a user, add an association:
59
69
 
@@ -69,124 +79,148 @@ And run:
69
79
  user.messages
70
80
  ```
71
81
 
72
- ### UTM Parameters
82
+ ### Extra Attributes
83
+
84
+ Record extra attributes on the `Ahoy::Message` model.
73
85
 
74
- UTM parameters are added to links if they don’t already exist.
86
+ Create a migration to add extra attributes to the `ahoy_messages` table. For example:
75
87
 
76
- The defaults are:
88
+ ```ruby
89
+ class AddCouponIdToAhoyMessages < ActiveRecord::Migration[5.2]
90
+ def change
91
+ add_column :ahoy_messages, :coupon_id, :integer
92
+ end
93
+ end
94
+ ```
77
95
 
78
- - utm_medium - `email`
79
- - utm_source - the mailer name like `user_mailer`
80
- - utm_campaign - the mailer action like `welcome_email`
96
+ Then use:
81
97
 
82
- Use `track utm_params: false` to skip tagging, or skip specific links with:
98
+ ```ruby
99
+ class CouponMailer < ApplicationMailer
100
+ track extra: {coupon_id: 1}
101
+ end
102
+ ```
83
103
 
104
+ You can use a proc as well.
84
105
 
85
- ```html
86
- <a data-skip-utm-params="true" href="...">Break it down</a>
106
+ ```ruby
107
+ class CouponMailer < ApplicationMailer
108
+ track extra: -> { {coupon_id: params[:coupon].id} }
109
+ end
87
110
  ```
88
111
 
89
- ### Opens
112
+ ### UTM Tagging
90
113
 
91
- An invisible pixel is added right before the `</body>` tag in HTML emails.
114
+ Automatically add UTM parameters to links.
92
115
 
93
- If the recipient has images enabled in his or her email client, the pixel is loaded and the open time recorded.
116
+ ```ruby
117
+ class CouponMailer < ApplicationMailer
118
+ track utm_params: true # use only/except to limit actions
119
+ end
120
+ ```
94
121
 
95
- Use `track open: false` to skip this.
122
+ The defaults are:
96
123
 
97
- ### Clicks
124
+ - `utm_medium` - `email`
125
+ - `utm_source` - the mailer name like `coupon_mailer`
126
+ - `utm_campaign` - the mailer action like `offer`
98
127
 
99
- A redirect is added to links to track clicks in HTML emails.
128
+ You can customize them with:
100
129
 
101
- ```
102
- https://chartkick.com
130
+ ```ruby
131
+ class CouponMailer < ApplicationMailer
132
+ track utm_params: true, utm_campaign: -> { "coupon#{params[:coupon].id}" }
133
+ end
103
134
  ```
104
135
 
105
- becomes
136
+ Skip specific links with:
106
137
 
107
- ```
108
- https://yoursite.com/ahoy/messages/rAnDoMtOkEn/click?url=https%3A%2F%2Fchartkick.com&signature=...
138
+ ```erb
139
+ <%= link_to "Go", some_url, data: {skip_utm_params: true} %>
109
140
  ```
110
141
 
111
- A signature is added to prevent [open redirects](https://www.owasp.org/index.php/Open_redirect).
142
+ ### Opens & Clicks
112
143
 
113
- Use `track click: false` to skip tracking, or skip specific links with:
114
-
115
- ```html
116
- <a data-skip-click="true" href="...">Can't touch this</a>
117
- ```
144
+ #### Setup
118
145
 
119
- ### Extra Attributes
146
+ Additional setup is required to track opens and clicks.
120
147
 
121
- Create a migration to add extra attributes to the `ahoy_messages` table, for example:
148
+ Create a migration with:
122
149
 
123
150
  ```ruby
124
- class AddCampaignIdToAhoyMessages < ActiveRecord::Migration
151
+ class AddTokenToAhoyMessages < ActiveRecord::Migration[5.2]
125
152
  def change
126
- add_column :ahoy_messages, :campaign_id, :integer
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
127
158
  end
128
159
  end
129
160
  ```
130
161
 
131
- Then use:
162
+ Create an initializer `config/initializers/ahoy_email.rb` with:
163
+
164
+ ```ruby
165
+ AhoyEmail.api = true
166
+ ```
167
+
168
+ And add to mailers you want to track:
132
169
 
133
170
  ```ruby
134
- track extra: {campaign_id: 1}
171
+ class CouponMailer < ApplicationMailer
172
+ track open: true, click: true # use only/except to limit actions
173
+ end
135
174
  ```
136
175
 
137
- ## Customize
176
+ #### How It Works
138
177
 
139
- ### Tracking
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.
140
179
 
141
- Skip tracking of attributes by removing them from your model. You can safely remove:
180
+ For clicks, a redirect is added to links to track clicks in HTML emails.
142
181
 
143
- - to
144
- - mailer
145
- - subject
146
- - content
182
+ ```
183
+ https://chartkick.com
184
+ ```
147
185
 
148
- ### Configuration
186
+ becomes
187
+
188
+ ```
189
+ https://yoursite.com/ahoy/messages/rAnDoMtOkEn/click?url=https%3A%2F%2Fchartkick.com&signature=...
190
+ ```
149
191
 
150
- There are 3 places to set options. Here’s the order of precedence.
192
+ A signature is added to prevent [open redirects](https://www.owasp.org/index.php/Open_redirect).
151
193
 
152
- #### Action
194
+ Skip specific links with:
153
195
 
154
- ``` ruby
155
- class UserMailer < ApplicationMailer
156
- def welcome_email(user)
157
- # ...
158
- track user: user
159
- mail to: user.email
160
- end
161
- end
196
+ ```erb
197
+ <%= link_to "Go", some_url, data: {skip_click: true} %>
162
198
  ```
163
199
 
164
- #### Mailer
200
+ By default, unsubscribe links are excluded. To change this, use:
165
201
 
166
202
  ```ruby
167
- class UserMailer < ApplicationMailer
168
- track utm_campaign: "boom"
169
- end
203
+ AhoyEmail.default_options[:unsubscribe_links] = true
170
204
  ```
171
205
 
172
- #### Global
206
+ You can specify the domain to use with:
173
207
 
174
208
  ```ruby
175
- AhoyEmail.track open: false
209
+ AhoyEmail.default_options[:url_options] = {host: "mydomain.com"}
176
210
  ```
177
211
 
178
- ## Events
212
+ #### Events
179
213
 
180
- Subscribe to open and click events. Create an initializer `config/initializers/ahoy_email.rb` with:
214
+ Subscribe to open and click events by adding to the initializer:
181
215
 
182
216
  ```ruby
183
217
  class EmailSubscriber
184
218
  def open(event)
185
- # any code you want
219
+ # your code
186
220
  end
187
221
 
188
222
  def click(event)
189
- # any code you want
223
+ # your code
190
224
  end
191
225
  end
192
226
 
@@ -209,56 +243,91 @@ end
209
243
  AhoyEmail.subscribers << EmailSubscriber.new
210
244
  ```
211
245
 
212
- ## Reference
246
+ ## Data Protection
213
247
 
214
- You can use a `Proc` for any option.
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.
215
249
 
216
- ```ruby
217
- track utm_campaign: ->(message, mailer) { mailer.action_name + Time.now.year }
218
- ```
219
-
220
- Disable tracking for an email
250
+ Create `app/models/ahoy/message.rb` with:
221
251
 
222
252
  ```ruby
223
- track message: false
253
+ class Ahoy::Message < ApplicationRecord
254
+ self.table_name = "ahoy_messages"
255
+ belongs_to :user, polymorphic: true, optional: true
256
+
257
+ attr_encrypted :to, key: ...
258
+ blind_index :to, key: ...
259
+ end
224
260
  ```
225
261
 
226
- Or specific actions
262
+ ## Reference
263
+
264
+ Set global options
227
265
 
228
266
  ```ruby
229
- track only: [:welcome_email]
230
- track except: [:welcome_email]
267
+ AhoyEmail.default_options[:user] = -> { params[:admin] }
231
268
  ```
232
269
 
233
- Or by default
270
+ Use a different model
234
271
 
235
272
  ```ruby
236
- AhoyEmail.track message: false
273
+ AhoyEmail.message_model = -> { UserMessage }
237
274
  ```
238
275
 
239
- Customize domain
276
+ Or fully customize how messages are tracked
240
277
 
241
278
  ```ruby
242
- track url_options: {host: "mydomain.com"}
279
+ AhoyEmail.track_method = lambda do |data|
280
+ # your code
281
+ end
243
282
  ```
244
283
 
245
- By default, unsubscribe links are excluded from tracking. To change this, use:
284
+ ## Mongoid
285
+
286
+ If you prefer to use Mongoid instead of ActiveRecord, create `app/models/ahoy/message.rb` with:
246
287
 
247
288
  ```ruby
248
- track unsubscribe_links: true
249
- ```
289
+ class Ahoy::Message
290
+ include Mongoid::Document
250
291
 
251
- Use a different model
292
+ belongs_to :user, polymorphic: true, optional: true, index: true
252
293
 
253
- ```ruby
254
- AhoyEmail.message_model = -> { UserMessage }
294
+ field :to, type: String
295
+ field :mailer, type: String
296
+ field :subject, type: String
297
+ field :sent_at, type: Time
298
+ end
255
299
  ```
256
300
 
257
301
  ## Upgrading
258
302
 
259
- ### 0.2.3
303
+ ### 1.0
304
+
305
+ Breaking changes
260
306
 
261
- Optionally, you can store UTM parameters by adding `utm_source`, `utm_medium`, and `utm_campaign` columns to your message model.
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
262
331
 
263
332
  ## History
264
333
 
@@ -272,3 +341,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
272
341
  - Fix bugs and [submit pull requests](https://github.com/ankane/ahoy_email/pulls)
273
342
  - Write, clarify, or fix documentation
274
343
  - Suggest or add new features
344
+
345
+ To get started with development and testing:
346
+
347
+ ```sh
348
+ git clone https://github.com/ankane/ahoy_email.git
349
+ cd ahoy_email
350
+ bundle install
351
+ rake test
352
+ ```
@@ -1,30 +1,40 @@
1
1
  module Ahoy
2
- class MessagesController < ActionController::Base
3
- if respond_to? :before_action
4
- before_action :set_message
5
- else
6
- before_filter :set_message
7
- end
2
+ class MessagesController < ApplicationController
3
+ filters = _process_action_callbacks.map(&:filter) - AhoyEmail.preserve_callbacks
4
+ skip_before_action(*filters, raise: false)
5
+ skip_after_action(*filters, raise: false)
6
+ skip_around_action(*filters, raise: false)
7
+
8
+ before_action :set_message
8
9
 
9
10
  def open
10
11
  if @message && !@message.opened_at
11
12
  @message.opened_at = Time.now
12
13
  @message.save!
13
14
  end
15
+
14
16
  publish :open
17
+
15
18
  send_data Base64.decode64("R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="), type: "image/gif", disposition: "inline"
16
19
  end
17
20
 
18
21
  def click
19
22
  if @message && !@message.clicked_at
20
23
  @message.clicked_at = Time.now
21
- @message.opened_at ||= @message.clicked_at
24
+ @message.opened_at ||= @message.clicked_at if @message.respond_to?(:opened_at=)
22
25
  @message.save!
23
26
  end
27
+
28
+ user_signature = params[:signature].to_s
24
29
  url = params[:url].to_s
25
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), AhoyEmail.secret_token, url)
26
- publish :click, url: params[:url]
27
- if secure_compare(params[:signature].to_s, signature)
30
+
31
+ # TODO sign more than just url and transition to HMAC-SHA256
32
+ digest = "SHA1"
33
+ signature = OpenSSL::HMAC.hexdigest(digest, AhoyEmail.secret_token, url)
34
+
35
+ if ActiveSupport::SecurityUtils.secure_compare(user_signature, signature)
36
+ publish :click, url: params[:url]
37
+
28
38
  redirect_to url
29
39
  else
30
40
  redirect_to AhoyEmail.invalid_redirect_url || main_app.root_url
@@ -46,17 +56,5 @@ module Ahoy
46
56
  end
47
57
  end
48
58
  end
49
-
50
- # from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/message_verifier.rb
51
- # constant-time comparison algorithm to prevent timing attacks
52
- def secure_compare(a, b)
53
- return false unless a.bytesize == b.bytesize
54
-
55
- l = a.unpack "C#{a.bytesize}"
56
-
57
- res = 0
58
- b.each_byte { |byte| res |= byte ^ l.shift }
59
- res == 0
60
- end
61
59
  end
62
60
  end
@@ -2,6 +2,6 @@ module Ahoy
2
2
  class Message < ActiveRecord::Base
3
3
  self.table_name = "ahoy_messages"
4
4
 
5
- belongs_to :user, AhoyEmail.belongs_to.merge(polymorphic: true)
5
+ belongs_to :user, polymorphic: true, optional: true
6
6
  end
7
7
  end
data/config/routes.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  Rails.application.routes.draw do
2
- unless respond_to?(:has_named_route?) && has_named_route?("ahoy_email_engine")
3
- mount AhoyEmail::Engine => "/ahoy"
4
- end
2
+ mount AhoyEmail::Engine => "/ahoy" if AhoyEmail.api
5
3
  end
6
4
 
7
5
  AhoyEmail::Engine.routes.draw do
@@ -13,10 +13,10 @@ module AhoyEmail
13
13
  app.config
14
14
  end
15
15
 
16
- creds.respond_to?(:secret_key_base) ? creds.secret_key_base : creds.secret_token
16
+ token = creds.respond_to?(:secret_key_base) ? creds.secret_key_base : creds.secret_token
17
+ token ||= app.secret_key_base # should come first, but need to maintain backward compatibility
18
+ token
17
19
  end
18
-
19
- AhoyEmail.belongs_to = {optional: true} if Rails::VERSION::MAJOR >= 5
20
20
  end
21
21
  end
22
22
  end
@@ -1,33 +1,43 @@
1
1
  module AhoyEmail
2
2
  module Mailer
3
- def self.included(base)
4
- base.extend ClassMethods
5
- base.prepend InstanceMethods
6
- base.class_eval do
7
- attr_accessor :ahoy_options
8
- class_attribute :ahoy_options
9
- self.ahoy_options = {}
10
- end
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_writer :ahoy_options
7
+ after_action :save_ahoy_options
11
8
  end
12
9
 
13
- module ClassMethods
14
- def track(options = {})
15
- self.ahoy_options = ahoy_options.merge(message: true).merge(options)
10
+ class_methods do
11
+ def track(**options)
12
+ before_action(options.slice(:only, :except)) do
13
+ self.ahoy_options = ahoy_options.merge(message: true).merge(options.except(:only, :except))
14
+ end
16
15
  end
17
16
  end
18
17
 
19
- module InstanceMethods
20
- def track(options = {})
21
- self.ahoy_options = (ahoy_options || {}).merge(message: true).merge(options)
22
- end
18
+ def track(**options)
19
+ self.ahoy_options = ahoy_options.merge(message: true).merge(options)
20
+ end
21
+
22
+ def ahoy_options
23
+ @ahoy_options ||= AhoyEmail.default_options
24
+ end
25
+
26
+ def save_ahoy_options
27
+ Safely.safely do
28
+ # do message first for performance
29
+ message = ahoy_options[:message]
30
+ message = message.respond_to?(:call) ? instance_exec(&message) : message
23
31
 
24
- def mail(headers = {}, &block)
25
- # this mimics what original method does
26
- return message if @_mail_was_called && headers.blank? && !block
32
+ if message
33
+ options = {}
34
+ ahoy_options.except(:message).each do |k, v|
35
+ # execute options in mailer content
36
+ options[k] = v.respond_to?(:call) ? instance_exec(&v) : v
37
+ end
27
38
 
28
- message = super
29
- AhoyEmail::Processor.new(message, self).process
30
- message
39
+ AhoyEmail::Processor.new(self, options).perform
40
+ end
31
41
  end
32
42
  end
33
43
  end
@@ -0,0 +1,7 @@
1
+ module AhoyEmail
2
+ class Observer
3
+ def self.delivered_email(message)
4
+ AhoyEmail::Tracker.new(message).perform
5
+ end
6
+ end
7
+ end