caffeinate 0.2.0 → 0.6.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/README.md +162 -77
- data/app/controllers/caffeinate/campaign_subscriptions_controller.rb +3 -3
- data/app/models/caffeinate/application_record.rb +0 -1
- data/app/models/caffeinate/campaign.rb +49 -2
- data/app/models/caffeinate/campaign_subscription.rb +50 -13
- data/app/models/caffeinate/mailing.rb +14 -6
- data/app/views/layouts/{caffeinate.html.erb → _caffeinate.html.erb} +0 -0
- data/db/migrate/20201124183102_create_caffeinate_campaigns.rb +1 -0
- data/db/migrate/20201124183303_create_caffeinate_campaign_subscriptions.rb +6 -3
- data/db/migrate/20201124183419_create_caffeinate_mailings.rb +2 -1
- data/lib/caffeinate.rb +4 -8
- data/lib/caffeinate/action_mailer.rb +4 -4
- data/lib/caffeinate/action_mailer/extension.rb +11 -5
- data/lib/caffeinate/action_mailer/interceptor.rb +4 -2
- data/lib/caffeinate/action_mailer/observer.rb +4 -3
- data/lib/caffeinate/active_record/extension.rb +17 -11
- data/lib/caffeinate/configuration.rb +11 -2
- data/lib/caffeinate/drip.rb +15 -2
- data/lib/caffeinate/drip_evaluator.rb +3 -0
- data/lib/caffeinate/dripper/base.rb +12 -5
- data/lib/caffeinate/dripper/batching.rb +22 -0
- data/lib/caffeinate/dripper/callbacks.rb +89 -6
- data/lib/caffeinate/dripper/campaign.rb +20 -8
- data/lib/caffeinate/dripper/defaults.rb +4 -2
- data/lib/caffeinate/dripper/delivery.rb +8 -8
- data/lib/caffeinate/dripper/drip.rb +3 -42
- data/lib/caffeinate/dripper/drip_collection.rb +62 -0
- data/lib/caffeinate/dripper/inferences.rb +7 -2
- data/lib/caffeinate/dripper/perform.rb +14 -7
- data/lib/caffeinate/dripper/periodical.rb +26 -0
- data/lib/caffeinate/dripper/subscriber.rb +14 -2
- data/lib/caffeinate/dripper_collection.rb +17 -0
- data/lib/caffeinate/engine.rb +6 -4
- data/lib/caffeinate/helpers.rb +3 -0
- data/lib/caffeinate/mail_ext.rb +12 -0
- data/lib/caffeinate/url_helpers.rb +3 -0
- data/lib/caffeinate/version.rb +1 -1
- data/lib/generators/caffeinate/install_generator.rb +5 -1
- data/lib/generators/caffeinate/templates/caffeinate.rb +21 -1
- metadata +22 -4
- data/lib/caffeinate/action_mailer/helpers.rb +0 -12
@@ -17,12 +17,12 @@
|
|
17
17
|
module Caffeinate
|
18
18
|
# Records of the mails sent and to be sent for a given `::Caffeinate::CampaignSubscriber`
|
19
19
|
class Mailing < ApplicationRecord
|
20
|
-
CURRENT_THREAD_KEY = :current_caffeinate_mailing.freeze
|
21
|
-
|
22
20
|
self.table_name = 'caffeinate_mailings'
|
23
21
|
|
24
22
|
belongs_to :caffeinate_campaign_subscription, class_name: 'Caffeinate::CampaignSubscription'
|
23
|
+
alias_attribute :subscription, :caffeinate_campaign_subscription
|
25
24
|
has_one :caffeinate_campaign, through: :caffeinate_campaign_subscription
|
25
|
+
alias_attribute :campaign, :caffeinate_campaign
|
26
26
|
|
27
27
|
scope :upcoming, -> { unsent.unskipped.where('send_at < ?', ::Caffeinate.config.time_now).order('send_at asc') }
|
28
28
|
scope :unsent, -> { unskipped.where(sent_at: nil) }
|
@@ -30,6 +30,13 @@ module Caffeinate
|
|
30
30
|
scope :skipped, -> { where.not(skipped_at: nil) }
|
31
31
|
scope :unskipped, -> { where(skipped_at: nil) }
|
32
32
|
|
33
|
+
def initialize_dup(args)
|
34
|
+
super
|
35
|
+
self.send_at = nil
|
36
|
+
self.sent_at = nil
|
37
|
+
self.skipped_at = nil
|
38
|
+
end
|
39
|
+
|
33
40
|
# Checks if the Mailing is not skipped and not sent
|
34
41
|
def pending?
|
35
42
|
unskipped? && unsent?
|
@@ -59,13 +66,12 @@ module Caffeinate
|
|
59
66
|
def skip!
|
60
67
|
update!(skipped_at: Caffeinate.config.time_now)
|
61
68
|
|
62
|
-
caffeinate_campaign.to_dripper.run_callbacks(:on_skip,
|
69
|
+
caffeinate_campaign.to_dripper.run_callbacks(:on_skip, self)
|
63
70
|
end
|
64
71
|
|
65
72
|
# The associated drip
|
66
|
-
# @todo This can be optimized with a better cache
|
67
73
|
def drip
|
68
|
-
@drip ||= caffeinate_campaign.to_dripper.drip_collection
|
74
|
+
@drip ||= caffeinate_campaign.to_dripper.drip_collection.for(mailer_action)
|
69
75
|
end
|
70
76
|
|
71
77
|
# The associated Subscriber from `::Caffeinate::CampaignSubscription`
|
@@ -80,7 +86,7 @@ module Caffeinate
|
|
80
86
|
|
81
87
|
# Assigns attributes to the Mailing from the Drip
|
82
88
|
def from_drip(drip)
|
83
|
-
self.send_at = drip.send_at
|
89
|
+
self.send_at = drip.send_at(self)
|
84
90
|
self.mailer_class = drip.options[:mailer_class]
|
85
91
|
self.mailer_action = drip.action
|
86
92
|
self
|
@@ -93,6 +99,8 @@ module Caffeinate
|
|
93
99
|
else
|
94
100
|
deliver!
|
95
101
|
end
|
102
|
+
|
103
|
+
caffeinate_campaign_subscription.touch
|
96
104
|
end
|
97
105
|
|
98
106
|
# Delivers the Mailing in the foreground
|
File without changes
|
@@ -7,16 +7,19 @@ class CreateCaffeinateCampaignSubscriptions < ActiveRecord::Migration[6.0]
|
|
7
7
|
create_table :caffeinate_campaign_subscriptions do |t|
|
8
8
|
t.references :caffeinate_campaign, null: false, index: { name: :caffeineate_campaign_subscriptions_on_campaign }, foreign_key: true
|
9
9
|
t.string :subscriber_type, null: false
|
10
|
-
t.
|
10
|
+
t.integer :subscriber_id, null: false
|
11
11
|
t.string :user_type
|
12
|
-
t.
|
12
|
+
t.integer :user_id
|
13
13
|
t.string :token, null: false
|
14
14
|
t.datetime :ended_at
|
15
|
+
t.string :ended_reason
|
16
|
+
t.datetime :resubscribed_at
|
15
17
|
t.datetime :unsubscribed_at
|
18
|
+
t.string :unsubscribe_reason
|
16
19
|
|
17
20
|
t.timestamps
|
18
21
|
end
|
19
22
|
add_index :caffeinate_campaign_subscriptions, :token, unique: true
|
20
|
-
add_index :caffeinate_campaign_subscriptions, %i[subscriber_id subscriber_type user_id user_type], name: :index_caffeinate_campaign_subscriptions
|
23
|
+
add_index :caffeinate_campaign_subscriptions, %i[caffeinate_campaign_id subscriber_id subscriber_type user_id user_type ended_at resubscribed_at unsubscribed_at], name: :index_caffeinate_campaign_subscriptions
|
21
24
|
end
|
22
25
|
end
|
@@ -14,6 +14,7 @@ class CreateCaffeinateMailings < ActiveRecord::Migration[6.0]
|
|
14
14
|
|
15
15
|
t.timestamps
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
|
+
add_index :caffeinate_mailings, %i[caffeinate_campaign_subscription_id send_at sent_at skipped_at], name: :index_caffeinate_mailings
|
18
19
|
end
|
19
20
|
end
|
data/lib/caffeinate.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails/all'
|
4
|
+
require 'caffeinate/mail_ext'
|
4
5
|
require 'caffeinate/engine'
|
5
6
|
require 'caffeinate/drip'
|
6
7
|
require 'caffeinate/url_helpers'
|
7
8
|
require 'caffeinate/configuration'
|
8
9
|
require 'caffeinate/dripper/base'
|
9
10
|
require 'caffeinate/deliver_async'
|
11
|
+
require 'caffeinate/dripper_collection'
|
10
12
|
|
11
13
|
module Caffeinate
|
12
|
-
|
13
|
-
|
14
|
-
@dripper_to_campaign_class ||= {}
|
15
|
-
end
|
16
|
-
|
17
|
-
# Convenience method for `dripper_to_campaign_class`
|
18
|
-
def self.register_dripper(name, klass)
|
19
|
-
dripper_to_campaign_class[name.to_sym] = klass
|
14
|
+
def self.dripper_collection
|
15
|
+
@drippers ||= DripperCollection.new
|
20
16
|
end
|
21
17
|
|
22
18
|
# Global configuration
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
require
|
3
|
+
require 'mail'
|
4
|
+
|
5
|
+
# Includes all files in `caffeinate/action_mailer`
|
6
|
+
Dir["#{__dir__}/action_mailer/*"].each { |path| require "caffeinate/action_mailer/#{File.basename(path)}" }
|
@@ -2,21 +2,27 @@
|
|
2
2
|
|
3
3
|
module Caffeinate
|
4
4
|
module ActionMailer
|
5
|
+
# Convenience for setting `@mailing`, and convenience methods for inferred `caffeinate_unsubscribe_url` and
|
6
|
+
# `caffeinate_subscribe_url`.
|
5
7
|
module Extension
|
6
8
|
def self.included(klass)
|
7
9
|
klass.before_action do
|
8
|
-
@mailing =
|
10
|
+
@mailing = params[:mailing] if params
|
9
11
|
end
|
10
12
|
|
11
13
|
klass.helper_method :caffeinate_unsubscribe_url, :caffeinate_subscribe_url
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
# Assumes `@mailing` is set
|
17
|
+
def caffeinate_unsubscribe_url(mailing: nil, **options)
|
18
|
+
mailing ||= @mailing
|
19
|
+
Caffeinate::UrlHelpers.caffeinate_unsubscribe_url(mailing.caffeinate_campaign_subscription, **options)
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
22
|
+
# Assumes `@mailing` is set
|
23
|
+
def caffeinate_subscribe_url(mailing: nil, **options)
|
24
|
+
mailing ||= @mailing
|
25
|
+
Caffeinate::UrlHelpers.caffeinate_subscribe_url(mailing.caffeinate_campaign_subscription, **options)
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
module Caffeinate
|
4
4
|
module ActionMailer
|
5
|
+
# Handles the evaluation of a drip against a mailing to determine if it ultimately gets delivered.
|
6
|
+
# Also invokes the `before_send` callbacks.
|
5
7
|
class Interceptor
|
6
8
|
# Handles `before_send` callbacks for a `Caffeinate::Dripper`
|
7
9
|
def self.delivering_email(message)
|
8
|
-
mailing =
|
10
|
+
mailing = message.caffeinate_mailing
|
9
11
|
return unless mailing
|
10
12
|
|
11
|
-
mailing.caffeinate_campaign.to_dripper.run_callbacks(:before_send, mailing
|
13
|
+
mailing.caffeinate_campaign.to_dripper.run_callbacks(:before_send, mailing, message)
|
12
14
|
drip = mailing.drip
|
13
15
|
message.perform_deliveries = drip.enabled?(mailing)
|
14
16
|
end
|
@@ -2,15 +2,16 @@
|
|
2
2
|
|
3
3
|
module Caffeinate
|
4
4
|
module ActionMailer
|
5
|
-
# Handles updating the Caffeinate::Message if it's available in
|
5
|
+
# Handles updating the Caffeinate::Message if it's available in Mail::Message.caffeinate_mailing
|
6
6
|
# and runs any associated callbacks
|
7
7
|
class Observer
|
8
8
|
def self.delivered_email(message)
|
9
|
-
mailing =
|
9
|
+
mailing = message.caffeinate_mailing
|
10
10
|
return unless mailing
|
11
11
|
|
12
12
|
mailing.update!(sent_at: Caffeinate.config.time_now, skipped_at: nil) if message.perform_deliveries
|
13
|
-
mailing.caffeinate_campaign.to_dripper.run_callbacks(:after_send, mailing
|
13
|
+
mailing.caffeinate_campaign.to_dripper.run_callbacks(:after_send, mailing, message)
|
14
|
+
true
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -2,32 +2,38 @@
|
|
2
2
|
|
3
3
|
module Caffeinate
|
4
4
|
module ActiveRecord
|
5
|
+
# Includes the ActiveRecord association and relevant scopes for an ActiveRecord-backed model
|
5
6
|
module Extension
|
6
7
|
# Adds the associations for a subscriber
|
7
|
-
def
|
8
|
-
has_many :caffeinate_campaign_subscriptions, as: :subscriber, class_name: '::Caffeinate::CampaignSubscription'
|
8
|
+
def acts_as_caffeinate_subscriber
|
9
|
+
has_many :caffeinate_campaign_subscriptions, as: :subscriber, class_name: '::Caffeinate::CampaignSubscription', dependent: :destroy
|
9
10
|
has_many :caffeinate_campaigns, through: :caffeinate_campaign_subscriptions, class_name: '::Caffeinate::Campaign'
|
10
11
|
has_many :caffeinate_mailings, through: :caffeinate_campaign_subscriptions, class_name: '::Caffeinate::Mailing'
|
11
12
|
|
12
13
|
scope :not_subscribed_to_campaign, lambda { |list|
|
13
|
-
|
14
|
-
|
14
|
+
where.not(id: ::Caffeinate::CampaignSubscription
|
15
|
+
.select(:subscriber_id)
|
16
|
+
.joins(:caffeinate_campaign)
|
17
|
+
.where(subscriber_type: name, caffeinate_campaigns: { slug: list }))
|
15
18
|
}
|
16
19
|
|
17
20
|
scope :unsubscribed_from_campaign, lambda { |list|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
where(id: unsubscribed)
|
21
|
+
where(id: ::Caffeinate::CampaignSubscription
|
22
|
+
.unsubscribed
|
23
|
+
.select(:subscriber_id)
|
24
|
+
.joins(:caffeinate_campaign)
|
25
|
+
.where(subscriber_type: name, caffeinate_campaigns: { slug: list }))
|
24
26
|
}
|
25
27
|
end
|
28
|
+
alias caffeinate_subscriber acts_as_caffeinate_subscriber
|
26
29
|
|
27
30
|
# Adds the associations for a user
|
28
|
-
def
|
31
|
+
def acts_as_caffeinate_user
|
29
32
|
has_many :caffeinate_campaign_subscriptions_as_user, as: :user, class_name: '::Caffeinate::CampaignSubscription'
|
33
|
+
has_many :caffeinate_campaigns_as_user, through: :caffeinate_campaign_subscriptions_as_user, class_name: '::Caffeinate::Campaign'
|
34
|
+
has_many :caffeinate_mailings_as_user, through: :caffeinate_campaign_subscriptions_as_user, class_name: '::Caffeinate::Campaign'
|
30
35
|
end
|
36
|
+
alias caffeinate_user acts_as_caffeinate_user
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
@@ -1,19 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Caffeinate
|
4
|
+
# Global configuration
|
4
5
|
class Configuration
|
5
|
-
attr_accessor :now, :async_delivery, :mailing_job
|
6
|
+
attr_accessor :now, :async_delivery, :mailing_job, :batch_size, :drippers_path, :implicit_campaigns
|
6
7
|
|
7
8
|
def initialize
|
8
9
|
@now = -> { Time.current }
|
9
10
|
@async_delivery = false
|
10
11
|
@mailing_job = nil
|
12
|
+
@batch_size = 1_000
|
13
|
+
@drippers_path = 'app/drippers'
|
14
|
+
@implicit_campaigns = true
|
11
15
|
end
|
12
16
|
|
13
17
|
def now=(val)
|
14
18
|
raise ArgumentError, '#now must be a proc' unless val.respond_to?(:call)
|
15
19
|
|
16
|
-
|
20
|
+
@now = val
|
21
|
+
end
|
22
|
+
|
23
|
+
# Automatically create a `::Caffeinate::Campaign` object if not found per `Dripper.inferred_campaign_slug`
|
24
|
+
def implicit_campaigns?
|
25
|
+
@implicit_campaigns == true
|
17
26
|
end
|
18
27
|
|
19
28
|
# The current time, for database calls
|
data/lib/caffeinate/drip.rb
CHANGED
@@ -7,6 +7,7 @@ module Caffeinate
|
|
7
7
|
# Handles the block and provides convenience methods for the drip
|
8
8
|
class Drip
|
9
9
|
attr_reader :dripper, :action, :options, :block
|
10
|
+
|
10
11
|
def initialize(dripper, action, options, &block)
|
11
12
|
@dripper = dripper
|
12
13
|
@action = action
|
@@ -19,12 +20,24 @@ module Caffeinate
|
|
19
20
|
options[:using] == :parameterized
|
20
21
|
end
|
21
22
|
|
22
|
-
def send_at
|
23
|
-
|
23
|
+
def send_at(mailing = nil)
|
24
|
+
if periodical?
|
25
|
+
start = mailing.instance_exec(&options[:start])
|
26
|
+
start += options[:every] if mailing.caffeinate_campaign_subscription.caffeinate_mailings.count.positive?
|
27
|
+
start.from_now
|
28
|
+
else
|
29
|
+
options[:delay].from_now
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def periodical?
|
34
|
+
options[:every].present?
|
24
35
|
end
|
25
36
|
|
26
37
|
# Checks if the drip is enabled
|
27
38
|
def enabled?(mailing)
|
39
|
+
dripper.run_callbacks(:before_drip, self, mailing)
|
40
|
+
|
28
41
|
DripEvaluator.new(mailing).call(&@block)
|
29
42
|
end
|
30
43
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Caffeinate
|
2
4
|
# Handles evaluating the `drip` block and provides convenience methods for handling the mailing or its campaign.
|
3
5
|
class DripEvaluator
|
4
6
|
attr_reader :mailing
|
7
|
+
|
5
8
|
def initialize(mailing)
|
6
9
|
@mailing = mailing
|
7
10
|
end
|
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'caffeinate/dripper/
|
4
|
-
require 'caffeinate/dripper/inferences'
|
3
|
+
require 'caffeinate/dripper/batching'
|
5
4
|
require 'caffeinate/dripper/callbacks'
|
6
|
-
require 'caffeinate/dripper/defaults'
|
7
|
-
require 'caffeinate/dripper/subscriber'
|
8
5
|
require 'caffeinate/dripper/campaign'
|
9
|
-
require 'caffeinate/dripper/
|
6
|
+
require 'caffeinate/dripper/defaults'
|
10
7
|
require 'caffeinate/dripper/delivery'
|
8
|
+
require 'caffeinate/dripper/drip'
|
9
|
+
require 'caffeinate/dripper/inferences'
|
10
|
+
require 'caffeinate/dripper/perform'
|
11
|
+
require 'caffeinate/dripper/periodical'
|
12
|
+
require 'caffeinate/dripper/subscriber'
|
11
13
|
|
12
14
|
module Caffeinate
|
13
15
|
module Dripper
|
16
|
+
# Base class
|
14
17
|
class Base
|
18
|
+
include Batching
|
15
19
|
include Callbacks
|
16
20
|
include Campaign
|
17
21
|
include Defaults
|
@@ -19,7 +23,10 @@ module Caffeinate
|
|
19
23
|
include Drip
|
20
24
|
include Inferences
|
21
25
|
include Perform
|
26
|
+
include Periodical
|
22
27
|
include Subscriber
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
31
|
+
|
32
|
+
ActiveSupport.run_load_hooks :caffeinate, Caffeinate::Dripper::Base
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Caffeinate
|
4
|
+
module Dripper
|
5
|
+
# Includes batch support for setting the batch size for Perform
|
6
|
+
module Batching
|
7
|
+
def self.included(klass)
|
8
|
+
klass.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def batch_size=(num)
|
13
|
+
@batch_size = num
|
14
|
+
end
|
15
|
+
|
16
|
+
def batch_size
|
17
|
+
@batch_size || ::Caffeinate.config.batch_size
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -2,12 +2,17 @@
|
|
2
2
|
|
3
3
|
module Caffeinate
|
4
4
|
module Dripper
|
5
|
+
# Callbacks for a Dripper.
|
5
6
|
module Callbacks
|
6
7
|
# :nodoc:
|
7
8
|
def self.included(klass)
|
8
9
|
klass.extend ClassMethods
|
9
10
|
end
|
10
11
|
|
12
|
+
def run_callbacks(name, *args)
|
13
|
+
self.class.run_callbacks(name, *args)
|
14
|
+
end
|
15
|
+
|
11
16
|
module ClassMethods
|
12
17
|
# :nodoc:
|
13
18
|
def run_callbacks(name, *args)
|
@@ -33,15 +38,80 @@ module Caffeinate
|
|
33
38
|
@on_subscribe_blocks ||= []
|
34
39
|
end
|
35
40
|
|
41
|
+
# Callback after a Caffeinate::CampaignSubscription is `#resubscribed!`
|
42
|
+
#
|
43
|
+
# on_resubscribe do |campaign_subscription|
|
44
|
+
# Slack.notify(:caffeinate, "Someone resubscribed to #{campaign_subscription.campaign.name}!")
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# @yield Caffeinate::CampaignSubscription
|
48
|
+
def on_resubscribe(&block)
|
49
|
+
on_resubscribe_blocks << block
|
50
|
+
end
|
51
|
+
|
52
|
+
# :nodoc:
|
53
|
+
def on_resubscribe_blocks
|
54
|
+
@on_resubscribe_blocks ||= []
|
55
|
+
end
|
56
|
+
|
57
|
+
# Callback before the mailings get processed.
|
58
|
+
#
|
59
|
+
# before_perform do |dripper|
|
60
|
+
# Slack.notify(:caffeinate, "Dripper is getting ready for mailing! #{dripper.caffeinate_campaign.name}!")
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# @yield Caffeinate::Dripper
|
64
|
+
def before_perform(&block)
|
65
|
+
before_perform_blocks << block
|
66
|
+
end
|
67
|
+
|
68
|
+
# :nodoc:
|
69
|
+
def before_perform_blocks
|
70
|
+
@before_perform_blocks ||= []
|
71
|
+
end
|
72
|
+
|
73
|
+
# Callback before the mailings get processed in a batch.
|
74
|
+
#
|
75
|
+
# after_process do |dripper, mailings|
|
76
|
+
# Slack.notify(:caffeinate, "Dripper #{dripper.name} sent #{mailings.size} mailings! Whoa!")
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @yield Caffeinate::Dripper
|
80
|
+
# @yield Caffeinate::Mailing [Array]
|
81
|
+
def on_perform(&block)
|
82
|
+
on_perform_blocks << block
|
83
|
+
end
|
84
|
+
|
85
|
+
# :nodoc:
|
86
|
+
def on_perform_blocks
|
87
|
+
@on_perform_blocks ||= []
|
88
|
+
end
|
89
|
+
|
90
|
+
# Callback after the all the mailings have been sent.
|
91
|
+
#
|
92
|
+
# after_process do |dripper|
|
93
|
+
# Slack.notify(:caffeinate, "Dripper #{dripper.name} sent #{mailings.size} mailings! Whoa!")
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# @yield Caffeinate::Dripper
|
97
|
+
# @yield Caffeinate::Mailing [Array]
|
98
|
+
def after_perform(&block)
|
99
|
+
after_perform_blocks << block
|
100
|
+
end
|
101
|
+
|
102
|
+
# :nodoc:
|
103
|
+
def after_perform_blocks
|
104
|
+
@after_perform_blocks ||= []
|
105
|
+
end
|
106
|
+
|
36
107
|
# Callback before a Drip has called the mailer.
|
37
108
|
#
|
38
109
|
# before_drip do |campaign_subscription, mailing, drip|
|
39
110
|
# Slack.notify(:caffeinate, "#{drip.action_name} is starting")
|
40
111
|
# end
|
41
112
|
#
|
42
|
-
# @yield Caffeinate::CampaignSubscription
|
43
|
-
# @yield Caffeinate::Mailing
|
44
113
|
# @yield Caffeinate::Drip current drip
|
114
|
+
# @yield Caffeinate::Mailing
|
45
115
|
def before_drip(&block)
|
46
116
|
before_drip_blocks << block
|
47
117
|
end
|
@@ -57,7 +127,6 @@ module Caffeinate
|
|
57
127
|
# Slack.notify(:caffeinate, "A new subscriber to #{campaign_subscription.campaign.name}!")
|
58
128
|
# end
|
59
129
|
#
|
60
|
-
# @yield Caffeinate::CampaignSubscription
|
61
130
|
# @yield Caffeinate::Mailing
|
62
131
|
# @yield Mail::Message
|
63
132
|
def before_send(&block)
|
@@ -75,7 +144,6 @@ module Caffeinate
|
|
75
144
|
# Slack.notify(:caffeinate, "A new subscriber to #{campaign_subscription.campaign.name}!")
|
76
145
|
# end
|
77
146
|
#
|
78
|
-
# @yield Caffeinate::CampaignSubscription
|
79
147
|
# @yield Caffeinate::Mailing
|
80
148
|
# @yield Mail::Message
|
81
149
|
def after_send(&block)
|
@@ -119,14 +187,29 @@ module Caffeinate
|
|
119
187
|
@on_unsubscribe_blocks ||= []
|
120
188
|
end
|
121
189
|
|
190
|
+
# Callback after a CampaignSubscriber has ended.
|
191
|
+
#
|
192
|
+
# on_end do |campaign_sub|
|
193
|
+
# Slack.notify(:caffeinate, "#{campaign_sub.id} has ended... sad day.")
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# @yield Caffeinate::CampaignSubscription
|
197
|
+
def on_end(&block)
|
198
|
+
on_end_blocks << block
|
199
|
+
end
|
200
|
+
|
201
|
+
# :nodoc:
|
202
|
+
def on_end_blocks
|
203
|
+
@on_end_blocks ||= []
|
204
|
+
end
|
205
|
+
|
122
206
|
# Callback after a `Caffeinate::Mailing` is skipped.
|
123
207
|
#
|
124
208
|
# on_skip do |campaign_subscription, mailing, message|
|
125
209
|
# Slack.notify(:caffeinate, "#{campaign_sub.id} has unsubscribed... sad day.")
|
126
210
|
# end
|
127
211
|
#
|
128
|
-
# @yield Caffeinate::
|
129
|
-
# @yield Caffeinate::Mailing
|
212
|
+
# @yield `Caffeinate::Mailing`
|
130
213
|
def on_skip(&block)
|
131
214
|
on_skip_blocks << block
|
132
215
|
end
|