mailkick 0.1.4 → 1.0.1
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 +5 -5
- data/CHANGELOG.md +72 -11
- data/LICENSE.txt +1 -1
- data/README.md +152 -97
- data/app/controllers/mailkick/subscriptions_controller.rb +41 -20
- data/app/models/mailkick/opt_out.rb +1 -1
- data/app/models/mailkick/subscription.rb +9 -0
- data/app/views/mailkick/subscriptions/show.html.erb +1 -1
- data/config/routes.rb +3 -1
- data/lib/generators/mailkick/install_generator.rb +6 -17
- data/lib/generators/mailkick/templates/install.rb.tt +11 -0
- data/lib/mailkick/engine.rb +13 -5
- data/lib/mailkick/legacy.rb +70 -0
- data/lib/mailkick/model.rb +11 -21
- data/lib/mailkick/service/aws_ses.rb +47 -0
- data/lib/mailkick/service/mailchimp.rb +5 -5
- data/lib/mailkick/service/mailgun.rb +1 -1
- data/lib/mailkick/service/mandrill.rb +6 -2
- 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/lib/mailkick/service.rb +1 -15
- data/lib/mailkick/url_helper.rb +8 -0
- data/lib/mailkick/version.rb +1 -1
- data/lib/mailkick.rb +32 -65
- metadata +21 -39
- data/.gitignore +0 -22
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/app/helpers/mailkick/url_helper.rb +0 -13
- data/lib/generators/mailkick/templates/install.rb +0 -16
- data/lib/mailkick/mailer.rb +0 -11
- data/lib/mailkick/processor.rb +0 -27
- data/mailkick.gemspec +0 -23
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :mailkick_subscriptions do |t|
|
4
|
+
t.references :subscriber, polymorphic: true, index: false
|
5
|
+
t.string :list
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :mailkick_subscriptions, [:subscriber_type, :subscriber_id, :list], unique: true, name: "index_mailkick_subscriptions_on_subscriber_and_list"
|
10
|
+
end
|
11
|
+
end
|
data/lib/mailkick/engine.rb
CHANGED
@@ -3,11 +3,19 @@ module Mailkick
|
|
3
3
|
isolate_namespace Mailkick
|
4
4
|
|
5
5
|
initializer "mailkick" do |app|
|
6
|
-
Mailkick.discover_services
|
7
|
-
|
8
|
-
Mailkick.secret_token ||=
|
9
|
-
|
10
|
-
|
6
|
+
Mailkick.discover_services unless Mailkick.services.any?
|
7
|
+
|
8
|
+
Mailkick.secret_token ||= begin
|
9
|
+
creds =
|
10
|
+
if app.respond_to?(:credentials) && app.credentials.secret_key_base
|
11
|
+
app.credentials
|
12
|
+
elsif app.respond_to?(:secrets)
|
13
|
+
app.secrets
|
14
|
+
else
|
15
|
+
app.config
|
16
|
+
end
|
17
|
+
|
18
|
+
creds.respond_to?(:secret_key_base) ? creds.secret_key_base : creds.secret_token
|
11
19
|
end
|
12
20
|
end
|
13
21
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Mailkick
|
2
|
+
module Legacy
|
3
|
+
# checks for table as long as it exists
|
4
|
+
def self.opt_outs?
|
5
|
+
unless defined?(@opt_outs) && @opt_outs == false
|
6
|
+
@opt_outs = ActiveRecord::Base.connection.table_exists?("mailkick_opt_outs")
|
7
|
+
end
|
8
|
+
@opt_outs
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.opted_out?(options)
|
12
|
+
opt_outs(options).any?
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.opt_out(options)
|
16
|
+
unless opted_out?(options)
|
17
|
+
time = options[:time] || Time.now
|
18
|
+
Mailkick::OptOut.create! do |o|
|
19
|
+
o.email = options[:email]
|
20
|
+
o.user = options[:user]
|
21
|
+
o.reason = options[:reason] || "unsubscribe"
|
22
|
+
o.list = options[:list]
|
23
|
+
o.created_at = time
|
24
|
+
o.updated_at = time
|
25
|
+
end
|
26
|
+
end
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.opt_in(options)
|
31
|
+
opt_outs(options).each do |opt_out|
|
32
|
+
opt_out.active = false
|
33
|
+
opt_out.save!
|
34
|
+
end
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.opt_outs(options = {})
|
39
|
+
relation = Mailkick::OptOut.where(active: true)
|
40
|
+
|
41
|
+
contact_relation = Mailkick::OptOut.none
|
42
|
+
if (email = options[:email])
|
43
|
+
contact_relation = contact_relation.or(Mailkick::OptOut.where(email: email))
|
44
|
+
end
|
45
|
+
if (user = options[:user])
|
46
|
+
contact_relation = contact_relation.or(
|
47
|
+
Mailkick::OptOut.where("user_id = ? AND user_type = ?", user.id, user.class.name)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
relation = relation.merge(contact_relation) if email || user
|
51
|
+
|
52
|
+
relation =
|
53
|
+
if options[:list]
|
54
|
+
relation.where("list IS NULL OR list = ?", options[:list])
|
55
|
+
else
|
56
|
+
relation.where("list IS NULL")
|
57
|
+
end
|
58
|
+
|
59
|
+
relation
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.opted_out_emails(options = {})
|
63
|
+
Set.new(opt_outs(options).where.not(email: nil).distinct.pluck(:email))
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.opted_out_users(options = {})
|
67
|
+
Set.new(opt_outs(options).where.not(user_id: nil).map(&:user))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/mailkick/model.rb
CHANGED
@@ -1,32 +1,22 @@
|
|
1
1
|
module Mailkick
|
2
2
|
module Model
|
3
|
-
def
|
4
|
-
email_key = options[:email_key] || :email
|
3
|
+
def has_subscriptions
|
5
4
|
class_eval do
|
6
|
-
|
7
|
-
|
8
|
-
if options[:list]
|
9
|
-
query = "(mailkick_opt_outs.list IS NULL OR mailkick_opt_outs.list = ?)"
|
10
|
-
binds << options[:list]
|
11
|
-
else
|
12
|
-
query = "mailkick_opt_outs.list IS NULL"
|
13
|
-
end
|
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
|
-
}
|
16
|
-
scope :not_opted_out, proc {|options = {}|
|
17
|
-
opted_out(options.merge(not: true))
|
18
|
-
}
|
5
|
+
has_many :mailkick_subscriptions, class_name: "Mailkick::Subscription", as: :subscriber
|
6
|
+
scope :subscribed, -> (list) { joins(:mailkick_subscriptions).where(mailkick_subscriptions: {list: list}) }
|
19
7
|
|
20
|
-
def
|
21
|
-
|
8
|
+
def subscribe(list)
|
9
|
+
mailkick_subscriptions.where(list: list).first_or_create!
|
10
|
+
nil
|
22
11
|
end
|
23
12
|
|
24
|
-
def
|
25
|
-
|
13
|
+
def unsubscribe(list)
|
14
|
+
mailkick_subscriptions.where(list: list).delete_all
|
15
|
+
nil
|
26
16
|
end
|
27
17
|
|
28
|
-
def
|
29
|
-
|
18
|
+
def subscribed?(list)
|
19
|
+
mailkick_subscriptions.where(list: list).exists?
|
30
20
|
end
|
31
21
|
end
|
32
22
|
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
|
@@ -4,7 +4,7 @@ module Mailkick
|
|
4
4
|
class Service
|
5
5
|
class Mailchimp < Mailkick::Service
|
6
6
|
def initialize(options = {})
|
7
|
-
@gibbon = ::Gibbon::
|
7
|
+
@gibbon = ::Gibbon::Request.new(api_key: options[:api_key] || ENV["MAILCHIMP_API_KEY"])
|
8
8
|
@list_id = options[:list_id] || ENV["MAILCHIMP_LIST_ID"]
|
9
9
|
end
|
10
10
|
|
@@ -14,11 +14,11 @@ module Mailkick
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def unsubscribes
|
17
|
-
fetch(@gibbon.lists.members(
|
17
|
+
fetch(@gibbon.lists(@list_id).members.retrieve(params: {status: "unsubscribed"}).body["members"], "unsubscribe")
|
18
18
|
end
|
19
19
|
|
20
20
|
def spam_reports
|
21
|
-
fetch(@gibbon.lists
|
21
|
+
fetch(@gibbon.lists(@list_id).abuse_reports.retrieve.body["abuse_reports"], "spam")
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.discoverable?
|
@@ -28,9 +28,9 @@ module Mailkick
|
|
28
28
|
protected
|
29
29
|
|
30
30
|
def fetch(response, reason)
|
31
|
-
response
|
31
|
+
response.map do |record|
|
32
32
|
{
|
33
|
-
email: record["
|
33
|
+
email: record["email_address"],
|
34
34
|
time: ActiveSupport::TimeZone["UTC"].parse(record["timestamp_opt"] || record["date"]),
|
35
35
|
reason: reason
|
36
36
|
}
|
@@ -6,7 +6,7 @@ module Mailkick
|
|
6
6
|
def initialize(options = {})
|
7
7
|
require "mailgun"
|
8
8
|
mailgun_client = ::Mailgun::Client.new(options[:api_key] || ENV["MAILGUN_API_KEY"])
|
9
|
-
domain = options[:domain] || ActionMailer::Base.
|
9
|
+
domain = options[:domain] || ActionMailer::Base.smtp_settings[:domain]
|
10
10
|
@mailgun_events = ::Mailgun::Events.new(mailgun_client, domain)
|
11
11
|
end
|
12
12
|
|
@@ -10,9 +10,12 @@ module Mailkick
|
|
10
10
|
"unsub" => "unsubscribe"
|
11
11
|
}
|
12
12
|
|
13
|
+
# TODO remove ENV["MANDRILL_APIKEY"]
|
13
14
|
def initialize(options = {})
|
14
15
|
require "mandrill"
|
15
|
-
@mandrill = ::Mandrill::API.new(
|
16
|
+
@mandrill = ::Mandrill::API.new(
|
17
|
+
options[:api_key] || ENV["MANDRILL_APIKEY"] || ENV["MANDRILL_API_KEY"]
|
18
|
+
)
|
16
19
|
end
|
17
20
|
|
18
21
|
# TODO paginate
|
@@ -26,8 +29,9 @@ module Mailkick
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
32
|
+
# TODO remove ENV["MANDRILL_APIKEY"]
|
29
33
|
def self.discoverable?
|
30
|
-
!!(defined?(::Mandrill::API) && ENV["MANDRILL_APIKEY"])
|
34
|
+
!!(defined?(::Mandrill::API) && (ENV["MANDRILL_APIKEY"] || ENV["MANDRILL_API_KEY"]))
|
31
35
|
end
|
32
36
|
end
|
33
37
|
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
|
data/lib/mailkick/service.rb
CHANGED
@@ -1,21 +1,7 @@
|
|
1
1
|
module Mailkick
|
2
2
|
class Service
|
3
3
|
def fetch_opt_outs
|
4
|
-
opt_outs
|
5
|
-
email = api_data[:email]
|
6
|
-
time = api_data[:time]
|
7
|
-
|
8
|
-
opt_out = Mailkick::OptOut.where(email: email).order("updated_at desc").first
|
9
|
-
if !opt_out || (time > opt_out.updated_at && !opt_out.active)
|
10
|
-
Mailkick.opt_out(
|
11
|
-
email: email,
|
12
|
-
user: Mailkick.user_method ? Mailkick.user_method.call(email) : nil,
|
13
|
-
reason: api_data[:reason],
|
14
|
-
time: time
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
true
|
4
|
+
Mailkick.process_opt_outs_method.call(opt_outs)
|
19
5
|
end
|
20
6
|
end
|
21
7
|
end
|
data/lib/mailkick/version.rb
CHANGED
data/lib/mailkick.rb
CHANGED
@@ -1,19 +1,31 @@
|
|
1
|
-
|
2
|
-
require "
|
3
|
-
|
4
|
-
|
1
|
+
# dependencies
|
2
|
+
require "active_support"
|
3
|
+
|
4
|
+
# stdlib
|
5
|
+
require "set"
|
6
|
+
|
7
|
+
# modules
|
8
|
+
require "mailkick/legacy"
|
5
9
|
require "mailkick/model"
|
6
10
|
require "mailkick/service"
|
11
|
+
require "mailkick/service/aws_ses"
|
7
12
|
require "mailkick/service/mailchimp"
|
13
|
+
require "mailkick/service/mailgun"
|
8
14
|
require "mailkick/service/mandrill"
|
9
15
|
require "mailkick/service/sendgrid"
|
10
|
-
require "mailkick/service/
|
11
|
-
require "
|
16
|
+
require "mailkick/service/sendgrid_v2"
|
17
|
+
require "mailkick/service/postmark"
|
18
|
+
require "mailkick/url_helper"
|
19
|
+
require "mailkick/version"
|
20
|
+
|
21
|
+
# integrations
|
22
|
+
require "mailkick/engine" if defined?(Rails)
|
12
23
|
|
13
24
|
module Mailkick
|
14
|
-
mattr_accessor :services, :
|
25
|
+
mattr_accessor :services, :secret_token, :mount, :process_opt_outs_method
|
15
26
|
self.services = []
|
16
|
-
self.
|
27
|
+
self.mount = true
|
28
|
+
self.process_opt_outs_method = ->(_) { raise "process_opt_outs_method not defined" }
|
17
29
|
|
18
30
|
def self.fetch_opt_outs
|
19
31
|
services.each(&:fetch_opt_outs)
|
@@ -25,67 +37,22 @@ module Mailkick
|
|
25
37
|
end
|
26
38
|
end
|
27
39
|
|
28
|
-
def self.
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.opt_out(options)
|
33
|
-
unless opted_out?(options)
|
34
|
-
time = options[:time] || Time.now
|
35
|
-
Mailkick::OptOut.create! do |o|
|
36
|
-
o.email = options[:email]
|
37
|
-
o.user = options[:user]
|
38
|
-
o.reason = options[:reason] || "unsubscribe"
|
39
|
-
o.list = options[:list]
|
40
|
-
o.created_at = time
|
41
|
-
o.updated_at = time
|
42
|
-
end
|
43
|
-
end
|
44
|
-
true
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.opt_in(options)
|
48
|
-
opt_outs(options).each do |opt_out|
|
49
|
-
opt_out.active = false
|
50
|
-
opt_out.save!
|
51
|
-
end
|
52
|
-
true
|
40
|
+
def self.message_verifier
|
41
|
+
@message_verifier ||= ActiveSupport::MessageVerifier.new(Mailkick.secret_token)
|
53
42
|
end
|
54
43
|
|
55
|
-
def self.
|
56
|
-
|
57
|
-
|
58
|
-
parts = []
|
59
|
-
binds = []
|
60
|
-
if (email = options[:email])
|
61
|
-
parts << "email = ?"
|
62
|
-
binds << email
|
63
|
-
end
|
64
|
-
if (user = options[:user])
|
65
|
-
parts << "user_id = ? and user_type = ?"
|
66
|
-
binds.concat [user.id, user.class.name]
|
67
|
-
end
|
68
|
-
relation = relation.where(parts.join(" OR "), *binds) if parts.any?
|
69
|
-
|
70
|
-
relation =
|
71
|
-
if options[:list]
|
72
|
-
relation.where("list IS NULL OR list = ?", options[:list])
|
73
|
-
else
|
74
|
-
relation.where("list IS NULL")
|
75
|
-
end
|
76
|
-
|
77
|
-
relation
|
78
|
-
end
|
44
|
+
def self.generate_token(subscriber, list)
|
45
|
+
raise ArgumentError, "Missing subscriber" unless subscriber
|
46
|
+
raise ArgumentError, "Missing list" unless list.present?
|
79
47
|
|
80
|
-
|
81
|
-
Set.new(opt_outs(options).where("email IS NOT NULL").uniq.pluck(:email))
|
48
|
+
message_verifier.generate([nil, subscriber.id, subscriber.class.name, list])
|
82
49
|
end
|
50
|
+
end
|
83
51
|
|
84
|
-
|
85
|
-
|
86
|
-
Set.new(opt_outs(options).where("user_id IS NOT NULL").map(&:user))
|
87
|
-
end
|
52
|
+
ActiveSupport.on_load :action_mailer do
|
53
|
+
helper Mailkick::UrlHelper
|
88
54
|
end
|
89
55
|
|
90
|
-
|
91
|
-
|
56
|
+
ActiveSupport.on_load(:active_record) do
|
57
|
+
extend Mailkick::Model
|
58
|
+
end
|
metadata
CHANGED
@@ -1,81 +1,65 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
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: 2021-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.6'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.6'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
14
|
+
name: activesupport
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
19
|
+
version: '5.2'
|
20
|
+
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - ">="
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
description:
|
42
|
-
email:
|
43
|
-
- andrew@chartkick.com
|
26
|
+
version: '5.2'
|
27
|
+
description:
|
28
|
+
email: andrew@ankane.org
|
44
29
|
executables: []
|
45
30
|
extensions: []
|
46
31
|
extra_rdoc_files: []
|
47
32
|
files:
|
48
|
-
- ".gitignore"
|
49
33
|
- CHANGELOG.md
|
50
|
-
- Gemfile
|
51
34
|
- LICENSE.txt
|
52
35
|
- README.md
|
53
|
-
- Rakefile
|
54
36
|
- app/controllers/mailkick/subscriptions_controller.rb
|
55
|
-
- app/helpers/mailkick/url_helper.rb
|
56
37
|
- app/models/mailkick/opt_out.rb
|
38
|
+
- app/models/mailkick/subscription.rb
|
57
39
|
- app/views/mailkick/subscriptions/show.html.erb
|
58
40
|
- config/routes.rb
|
59
41
|
- lib/generators/mailkick/install_generator.rb
|
60
|
-
- lib/generators/mailkick/templates/install.rb
|
42
|
+
- lib/generators/mailkick/templates/install.rb.tt
|
61
43
|
- lib/generators/mailkick/views_generator.rb
|
62
44
|
- lib/mailkick.rb
|
63
45
|
- lib/mailkick/engine.rb
|
64
|
-
- lib/mailkick/
|
46
|
+
- lib/mailkick/legacy.rb
|
65
47
|
- lib/mailkick/model.rb
|
66
|
-
- lib/mailkick/processor.rb
|
67
48
|
- lib/mailkick/service.rb
|
49
|
+
- lib/mailkick/service/aws_ses.rb
|
68
50
|
- lib/mailkick/service/mailchimp.rb
|
69
51
|
- lib/mailkick/service/mailgun.rb
|
70
52
|
- lib/mailkick/service/mandrill.rb
|
53
|
+
- lib/mailkick/service/postmark.rb
|
71
54
|
- lib/mailkick/service/sendgrid.rb
|
55
|
+
- lib/mailkick/service/sendgrid_v2.rb
|
56
|
+
- lib/mailkick/url_helper.rb
|
72
57
|
- lib/mailkick/version.rb
|
73
|
-
- mailkick.gemspec
|
74
58
|
homepage: https://github.com/ankane/mailkick
|
75
59
|
licenses:
|
76
60
|
- MIT
|
77
61
|
metadata: {}
|
78
|
-
post_install_message:
|
62
|
+
post_install_message:
|
79
63
|
rdoc_options: []
|
80
64
|
require_paths:
|
81
65
|
- lib
|
@@ -83,17 +67,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
67
|
requirements:
|
84
68
|
- - ">="
|
85
69
|
- !ruby/object:Gem::Version
|
86
|
-
version: '
|
70
|
+
version: '2.6'
|
87
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
72
|
requirements:
|
89
73
|
- - ">="
|
90
74
|
- !ruby/object:Gem::Version
|
91
75
|
version: '0'
|
92
76
|
requirements: []
|
93
|
-
|
94
|
-
|
95
|
-
signing_key:
|
77
|
+
rubygems_version: 3.2.3
|
78
|
+
signing_key:
|
96
79
|
specification_version: 4
|
97
|
-
summary: Email subscriptions
|
80
|
+
summary: Email subscriptions for Rails
|
98
81
|
test_files: []
|
99
|
-
has_rdoc:
|