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 +4 -4
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +47 -0
- data/LICENSE.txt +1 -1
- data/README.md +174 -96
- data/app/controllers/ahoy/messages_controller.rb +20 -22
- data/app/models/ahoy/message.rb +1 -1
- data/config/routes.rb +1 -3
- data/lib/ahoy_email/engine.rb +3 -3
- data/lib/ahoy_email/mailer.rb +31 -21
- data/lib/ahoy_email/observer.rb +7 -0
- data/lib/ahoy_email/processor.rb +52 -67
- data/lib/ahoy_email/tracker.rb +19 -0
- data/lib/ahoy_email/version.rb +1 -1
- data/lib/ahoy_email.rb +50 -22
- data/lib/generators/ahoy_email/install_generator.rb +3 -20
- data/lib/generators/ahoy_email/templates/install.rb.tt +11 -0
- metadata +15 -64
- data/.gitignore +0 -24
- data/.travis.yml +0 -16
- data/Gemfile +0 -6
- data/Rakefile +0 -9
- data/ahoy_email.gemspec +0 -35
- data/lib/ahoy_email/interceptor.rb +0 -9
- data/lib/generators/ahoy_email/templates/install.rb +0 -30
- data/test/gemfiles/actionmailer42.gemfile +0 -6
- data/test/gemfiles/actionmailer50.gemfile +0 -6
- data/test/gemfiles/actionmailer51.gemfile +0 -6
- data/test/internal/config/database.yml +0 -3
- data/test/internal/config/routes.rb +0 -3
- data/test/internal/db/schema.rb +0 -30
- data/test/mailer_test.rb +0 -153
- data/test/test_helper.rb +0 -16
data/lib/ahoy_email/processor.rb
CHANGED
@@ -1,103 +1,90 @@
|
|
1
1
|
module AhoyEmail
|
2
2
|
class Processor
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :mailer, :options
|
4
4
|
|
5
5
|
UTM_PARAMETERS = %w(utm_source utm_medium utm_term utm_content utm_campaign)
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@message = message
|
7
|
+
def initialize(mailer, options)
|
9
8
|
@mailer = mailer
|
10
|
-
|
11
|
-
|
12
|
-
def process
|
13
|
-
Safely.safely do
|
14
|
-
action_name = mailer.action_name.to_sym
|
15
|
-
if options[:message] && (!options[:only] || options[:only].include?(action_name)) && !options[:except].to_a.include?(action_name)
|
16
|
-
@ahoy_message = AhoyEmail.message_model.new
|
17
|
-
ahoy_message.token = generate_token
|
18
|
-
ahoy_message.to = Array(message.to).join(", ") if ahoy_message.respond_to?(:to=)
|
19
|
-
ahoy_message.user = options[:user]
|
9
|
+
@options = options
|
20
10
|
|
21
|
-
|
22
|
-
|
11
|
+
unknown_keywords = options.keys - AhoyEmail.default_options.keys
|
12
|
+
raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
|
13
|
+
end
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
def perform
|
16
|
+
track_open if options[:open]
|
17
|
+
track_links if options[:utm_params] || options[:click]
|
18
|
+
track_message
|
19
|
+
end
|
27
20
|
|
28
|
-
|
29
|
-
ahoy_message.send("#{k}=", options[k.to_sym]) if ahoy_message.respond_to?("#{k}=")
|
30
|
-
end
|
21
|
+
protected
|
31
22
|
|
32
|
-
|
23
|
+
def message
|
24
|
+
mailer.message
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
27
|
+
def token
|
28
|
+
@token ||= SecureRandom.urlsafe_base64(32).gsub(/[\-_]/, "").first(32)
|
38
29
|
end
|
39
30
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
31
|
+
def track_message
|
32
|
+
data = {
|
33
|
+
mailer: options[:mailer],
|
34
|
+
extra: options[:extra],
|
35
|
+
user: options[:user]
|
36
|
+
}
|
37
|
+
|
38
|
+
# legacy, remove in next major version
|
39
|
+
user = options[:user]
|
40
|
+
if user
|
41
|
+
data[:user_type] = user.model_name.name
|
42
|
+
id = user.id
|
43
|
+
data[:user_id] = id.is_a?(Integer) ? id : id.to_s
|
50
44
|
end
|
51
|
-
end
|
52
45
|
|
53
|
-
|
46
|
+
if options[:open] || options[:click]
|
47
|
+
data[:token] = token
|
48
|
+
end
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
if mailer.ahoy_options
|
59
|
-
options = options.except(:only, :except).merge(mailer.ahoy_options)
|
60
|
-
end
|
61
|
-
options.each do |k, v|
|
62
|
-
if v.respond_to?(:call)
|
63
|
-
options[k] = v.call(message, mailer)
|
64
|
-
end
|
50
|
+
if options[:utm_params]
|
51
|
+
UTM_PARAMETERS.map(&:to_sym).each do |k|
|
52
|
+
data[k] = options[k] if options[k]
|
65
53
|
end
|
66
|
-
options
|
67
54
|
end
|
68
|
-
end
|
69
55
|
|
70
|
-
|
71
|
-
SecureRandom.urlsafe_base64(32).gsub(/[\-_]/, "").first(32)
|
56
|
+
mailer.message.ahoy_data = data
|
72
57
|
end
|
73
58
|
|
74
59
|
def track_open
|
75
60
|
if html_part?
|
76
|
-
|
61
|
+
part = message.html_part || message
|
62
|
+
raw_source = part.body.raw_source
|
63
|
+
|
77
64
|
regex = /<\/body>/i
|
78
65
|
url =
|
79
66
|
url_for(
|
80
67
|
controller: "ahoy/messages",
|
81
68
|
action: "open",
|
82
|
-
id:
|
69
|
+
id: token,
|
83
70
|
format: "gif"
|
84
71
|
)
|
85
72
|
pixel = ActionController::Base.helpers.image_tag(url, size: "1x1", alt: "")
|
86
73
|
|
87
74
|
# try to add before body tag
|
88
75
|
if raw_source.match(regex)
|
89
|
-
raw_source.gsub
|
76
|
+
part.body = raw_source.gsub(regex, "#{pixel}\\0")
|
90
77
|
else
|
91
|
-
raw_source
|
78
|
+
part.body = raw_source + pixel
|
92
79
|
end
|
93
80
|
end
|
94
81
|
end
|
95
82
|
|
96
83
|
def track_links
|
97
84
|
if html_part?
|
98
|
-
|
85
|
+
part = message.html_part || message
|
99
86
|
|
100
|
-
doc = Nokogiri::HTML(body.raw_source)
|
87
|
+
doc = Nokogiri::HTML(part.body.raw_source)
|
101
88
|
doc.css("a[href]").each do |link|
|
102
89
|
uri = parse_uri(link["href"])
|
103
90
|
next unless trackable?(uri)
|
@@ -113,20 +100,22 @@ module AhoyEmail
|
|
113
100
|
end
|
114
101
|
|
115
102
|
if options[:click] && !skip_attribute?(link, "click")
|
116
|
-
|
103
|
+
raise "Secret token is empty" unless AhoyEmail.secret_token
|
104
|
+
|
105
|
+
# TODO sign more than just url and transition to HMAC-SHA256
|
106
|
+
signature = OpenSSL::HMAC.hexdigest("SHA1", AhoyEmail.secret_token, link["href"])
|
117
107
|
link["href"] =
|
118
108
|
url_for(
|
119
109
|
controller: "ahoy/messages",
|
120
110
|
action: "click",
|
121
|
-
id:
|
111
|
+
id: token,
|
122
112
|
url: link["href"],
|
123
113
|
signature: signature
|
124
114
|
)
|
125
115
|
end
|
126
116
|
end
|
127
117
|
|
128
|
-
|
129
|
-
body.raw_source.sub!(body.raw_source, doc.to_s)
|
118
|
+
part.body = doc.to_s
|
130
119
|
end
|
131
120
|
end
|
132
121
|
|
@@ -157,11 +146,7 @@ module AhoyEmail
|
|
157
146
|
# Return uri if valid, nil otherwise
|
158
147
|
def parse_uri(href)
|
159
148
|
# to_s prevent to return nil from this method
|
160
|
-
|
161
|
-
Addressable::URI.heuristic_parse(href.to_s) rescue nil
|
162
|
-
else
|
163
|
-
Addressable::URI.parse(href.to_s) rescue nil
|
164
|
-
end
|
149
|
+
Addressable::URI.heuristic_parse(href.to_s) rescue nil
|
165
150
|
end
|
166
151
|
|
167
152
|
def url_for(opt)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AhoyEmail
|
2
|
+
class Tracker
|
3
|
+
attr_reader :message
|
4
|
+
|
5
|
+
def initialize(message)
|
6
|
+
@message = message
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform
|
10
|
+
Safely.safely do
|
11
|
+
# perform_deliveries check still needed in observer
|
12
|
+
if message.perform_deliveries && message.ahoy_data
|
13
|
+
data = message.ahoy_data.merge(message: message)
|
14
|
+
message.ahoy_message = AhoyEmail.track_method.call(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/ahoy_email/version.rb
CHANGED
data/lib/ahoy_email.rb
CHANGED
@@ -1,47 +1,74 @@
|
|
1
|
+
# dependencies
|
1
2
|
require "active_support"
|
2
|
-
require "nokogiri"
|
3
3
|
require "addressable/uri"
|
4
|
+
require "nokogiri"
|
4
5
|
require "openssl"
|
5
6
|
require "safely/core"
|
7
|
+
|
8
|
+
# modules
|
6
9
|
require "ahoy_email/processor"
|
7
|
-
require "ahoy_email/
|
10
|
+
require "ahoy_email/tracker"
|
11
|
+
require "ahoy_email/observer"
|
8
12
|
require "ahoy_email/mailer"
|
9
|
-
require "ahoy_email/engine"
|
10
13
|
require "ahoy_email/version"
|
14
|
+
require "ahoy_email/engine" if defined?(Rails)
|
11
15
|
|
12
16
|
module AhoyEmail
|
13
|
-
mattr_accessor :secret_token, :
|
17
|
+
mattr_accessor :secret_token, :default_options, :subscribers, :invalid_redirect_url, :track_method, :api, :preserve_callbacks
|
18
|
+
mattr_writer :message_model
|
19
|
+
|
20
|
+
self.api = false
|
14
21
|
|
15
|
-
self.
|
22
|
+
self.default_options = {
|
16
23
|
message: true,
|
17
|
-
open:
|
18
|
-
click:
|
19
|
-
utm_params:
|
20
|
-
utm_source: ->
|
24
|
+
open: false,
|
25
|
+
click: false,
|
26
|
+
utm_params: false,
|
27
|
+
utm_source: -> { mailer_name },
|
21
28
|
utm_medium: "email",
|
22
29
|
utm_term: nil,
|
23
30
|
utm_content: nil,
|
24
|
-
utm_campaign: ->
|
25
|
-
user: ->(
|
26
|
-
mailer: ->
|
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) },
|
33
|
+
mailer: -> { "#{self.class.name}##{action_name}" },
|
27
34
|
url_options: {},
|
28
|
-
|
35
|
+
extra: {},
|
36
|
+
unsubscribe_links: false
|
29
37
|
}
|
30
38
|
|
31
|
-
self.
|
39
|
+
self.track_method = lambda do |data|
|
40
|
+
message = data[:message]
|
32
41
|
|
33
|
-
|
42
|
+
ahoy_message = AhoyEmail.message_model.new
|
43
|
+
ahoy_message.to = Array(message.to).join(", ") if ahoy_message.respond_to?(:to=)
|
44
|
+
ahoy_message.user = data[:user] if ahoy_message.respond_to?(:user=)
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
|
46
|
+
ahoy_message.mailer = data[:mailer] if ahoy_message.respond_to?(:mailer=)
|
47
|
+
ahoy_message.subject = message.subject if ahoy_message.respond_to?(:subject=)
|
48
|
+
ahoy_message.content = message.encoded if ahoy_message.respond_to?(:content=)
|
49
|
+
|
50
|
+
AhoyEmail::Processor::UTM_PARAMETERS.each do |k|
|
51
|
+
ahoy_message.send("#{k}=", data[k.to_sym]) if ahoy_message.respond_to?("#{k}=")
|
52
|
+
end
|
38
53
|
|
39
|
-
|
40
|
-
|
54
|
+
ahoy_message.token = data[:token] if ahoy_message.respond_to?(:token=)
|
55
|
+
|
56
|
+
ahoy_message.assign_attributes(data[:extra] || {})
|
57
|
+
|
58
|
+
ahoy_message.sent_at = Time.now
|
59
|
+
ahoy_message.save!
|
60
|
+
|
61
|
+
ahoy_message
|
41
62
|
end
|
42
63
|
|
64
|
+
self.subscribers = []
|
65
|
+
|
66
|
+
self.preserve_callbacks = []
|
67
|
+
|
68
|
+
self.message_model = -> { ::Ahoy::Message }
|
69
|
+
|
43
70
|
def self.message_model
|
44
|
-
model =
|
71
|
+
model = defined?(@@message_model) && @@message_model
|
45
72
|
model = model.call if model.respond_to?(:call)
|
46
73
|
model
|
47
74
|
end
|
@@ -49,5 +76,6 @@ end
|
|
49
76
|
|
50
77
|
ActiveSupport.on_load(:action_mailer) do
|
51
78
|
include AhoyEmail::Mailer
|
52
|
-
|
79
|
+
register_observer AhoyEmail::Observer
|
80
|
+
Mail::Message.send(:attr_accessor, :ahoy_data, :ahoy_message)
|
53
81
|
end
|
@@ -1,34 +1,17 @@
|
|
1
|
-
# taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
|
2
|
-
require "rails/generators"
|
3
|
-
require "rails/generators/migration"
|
4
|
-
require "active_record"
|
5
1
|
require "rails/generators/active_record"
|
6
2
|
|
7
3
|
module AhoyEmail
|
8
4
|
module Generators
|
9
5
|
class InstallGenerator < Rails::Generators::Base
|
10
|
-
include
|
11
|
-
|
12
|
-
source_root File.expand_path("../templates", __FILE__)
|
13
|
-
|
14
|
-
# Implement the required interface for Rails::Generators::Migration.
|
15
|
-
def self.next_migration_number(dirname) #:nodoc:
|
16
|
-
next_migration_number = current_migration_number(dirname) + 1
|
17
|
-
if ActiveRecord::Base.timestamped_migrations
|
18
|
-
[Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
|
19
|
-
else
|
20
|
-
"%.3d" % next_migration_number
|
21
|
-
end
|
22
|
-
end
|
6
|
+
include ActiveRecord::Generators::Migration
|
7
|
+
source_root File.join(__dir__, "templates")
|
23
8
|
|
24
9
|
def copy_migration
|
25
10
|
migration_template "install.rb", "db/migrate/create_ahoy_messages.rb", migration_version: migration_version
|
26
11
|
end
|
27
12
|
|
28
13
|
def migration_version
|
29
|
-
|
30
|
-
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
31
|
-
end
|
14
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
32
15
|
end
|
33
16
|
end
|
34
17
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :ahoy_messages do |t|
|
4
|
+
t.references :user, polymorphic: true
|
5
|
+
t.text :to
|
6
|
+
t.string :mailer
|
7
|
+
t.text :subject
|
8
|
+
t.timestamp :sent_at
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ahoy_email
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: railties
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: actionmailer
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activerecord
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
19
|
+
version: '5'
|
48
20
|
type: :runtime
|
49
21
|
prerelease: false
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
51
23
|
requirements:
|
52
24
|
- - ">="
|
53
25
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
26
|
+
version: '5'
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
28
|
name: addressable
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +109,7 @@ dependencies:
|
|
137
109
|
- !ruby/object:Gem::Version
|
138
110
|
version: '0'
|
139
111
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
112
|
+
name: activerecord
|
141
113
|
requirement: !ruby/object:Gem::Requirement
|
142
114
|
requirements:
|
143
115
|
- - ">="
|
@@ -151,7 +123,7 @@ dependencies:
|
|
151
123
|
- !ruby/object:Gem::Version
|
152
124
|
version: '0'
|
153
125
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
126
|
+
name: combustion
|
155
127
|
requirement: !ruby/object:Gem::Requirement
|
156
128
|
requirements:
|
157
129
|
- - ">="
|
@@ -179,39 +151,27 @@ dependencies:
|
|
179
151
|
- !ruby/object:Gem::Version
|
180
152
|
version: '0'
|
181
153
|
description:
|
182
|
-
email:
|
183
|
-
- andrew@chartkick.com
|
154
|
+
email: andrew@chartkick.com
|
184
155
|
executables: []
|
185
156
|
extensions: []
|
186
157
|
extra_rdoc_files: []
|
187
158
|
files:
|
188
|
-
- ".gitignore"
|
189
|
-
- ".travis.yml"
|
190
159
|
- CHANGELOG.md
|
191
|
-
-
|
160
|
+
- CONTRIBUTING.md
|
192
161
|
- LICENSE.txt
|
193
162
|
- README.md
|
194
|
-
- Rakefile
|
195
|
-
- ahoy_email.gemspec
|
196
163
|
- app/controllers/ahoy/messages_controller.rb
|
197
164
|
- app/models/ahoy/message.rb
|
198
165
|
- config/routes.rb
|
199
166
|
- lib/ahoy_email.rb
|
200
167
|
- lib/ahoy_email/engine.rb
|
201
|
-
- lib/ahoy_email/interceptor.rb
|
202
168
|
- lib/ahoy_email/mailer.rb
|
169
|
+
- lib/ahoy_email/observer.rb
|
203
170
|
- lib/ahoy_email/processor.rb
|
171
|
+
- lib/ahoy_email/tracker.rb
|
204
172
|
- lib/ahoy_email/version.rb
|
205
173
|
- lib/generators/ahoy_email/install_generator.rb
|
206
|
-
- lib/generators/ahoy_email/templates/install.rb
|
207
|
-
- test/gemfiles/actionmailer42.gemfile
|
208
|
-
- test/gemfiles/actionmailer50.gemfile
|
209
|
-
- test/gemfiles/actionmailer51.gemfile
|
210
|
-
- test/internal/config/database.yml
|
211
|
-
- test/internal/config/routes.rb
|
212
|
-
- test/internal/db/schema.rb
|
213
|
-
- test/mailer_test.rb
|
214
|
-
- test/test_helper.rb
|
174
|
+
- lib/generators/ahoy_email/templates/install.rb.tt
|
215
175
|
homepage: https://github.com/ankane/ahoy_email
|
216
176
|
licenses:
|
217
177
|
- MIT
|
@@ -224,24 +184,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
224
184
|
requirements:
|
225
185
|
- - ">="
|
226
186
|
- !ruby/object:Gem::Version
|
227
|
-
version: 2.
|
187
|
+
version: '2.4'
|
228
188
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
189
|
requirements:
|
230
190
|
- - ">="
|
231
191
|
- !ruby/object:Gem::Version
|
232
192
|
version: '0'
|
233
193
|
requirements: []
|
234
|
-
|
235
|
-
rubygems_version: 2.7.6
|
194
|
+
rubygems_version: 3.0.4
|
236
195
|
signing_key:
|
237
196
|
specification_version: 4
|
238
|
-
summary:
|
239
|
-
test_files:
|
240
|
-
- test/gemfiles/actionmailer42.gemfile
|
241
|
-
- test/gemfiles/actionmailer50.gemfile
|
242
|
-
- test/gemfiles/actionmailer51.gemfile
|
243
|
-
- test/internal/config/database.yml
|
244
|
-
- test/internal/config/routes.rb
|
245
|
-
- test/internal/db/schema.rb
|
246
|
-
- test/mailer_test.rb
|
247
|
-
- test/test_helper.rb
|
197
|
+
summary: Email analytics for Rails
|
198
|
+
test_files: []
|
data/.gitignore
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
*.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
18
|
-
*.bundle
|
19
|
-
*.so
|
20
|
-
*.o
|
21
|
-
*.a
|
22
|
-
mkmf.log
|
23
|
-
*.log
|
24
|
-
*.sqlite
|
data/.travis.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.4.2
|
4
|
-
sudo: false
|
5
|
-
script: bundle exec rake test
|
6
|
-
before_script:
|
7
|
-
- gem install bundler
|
8
|
-
notifications:
|
9
|
-
email:
|
10
|
-
on_success: never
|
11
|
-
on_failure: change
|
12
|
-
gemfile:
|
13
|
-
- Gemfile
|
14
|
-
- test/gemfiles/actionmailer51.gemfile
|
15
|
-
- test/gemfiles/actionmailer50.gemfile
|
16
|
-
- test/gemfiles/actionmailer42.gemfile
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/ahoy_email.gemspec
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require "ahoy_email/version"
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "ahoy_email"
|
8
|
-
spec.version = AhoyEmail::VERSION
|
9
|
-
spec.authors = ["Andrew Kane"]
|
10
|
-
spec.email = ["andrew@chartkick.com"]
|
11
|
-
spec.summary = "Simple, powerful email tracking for Rails"
|
12
|
-
spec.homepage = "https://github.com/ankane/ahoy_email"
|
13
|
-
spec.license = "MIT"
|
14
|
-
|
15
|
-
spec.files = `git ls-files -z`.split("\x0")
|
16
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
-
spec.require_paths = ["lib"]
|
19
|
-
|
20
|
-
spec.required_ruby_version = ">= 2.2.0"
|
21
|
-
|
22
|
-
spec.add_runtime_dependency "railties"
|
23
|
-
spec.add_runtime_dependency "actionmailer"
|
24
|
-
spec.add_runtime_dependency "activerecord"
|
25
|
-
spec.add_runtime_dependency "addressable", ">= 2.3.2"
|
26
|
-
spec.add_runtime_dependency "nokogiri"
|
27
|
-
spec.add_runtime_dependency "safely_block", ">= 0.1.1"
|
28
|
-
|
29
|
-
spec.add_development_dependency "bundler"
|
30
|
-
spec.add_development_dependency "rake"
|
31
|
-
spec.add_development_dependency "minitest"
|
32
|
-
spec.add_development_dependency "combustion"
|
33
|
-
spec.add_development_dependency "rails"
|
34
|
-
spec.add_development_dependency "sqlite3"
|
35
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
|
2
|
-
def change
|
3
|
-
create_table :ahoy_messages do |t|
|
4
|
-
t.string :token
|
5
|
-
|
6
|
-
# user
|
7
|
-
t.text :to
|
8
|
-
t.references :user, polymorphic: true
|
9
|
-
|
10
|
-
# optional - feel free to remove
|
11
|
-
t.string :mailer
|
12
|
-
t.text :subject
|
13
|
-
# t.text :content
|
14
|
-
|
15
|
-
# optional
|
16
|
-
# t.string :utm_source
|
17
|
-
# t.string :utm_medium
|
18
|
-
# t.string :utm_term
|
19
|
-
# t.string :utm_content
|
20
|
-
# t.string :utm_campaign
|
21
|
-
|
22
|
-
# timestamps
|
23
|
-
t.timestamp :sent_at
|
24
|
-
t.timestamp :opened_at
|
25
|
-
t.timestamp :clicked_at
|
26
|
-
end
|
27
|
-
|
28
|
-
add_index :ahoy_messages, [:token]
|
29
|
-
end
|
30
|
-
end
|