mailkick 0.3.0 → 0.4.3
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 +42 -17
- data/LICENSE.txt +1 -1
- data/README.md +64 -16
- data/app/controllers/mailkick/subscriptions_controller.rb +1 -5
- data/app/models/mailkick/opt_out.rb +1 -1
- data/lib/generators/mailkick/install_generator.rb +3 -20
- data/lib/generators/mailkick/templates/{install.rb → install.rb.tt} +0 -0
- data/lib/mailkick.rb +30 -13
- data/lib/mailkick/engine.rb +1 -5
- data/lib/mailkick/model.rb +10 -9
- data/lib/mailkick/service/aws_ses.rb +47 -0
- data/lib/mailkick/service/postmark.rb +41 -0
- data/lib/mailkick/service/sendgrid.rb +4 -1
- data/lib/mailkick/service/sendgrid_v2.rb +52 -0
- data/{app/helpers → lib}/mailkick/url_helper.rb +4 -3
- data/lib/mailkick/version.rb +1 -1
- metadata +32 -44
- data/.gitignore +0 -24
- data/.travis.yml +0 -16
- data/Gemfile +0 -6
- data/Rakefile +0 -9
- data/mailkick.gemspec +0 -32
- data/test/gemfiles/actionmailer42.gemfile +0 -6
- data/test/gemfiles/actionmailer50.gemfile +0 -6
- data/test/gemfiles/actionmailer51.gemfile +0 -6
- data/test/internal/app/mailers/user_mailer.rb +0 -7
- data/test/internal/app/models/user.rb +0 -3
- data/test/internal/app/views/user_mailer/welcome.html.erb +0 -1
- data/test/internal/app/views/user_mailer/welcome.text.erb +0 -1
- data/test/internal/config/database.yml +0 -3
- data/test/internal/db/schema.rb +0 -16
- data/test/mailkick_test.rb +0 -29
- data/test/test_helper.rb +0 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a3e1a782d63a1ad223871a87aab2875c73c1a7860f614801184d005113d4d82
|
|
4
|
+
data.tar.gz: 802fdb1f89e3ca6c25761bb61fd085b1936336ea5fd6bc6a020a1b79a21859c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e93ee8b3bcf05fa1536141e2f9ef639e30efd236eb9d280bb88bc7e234f6a6aa9a246eb91bd6aee188c74226e11cf0cdcb67e636ffafeb76f525f89096ec5eda
|
|
7
|
+
data.tar.gz: 23441f577b0f294a46f47e61cc66c994a319d1e3d89ff310bd26d997c5b6bdbd2270318fda74de96e588f7da58691c63d3c188853be382a41a3608803034435d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,73 +1,98 @@
|
|
|
1
|
-
## 0.3
|
|
1
|
+
## 0.4.3 (2020-11-01)
|
|
2
|
+
|
|
3
|
+
- Added support for AWS SES
|
|
4
|
+
|
|
5
|
+
## 0.4.2 (2020-04-06)
|
|
6
|
+
|
|
7
|
+
- Added support for official SendGrid gem
|
|
8
|
+
- Fixed deprecation warning
|
|
9
|
+
|
|
10
|
+
## 0.4.1 (2019-10-27)
|
|
11
|
+
|
|
12
|
+
- Added Postmark support
|
|
13
|
+
|
|
14
|
+
## 0.4.0 (2019-07-15)
|
|
15
|
+
|
|
16
|
+
- Fixed error with model methods and `email_key` option
|
|
17
|
+
- Fixed bug with `opted_out` scope
|
|
18
|
+
- Dropped support for Action Mailer 4.2
|
|
19
|
+
|
|
20
|
+
## 0.3.1 (2018-04-21)
|
|
21
|
+
|
|
22
|
+
- Fixed `Secret should not be nil` error in Rails 5.2
|
|
23
|
+
- Gracefully handle missing email
|
|
24
|
+
- Added `user` option to `mailkick_unsubscribe_url`
|
|
25
|
+
|
|
26
|
+
## 0.3.0 (2018-04-20)
|
|
2
27
|
|
|
3
28
|
- Improved performance
|
|
4
29
|
- Fixed `Subscription not found` for Rails 5.2
|
|
5
30
|
- Use `references` in migration
|
|
6
31
|
- Use `smtp_settings[:domain]` for Mailgun
|
|
7
|
-
- Dropped support for
|
|
32
|
+
- Dropped support for Action Mailer < 4.2
|
|
8
33
|
|
|
9
|
-
## 0.2.1
|
|
34
|
+
## 0.2.1 (2017-10-30)
|
|
10
35
|
|
|
11
36
|
- Fixed errors with Rails 5+
|
|
12
37
|
- Fixed errors with the latest version of Gibbon
|
|
13
38
|
|
|
14
|
-
## 0.2.0
|
|
39
|
+
## 0.2.0 (2017-05-01)
|
|
15
40
|
|
|
16
41
|
- Added support for Rails 5.1
|
|
17
42
|
|
|
18
|
-
## 0.1.6
|
|
43
|
+
## 0.1.6 (2017-01-10)
|
|
19
44
|
|
|
20
45
|
- Fixed error with frozen strings
|
|
21
46
|
|
|
22
|
-
## 0.1.5
|
|
47
|
+
## 0.1.5 (2016-12-06)
|
|
23
48
|
|
|
24
49
|
- Use `safely`
|
|
25
50
|
- Only discover services if not manually set
|
|
26
51
|
- Added `mount` option
|
|
27
52
|
|
|
28
|
-
## 0.1.4
|
|
53
|
+
## 0.1.4 (2016-02-20)
|
|
29
54
|
|
|
30
55
|
- Use `Module#prepend` instead of `alias_method_chain`
|
|
31
56
|
|
|
32
|
-
## 0.1.3
|
|
57
|
+
## 0.1.3 (2015-06-29)
|
|
33
58
|
|
|
34
59
|
- Fixed issue with double escaping tokens
|
|
35
60
|
|
|
36
|
-
## 0.1.2
|
|
61
|
+
## 0.1.2 (2015-06-07)
|
|
37
62
|
|
|
38
63
|
- Added support for Mailgun
|
|
39
64
|
|
|
40
|
-
## 0.1.1
|
|
65
|
+
## 0.1.1 (2015-01-31)
|
|
41
66
|
|
|
42
67
|
- Fixed tokens with `+` in them
|
|
43
68
|
|
|
44
|
-
## 0.1.0
|
|
69
|
+
## 0.1.0 (2014-08-31)
|
|
45
70
|
|
|
46
71
|
- Fixed secret token for Rails 4.1
|
|
47
72
|
|
|
48
|
-
## 0.0.6
|
|
73
|
+
## 0.0.6 (2014-05-09)
|
|
49
74
|
|
|
50
75
|
- Rails 3 fix
|
|
51
76
|
|
|
52
|
-
## 0.0.5
|
|
77
|
+
## 0.0.5 (2014-05-05)
|
|
53
78
|
|
|
54
79
|
- Fixed bug with subscriptions page
|
|
55
80
|
|
|
56
|
-
## 0.0.4
|
|
81
|
+
## 0.0.4 (2014-05-05)
|
|
57
82
|
|
|
58
83
|
- Added `email_key` option to `mailkick_user`
|
|
59
84
|
|
|
60
|
-
## 0.0.3
|
|
85
|
+
## 0.0.3 (2014-05-04)
|
|
61
86
|
|
|
62
87
|
- Added support for multiple lists
|
|
63
88
|
- Changed `mailkick_user` method names - sorry early adopters :(
|
|
64
89
|
|
|
65
|
-
## 0.0.2
|
|
90
|
+
## 0.0.2 (2014-05-04)
|
|
66
91
|
|
|
67
92
|
- Added Mailchimp service
|
|
68
93
|
- Fixed Mandrill service
|
|
69
94
|
- Added `uniq` to `subscribed` scope
|
|
70
95
|
|
|
71
|
-
## 0.0.1
|
|
96
|
+
## 0.0.1 (2014-05-04)
|
|
72
97
|
|
|
73
98
|
- First release
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mailkick
|
|
2
2
|
|
|
3
|
-
Email
|
|
3
|
+
Email unsubscribes for Rails
|
|
4
4
|
|
|
5
5
|
- Add one-click unsubscribe links to your emails
|
|
6
6
|
- Fetch bounces and spam reports from your email service
|
|
@@ -89,43 +89,76 @@ Fetch bounces, spam reports, and unsubscribes from your email service.
|
|
|
89
89
|
Mailkick.fetch_opt_outs
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
The following services are supported:
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
- [AWS SES](#aws-ses)
|
|
95
|
+
- [Mailchimp](#mailchimp)
|
|
96
|
+
- [Mailgun](#mailgun)
|
|
97
|
+
- [Mandrill](#mandrill)
|
|
98
|
+
- [Postmark](#postmark)
|
|
99
|
+
- [SendGrid](#sendgrid)
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
gem 'sendgrid_toolkit'
|
|
98
|
-
```
|
|
101
|
+
Will gladly accept pull requests for others.
|
|
99
102
|
|
|
100
|
-
|
|
103
|
+
#### AWS SES
|
|
101
104
|
|
|
102
|
-
|
|
105
|
+
Add the gem
|
|
103
106
|
|
|
104
107
|
```ruby
|
|
105
|
-
gem '
|
|
108
|
+
gem 'aws-sdk-sesv2'
|
|
106
109
|
```
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
And [configure your AWS credentials](https://github.com/aws/aws-sdk-ruby#configuration). Requires `ses:ListSuppressedDestinations` permission.
|
|
109
112
|
|
|
110
113
|
#### Mailchimp
|
|
111
114
|
|
|
115
|
+
Add the gem
|
|
116
|
+
|
|
112
117
|
```ruby
|
|
113
118
|
gem 'gibbon', '>= 2'
|
|
114
119
|
```
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
And set `ENV["MAILCHIMP_API_KEY"]` and `ENV["MAILCHIMP_LIST_ID"]`.
|
|
117
122
|
|
|
118
123
|
#### Mailgun
|
|
119
124
|
|
|
125
|
+
Add the gem
|
|
126
|
+
|
|
120
127
|
```ruby
|
|
121
128
|
gem 'mailgun-ruby'
|
|
122
129
|
```
|
|
123
130
|
|
|
124
|
-
|
|
131
|
+
And set `ENV["MAILGUN_API_KEY"]`.
|
|
125
132
|
|
|
126
|
-
####
|
|
133
|
+
#### Mandrill
|
|
134
|
+
|
|
135
|
+
Add the gem
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
gem 'mandrill-api'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
And set `ENV["MANDRILL_APIKEY"]`.
|
|
127
142
|
|
|
128
|
-
|
|
143
|
+
#### Postmark
|
|
144
|
+
|
|
145
|
+
Add the gem
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
gem 'postmark'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
And set `ENV["POSTMARK_API_KEY"]`.
|
|
152
|
+
|
|
153
|
+
#### SendGrid
|
|
154
|
+
|
|
155
|
+
Add the gem
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
gem 'sendgrid-ruby'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
And set `ENV["SENDGRID_API_KEY"]`. The API key requires only the `Suppressions` permission.
|
|
129
162
|
|
|
130
163
|
### Advanced
|
|
131
164
|
|
|
@@ -133,8 +166,8 @@ For more control over services, set them by hand.
|
|
|
133
166
|
|
|
134
167
|
```ruby
|
|
135
168
|
Mailkick.services = [
|
|
136
|
-
Mailkick::Service::
|
|
137
|
-
Mailkick::Service::
|
|
169
|
+
Mailkick::Service::SendGridV2.new(api_key: "API_KEY"),
|
|
170
|
+
Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID")
|
|
138
171
|
]
|
|
139
172
|
```
|
|
140
173
|
|
|
@@ -203,6 +236,12 @@ Resubscribe
|
|
|
203
236
|
user.opt_in
|
|
204
237
|
```
|
|
205
238
|
|
|
239
|
+
Access the opt-out model directly
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
Mailkick::OptOut.all
|
|
243
|
+
```
|
|
244
|
+
|
|
206
245
|
## History
|
|
207
246
|
|
|
208
247
|
View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
|
|
@@ -215,3 +254,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
|
|
|
215
254
|
- Fix bugs and [submit pull requests](https://github.com/ankane/mailkick/pulls)
|
|
216
255
|
- Write, clarify, or fix documentation
|
|
217
256
|
- Suggest or add new features
|
|
257
|
+
|
|
258
|
+
To get started with development and testing:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
git clone https://github.com/ankane/mailkick.git
|
|
262
|
+
cd mailkick
|
|
263
|
+
bundle install
|
|
264
|
+
bundle exec rake test
|
|
265
|
+
```
|
|
@@ -31,11 +31,7 @@ module Mailkick
|
|
|
31
31
|
list: @list
|
|
32
32
|
}
|
|
33
33
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
|
34
|
-
|
|
35
|
-
render plain: "Subscription not found", status: :bad_request
|
|
36
|
-
else
|
|
37
|
-
render text: "Subscription not found", status: :bad_request
|
|
38
|
-
end
|
|
34
|
+
render plain: "Subscription not found", status: :bad_request
|
|
39
35
|
end
|
|
40
36
|
|
|
41
37
|
def opted_out?
|
|
@@ -2,6 +2,6 @@ module Mailkick
|
|
|
2
2
|
class OptOut < ActiveRecord::Base
|
|
3
3
|
self.table_name = "mailkick_opt_outs"
|
|
4
4
|
|
|
5
|
-
belongs_to :user,
|
|
5
|
+
belongs_to :user, polymorphic: true, optional: true
|
|
6
6
|
end
|
|
7
7
|
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 Mailkick
|
|
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/install_mailkick.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
|
|
File without changes
|
data/lib/mailkick.rb
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
# dependencies
|
|
2
2
|
require "active_support"
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
# stdlib
|
|
5
|
+
require "set"
|
|
6
|
+
|
|
7
|
+
# modules
|
|
5
8
|
require "mailkick/model"
|
|
6
9
|
require "mailkick/service"
|
|
10
|
+
require "mailkick/service/aws_ses"
|
|
7
11
|
require "mailkick/service/mailchimp"
|
|
8
12
|
require "mailkick/service/mailgun"
|
|
9
13
|
require "mailkick/service/mandrill"
|
|
10
14
|
require "mailkick/service/sendgrid"
|
|
15
|
+
require "mailkick/service/sendgrid_v2"
|
|
16
|
+
require "mailkick/service/postmark"
|
|
17
|
+
require "mailkick/url_helper"
|
|
11
18
|
require "mailkick/version"
|
|
12
19
|
|
|
20
|
+
# integrations
|
|
21
|
+
require "mailkick/engine" if defined?(Rails)
|
|
22
|
+
|
|
13
23
|
module Mailkick
|
|
14
24
|
mattr_accessor :services, :user_method, :secret_token, :mount
|
|
15
25
|
self.services = []
|
|
@@ -56,17 +66,16 @@ module Mailkick
|
|
|
56
66
|
def self.opt_outs(options = {})
|
|
57
67
|
relation = Mailkick::OptOut.where(active: true)
|
|
58
68
|
|
|
59
|
-
|
|
60
|
-
binds = []
|
|
69
|
+
contact_relation = Mailkick::OptOut.none
|
|
61
70
|
if (email = options[:email])
|
|
62
|
-
|
|
63
|
-
binds << email
|
|
71
|
+
contact_relation = contact_relation.or(Mailkick::OptOut.where(email: email))
|
|
64
72
|
end
|
|
65
73
|
if (user = options[:user])
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
contact_relation = contact_relation.or(
|
|
75
|
+
Mailkick::OptOut.where("user_id = ? AND user_type = ?", user.id, user.class.name)
|
|
76
|
+
)
|
|
68
77
|
end
|
|
69
|
-
relation = relation.
|
|
78
|
+
relation = relation.merge(contact_relation) if email || user
|
|
70
79
|
|
|
71
80
|
relation =
|
|
72
81
|
if options[:list]
|
|
@@ -78,25 +87,33 @@ module Mailkick
|
|
|
78
87
|
relation
|
|
79
88
|
end
|
|
80
89
|
|
|
90
|
+
# TODO use keyword arguments
|
|
81
91
|
def self.opted_out_emails(options = {})
|
|
82
|
-
Set.new(opt_outs(options).where(
|
|
92
|
+
Set.new(opt_outs(options).where.not(email: nil).distinct.pluck(:email))
|
|
83
93
|
end
|
|
84
94
|
|
|
95
|
+
# TODO use keyword arguments
|
|
85
96
|
# does not take into account emails
|
|
86
97
|
def self.opted_out_users(options = {})
|
|
87
|
-
Set.new(opt_outs(options).where(
|
|
98
|
+
Set.new(opt_outs(options).where.not(user_id: nil).map(&:user))
|
|
88
99
|
end
|
|
89
100
|
|
|
90
101
|
def self.message_verifier
|
|
91
102
|
@message_verifier ||= ActiveSupport::MessageVerifier.new(Mailkick.secret_token)
|
|
92
103
|
end
|
|
93
104
|
|
|
94
|
-
def self.generate_token(email, list: nil)
|
|
95
|
-
|
|
105
|
+
def self.generate_token(email, user: nil, list: nil)
|
|
106
|
+
raise ArgumentError, "Missing email" unless email
|
|
107
|
+
|
|
108
|
+
user ||= Mailkick.user_method.call(email) if Mailkick.user_method
|
|
96
109
|
message_verifier.generate([email, user.try(:id), user.try(:class).try(:name), list])
|
|
97
110
|
end
|
|
98
111
|
end
|
|
99
112
|
|
|
113
|
+
ActiveSupport.on_load :action_mailer do
|
|
114
|
+
helper Mailkick::UrlHelper
|
|
115
|
+
end
|
|
116
|
+
|
|
100
117
|
ActiveSupport.on_load(:active_record) do
|
|
101
118
|
extend Mailkick::Model
|
|
102
119
|
end
|
data/lib/mailkick/engine.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Mailkick
|
|
|
7
7
|
|
|
8
8
|
Mailkick.secret_token ||= begin
|
|
9
9
|
creds =
|
|
10
|
-
if app.respond_to?(:credentials)
|
|
10
|
+
if app.respond_to?(:credentials) && app.credentials.secret_key_base
|
|
11
11
|
app.credentials
|
|
12
12
|
elsif app.respond_to?(:secrets)
|
|
13
13
|
app.secrets
|
|
@@ -17,10 +17,6 @@ module Mailkick
|
|
|
17
17
|
|
|
18
18
|
creds.respond_to?(:secret_key_base) ? creds.secret_key_base : creds.secret_token
|
|
19
19
|
end
|
|
20
|
-
|
|
21
|
-
ActiveSupport.on_load :action_mailer do
|
|
22
|
-
helper Mailkick::UrlHelper
|
|
23
|
-
end
|
|
24
20
|
end
|
|
25
21
|
end
|
|
26
22
|
end
|
data/lib/mailkick/model.rb
CHANGED
|
@@ -3,8 +3,8 @@ module Mailkick
|
|
|
3
3
|
def mailkick_user(opts = {})
|
|
4
4
|
email_key = opts[:email_key] || :email
|
|
5
5
|
class_eval do
|
|
6
|
-
scope :opted_out,
|
|
7
|
-
binds = [
|
|
6
|
+
scope :opted_out, lambda { |options = {}|
|
|
7
|
+
binds = [name, true]
|
|
8
8
|
if options[:list]
|
|
9
9
|
query = "(mailkick_opt_outs.list IS NULL OR mailkick_opt_outs.list = ?)"
|
|
10
10
|
binds << options[:list]
|
|
@@ -13,20 +13,21 @@ module Mailkick
|
|
|
13
13
|
end
|
|
14
14
|
where("#{options[:not] ? 'NOT ' : ''}EXISTS(SELECT * FROM mailkick_opt_outs WHERE (#{table_name}.#{email_key} = mailkick_opt_outs.email OR (#{table_name}.#{primary_key} = mailkick_opt_outs.user_id AND mailkick_opt_outs.user_type = ?)) AND mailkick_opt_outs.active = ? AND #{query})", *binds)
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
scope :not_opted_out, lambda { |options = {}|
|
|
17
18
|
opted_out(options.merge(not: true))
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
Mailkick.opted_out?({email:
|
|
21
|
+
define_method :opted_out? do |options = {}|
|
|
22
|
+
Mailkick.opted_out?({email: send(email_key), user: self}.merge(options))
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
Mailkick.opt_out({email:
|
|
25
|
+
define_method :opt_out do |options = {}|
|
|
26
|
+
Mailkick.opt_out({email: send(email_key), user: self}.merge(options))
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
Mailkick.opt_in({email:
|
|
29
|
+
define_method :opt_in do |options = {}|
|
|
30
|
+
Mailkick.opt_in({email: send(email_key), user: self}.merge(options))
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SESV2/Client.html
|
|
2
|
+
|
|
3
|
+
module Mailkick
|
|
4
|
+
class Service
|
|
5
|
+
class AwsSes < Mailkick::Service
|
|
6
|
+
REASONS_MAP = {
|
|
7
|
+
"BOUNCE" => "bounce",
|
|
8
|
+
"COMPLAINT" => "spam"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
def initialize(options = {})
|
|
12
|
+
@options = options
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def opt_outs
|
|
16
|
+
response = client.list_suppressed_destinations({
|
|
17
|
+
reasons: ["BOUNCE", "COMPLAINT"],
|
|
18
|
+
# TODO make configurable
|
|
19
|
+
start_date: Time.now - (86400 * 365),
|
|
20
|
+
end_date: Time.now
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
opt_outs = []
|
|
24
|
+
response.each do |page|
|
|
25
|
+
page.suppressed_destination_summaries.each do |record|
|
|
26
|
+
opt_outs << {
|
|
27
|
+
email: record.email_address,
|
|
28
|
+
time: record.last_update_time,
|
|
29
|
+
reason: REASONS_MAP[record.reason]
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
opt_outs
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.discoverable?
|
|
37
|
+
!!defined?(::Aws::SESV2::Client)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def client
|
|
43
|
+
@client ||= ::Aws::SESV2::Client.new
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# https://github.com/wildbit/postmark-gem
|
|
2
|
+
|
|
3
|
+
module Mailkick
|
|
4
|
+
class Service
|
|
5
|
+
class Postmark < Mailkick::Service
|
|
6
|
+
REASONS_MAP = {
|
|
7
|
+
"SpamNotification" => "spam",
|
|
8
|
+
"SpamComplaint" => "spam",
|
|
9
|
+
"Unsubscribe" => "unsubscribe",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def initialize(options = {})
|
|
13
|
+
@client = ::Postmark::ApiClient.new(options[:api_key] || ENV["POSTMARK_API_KEY"])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def opt_outs
|
|
17
|
+
bounces
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def bounces
|
|
21
|
+
fetch(@client.bounces)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.discoverable?
|
|
25
|
+
!!(defined?(::Postmark) && ENV["POSTMARK_API_KEY"])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
protected
|
|
29
|
+
|
|
30
|
+
def fetch(response)
|
|
31
|
+
response.map do |record|
|
|
32
|
+
{
|
|
33
|
+
email: record[:email],
|
|
34
|
+
time: ActiveSupport::TimeZone["UTC"].parse(record[:bounced_at]),
|
|
35
|
+
reason: REASONS_MAP.fetch(record[:type], "bounce")
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Mailkick
|
|
4
4
|
class Service
|
|
5
|
-
class
|
|
5
|
+
class SendGrid < Mailkick::Service
|
|
6
6
|
def initialize(options = {})
|
|
7
7
|
@api_user = options[:api_user] || ENV["SENDGRID_USERNAME"]
|
|
8
8
|
@api_key = options[:api_key] || ENV["SENDGRID_PASSWORD"]
|
|
@@ -41,5 +41,8 @@ module Mailkick
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
# backwards compatibility
|
|
46
|
+
Sendgrid = SendGrid
|
|
44
47
|
end
|
|
45
48
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# https://github.com/sendgrid/sendgrid-ruby
|
|
2
|
+
|
|
3
|
+
module Mailkick
|
|
4
|
+
class Service
|
|
5
|
+
class SendGridV2 < Mailkick::Service
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@api_key = options[:api_key] || ENV["SENDGRID_API_KEY"]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def opt_outs
|
|
11
|
+
unsubscribes + spam_reports + bounces
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def unsubscribes
|
|
15
|
+
fetch(client.suppression.unsubscribes, "unsubscribe")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def spam_reports
|
|
19
|
+
fetch(client.suppression.spam_reports, "spam")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bounces
|
|
23
|
+
fetch(client.suppression.bounces, "bounce")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.discoverable?
|
|
27
|
+
!!(defined?(::SendGrid::API) && ENV["SENDGRID_API_KEY"])
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
protected
|
|
31
|
+
|
|
32
|
+
def client
|
|
33
|
+
@client ||= ::SendGrid::API.new(api_key: @api_key).client
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def fetch(query, reason)
|
|
37
|
+
# TODO paginate
|
|
38
|
+
response = query.get
|
|
39
|
+
|
|
40
|
+
raise "Bad status code: #{response.status_code}" if response.status_code.to_i != 200
|
|
41
|
+
|
|
42
|
+
response.parsed_body.map do |record|
|
|
43
|
+
{
|
|
44
|
+
email: record[:email],
|
|
45
|
+
time: Time.at(record[:created]),
|
|
46
|
+
reason: reason
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module Mailkick
|
|
2
2
|
module UrlHelper
|
|
3
|
-
def mailkick_unsubscribe_url(email: nil, list: nil, **options)
|
|
4
|
-
email ||= controller.message.to.first
|
|
3
|
+
def mailkick_unsubscribe_url(email: nil, user: nil, list: nil, **options)
|
|
4
|
+
email ||= controller.try(:message).try(:to).try(:first)
|
|
5
|
+
|
|
5
6
|
Mailkick::Engine.routes.url_helpers.url_for(
|
|
6
7
|
(ActionMailer::Base.default_url_options || {}).merge(options).merge(
|
|
7
8
|
controller: "mailkick/subscriptions",
|
|
8
9
|
action: "unsubscribe",
|
|
9
|
-
id: Mailkick.generate_token(email, list: list)
|
|
10
|
+
id: Mailkick.generate_token(email, user: user, list: list)
|
|
10
11
|
)
|
|
11
12
|
)
|
|
12
13
|
end
|
data/lib/mailkick/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mailkick
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '5'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '5'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -122,6 +122,20 @@ dependencies:
|
|
|
122
122
|
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: postmark
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
125
139
|
- !ruby/object:Gem::Dependency
|
|
126
140
|
name: combustion
|
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -164,54 +178,40 @@ dependencies:
|
|
|
164
178
|
- - ">="
|
|
165
179
|
- !ruby/object:Gem::Version
|
|
166
180
|
version: '0'
|
|
167
|
-
description:
|
|
168
|
-
email:
|
|
169
|
-
- andrew@chartkick.com
|
|
181
|
+
description:
|
|
182
|
+
email: andrew@chartkick.com
|
|
170
183
|
executables: []
|
|
171
184
|
extensions: []
|
|
172
185
|
extra_rdoc_files: []
|
|
173
186
|
files:
|
|
174
|
-
- ".gitignore"
|
|
175
|
-
- ".travis.yml"
|
|
176
187
|
- CHANGELOG.md
|
|
177
|
-
- Gemfile
|
|
178
188
|
- LICENSE.txt
|
|
179
189
|
- README.md
|
|
180
|
-
- Rakefile
|
|
181
190
|
- app/controllers/mailkick/subscriptions_controller.rb
|
|
182
|
-
- app/helpers/mailkick/url_helper.rb
|
|
183
191
|
- app/models/mailkick/opt_out.rb
|
|
184
192
|
- app/views/mailkick/subscriptions/show.html.erb
|
|
185
193
|
- config/routes.rb
|
|
186
194
|
- lib/generators/mailkick/install_generator.rb
|
|
187
|
-
- lib/generators/mailkick/templates/install.rb
|
|
195
|
+
- lib/generators/mailkick/templates/install.rb.tt
|
|
188
196
|
- lib/generators/mailkick/views_generator.rb
|
|
189
197
|
- lib/mailkick.rb
|
|
190
198
|
- lib/mailkick/engine.rb
|
|
191
199
|
- lib/mailkick/model.rb
|
|
192
200
|
- lib/mailkick/service.rb
|
|
201
|
+
- lib/mailkick/service/aws_ses.rb
|
|
193
202
|
- lib/mailkick/service/mailchimp.rb
|
|
194
203
|
- lib/mailkick/service/mailgun.rb
|
|
195
204
|
- lib/mailkick/service/mandrill.rb
|
|
205
|
+
- lib/mailkick/service/postmark.rb
|
|
196
206
|
- lib/mailkick/service/sendgrid.rb
|
|
207
|
+
- lib/mailkick/service/sendgrid_v2.rb
|
|
208
|
+
- lib/mailkick/url_helper.rb
|
|
197
209
|
- lib/mailkick/version.rb
|
|
198
|
-
- mailkick.gemspec
|
|
199
|
-
- test/gemfiles/actionmailer42.gemfile
|
|
200
|
-
- test/gemfiles/actionmailer50.gemfile
|
|
201
|
-
- test/gemfiles/actionmailer51.gemfile
|
|
202
|
-
- test/internal/app/mailers/user_mailer.rb
|
|
203
|
-
- test/internal/app/models/user.rb
|
|
204
|
-
- test/internal/app/views/user_mailer/welcome.html.erb
|
|
205
|
-
- test/internal/app/views/user_mailer/welcome.text.erb
|
|
206
|
-
- test/internal/config/database.yml
|
|
207
|
-
- test/internal/db/schema.rb
|
|
208
|
-
- test/mailkick_test.rb
|
|
209
|
-
- test/test_helper.rb
|
|
210
210
|
homepage: https://github.com/ankane/mailkick
|
|
211
211
|
licenses:
|
|
212
212
|
- MIT
|
|
213
213
|
metadata: {}
|
|
214
|
-
post_install_message:
|
|
214
|
+
post_install_message:
|
|
215
215
|
rdoc_options: []
|
|
216
216
|
require_paths:
|
|
217
217
|
- lib
|
|
@@ -219,27 +219,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
219
219
|
requirements:
|
|
220
220
|
- - ">="
|
|
221
221
|
- !ruby/object:Gem::Version
|
|
222
|
-
version: '
|
|
222
|
+
version: '2.4'
|
|
223
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
224
|
requirements:
|
|
225
225
|
- - ">="
|
|
226
226
|
- !ruby/object:Gem::Version
|
|
227
227
|
version: '0'
|
|
228
228
|
requirements: []
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
signing_key:
|
|
229
|
+
rubygems_version: 3.1.4
|
|
230
|
+
signing_key:
|
|
232
231
|
specification_version: 4
|
|
233
|
-
summary: Email
|
|
234
|
-
test_files:
|
|
235
|
-
- test/gemfiles/actionmailer42.gemfile
|
|
236
|
-
- test/gemfiles/actionmailer50.gemfile
|
|
237
|
-
- test/gemfiles/actionmailer51.gemfile
|
|
238
|
-
- test/internal/app/mailers/user_mailer.rb
|
|
239
|
-
- test/internal/app/models/user.rb
|
|
240
|
-
- test/internal/app/views/user_mailer/welcome.html.erb
|
|
241
|
-
- test/internal/app/views/user_mailer/welcome.text.erb
|
|
242
|
-
- test/internal/config/database.yml
|
|
243
|
-
- test/internal/db/schema.rb
|
|
244
|
-
- test/mailkick_test.rb
|
|
245
|
-
- test/test_helper.rb
|
|
232
|
+
summary: Email unsubscribes for Rails
|
|
233
|
+
test_files: []
|
data/.gitignore
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
*.gem
|
|
2
|
-
*.rbc
|
|
3
|
-
.bundle
|
|
4
|
-
.config
|
|
5
|
-
.yardoc
|
|
6
|
-
Gemfile.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/mailkick.gemspec
DELETED
|
@@ -1,32 +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 "mailkick/version"
|
|
5
|
-
|
|
6
|
-
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name = "mailkick"
|
|
8
|
-
spec.version = Mailkick::VERSION
|
|
9
|
-
spec.authors = ["Andrew Kane"]
|
|
10
|
-
spec.email = ["andrew@chartkick.com"]
|
|
11
|
-
spec.summary = "Email subscriptions made easy"
|
|
12
|
-
spec.homepage = "https://github.com/ankane/mailkick"
|
|
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.add_dependency "activesupport", ">= 4.2"
|
|
21
|
-
|
|
22
|
-
spec.add_development_dependency "bundler"
|
|
23
|
-
spec.add_development_dependency "gibbon", ">= 2"
|
|
24
|
-
spec.add_development_dependency "mailgun-ruby"
|
|
25
|
-
spec.add_development_dependency "mandrill-api"
|
|
26
|
-
spec.add_development_dependency "minitest"
|
|
27
|
-
spec.add_development_dependency "rake"
|
|
28
|
-
spec.add_development_dependency "sendgrid_toolkit"
|
|
29
|
-
spec.add_development_dependency "combustion"
|
|
30
|
-
spec.add_development_dependency "rails"
|
|
31
|
-
spec.add_development_dependency "sqlite3"
|
|
32
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<p><%= mailkick_unsubscribe_url %></p>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Unsubscribe: <%= mailkick_unsubscribe_url %>
|
data/test/internal/db/schema.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
ActiveRecord::Schema.define do
|
|
2
|
-
create_table :mailkick_opt_outs do |t|
|
|
3
|
-
t.string :email
|
|
4
|
-
t.references :user, polymorphic: true
|
|
5
|
-
t.boolean :active, null: false, default: true
|
|
6
|
-
t.string :reason
|
|
7
|
-
t.string :list
|
|
8
|
-
t.timestamps
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
add_index :mailkick_opt_outs, :email
|
|
12
|
-
|
|
13
|
-
create_table :users do |t|
|
|
14
|
-
t.string :email
|
|
15
|
-
end
|
|
16
|
-
end
|
data/test/mailkick_test.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require_relative "test_helper"
|
|
2
|
-
|
|
3
|
-
class MailkickTest < Minitest::Test
|
|
4
|
-
def test_unsubscribe_url
|
|
5
|
-
message = UserMailer.welcome.deliver_now
|
|
6
|
-
html_body = message.html_part.body.to_s
|
|
7
|
-
assert_includes html_body, "BAhbCUkiFXRlc3RAZXhhbXBsZS5vcmcGOgZFVDAwMA==--f435e91ba90e1732d3e999af1f2126dcc8182a5d"
|
|
8
|
-
text_body = message.text_part.body.to_s
|
|
9
|
-
assert_includes text_body, "BAhbCUkiFXRlc3RAZXhhbXBsZS5vcmcGOgZFVDAwMA==--f435e91ba90e1732d3e999af1f2126dcc8182a5d"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_opt_out
|
|
13
|
-
email = "test2@example.org"
|
|
14
|
-
user = User.create!(email: email)
|
|
15
|
-
|
|
16
|
-
Mailkick.opt_out(email: email, user: user)
|
|
17
|
-
|
|
18
|
-
opt_outs = Mailkick::OptOut.all.to_a
|
|
19
|
-
assert_equal 1, opt_outs.size
|
|
20
|
-
|
|
21
|
-
opt_out = opt_outs.first
|
|
22
|
-
assert_equal email, opt_out.email
|
|
23
|
-
assert_equal user, opt_out.user
|
|
24
|
-
|
|
25
|
-
assert user.opted_out?
|
|
26
|
-
assert_equal 1, User.opted_out.count
|
|
27
|
-
assert_equal 0, User.not_opted_out.count
|
|
28
|
-
end
|
|
29
|
-
end
|
data/test/test_helper.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require "bundler/setup"
|
|
2
|
-
require "combustion"
|
|
3
|
-
Bundler.require(:default)
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
require "minitest/pride"
|
|
6
|
-
require "logger"
|
|
7
|
-
|
|
8
|
-
Minitest::Test = Minitest::Unit::TestCase unless defined?(Minitest::Test)
|
|
9
|
-
|
|
10
|
-
Combustion.path = "test/internal"
|
|
11
|
-
Combustion.initialize! :all do
|
|
12
|
-
if config.active_record.sqlite3.respond_to?(:represent_boolean_as_integer)
|
|
13
|
-
config.active_record.sqlite3.represent_boolean_as_integer = false
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"]
|
|
18
|
-
ActionMailer::Base.delivery_method = :test
|
|
19
|
-
|
|
20
|
-
Mailkick.secret_token = "test123"
|