ahoy_email 0.5.2 → 1.1.0
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 +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
|