caffeinate 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/caffeinate/campaign_subscriptions_controller.rb +17 -2
  4. data/app/models/caffeinate/campaign.rb +11 -1
  5. data/app/models/caffeinate/campaign_subscription.rb +22 -5
  6. data/app/models/caffeinate/mailing.rb +18 -2
  7. data/app/views/caffeinate/campaign_subscriptions/subscribe.html.erb +3 -0
  8. data/app/views/caffeinate/campaign_subscriptions/unsubscribe.html.erb +3 -0
  9. data/app/views/layouts/caffeinate.html.erb +11 -0
  10. data/config/locales/en.yml +6 -0
  11. data/lib/caffeinate.rb +1 -0
  12. data/lib/caffeinate/action_mailer/extension.rb +11 -1
  13. data/lib/caffeinate/action_mailer/interceptor.rb +1 -1
  14. data/lib/caffeinate/action_mailer/observer.rb +3 -3
  15. data/lib/caffeinate/active_record/extension.rb +1 -1
  16. data/lib/caffeinate/drip.rb +10 -35
  17. data/lib/caffeinate/drip_evaluator.rb +33 -0
  18. data/lib/caffeinate/dripper/base.rb +2 -10
  19. data/lib/caffeinate/dripper/campaign.rb +1 -1
  20. data/lib/caffeinate/dripper/defaults.rb +1 -1
  21. data/lib/caffeinate/dripper/delivery.rb +1 -1
  22. data/lib/caffeinate/dripper/drip.rb +19 -5
  23. data/lib/caffeinate/dripper/inferences.rb +26 -0
  24. data/lib/caffeinate/dripper/perform.rb +4 -2
  25. data/lib/caffeinate/dripper/subscriber.rb +2 -2
  26. data/lib/caffeinate/engine.rb +11 -0
  27. data/lib/caffeinate/helpers.rb +21 -0
  28. data/lib/caffeinate/url_helpers.rb +7 -0
  29. data/lib/caffeinate/version.rb +1 -1
  30. data/lib/generators/caffeinate/templates/{application_campaign.rb → application_dripper.rb} +0 -0
  31. metadata +15 -15
  32. data/app/views/layouts/caffeinate/application.html.erb +0 -15
  33. data/app/views/layouts/caffeinate/campaign_subscriptions/unsubscribe.html.erb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28eb7e2e3a7a394e841eb4fe5a326ca72725281ffe804a4578e7f96bf25ab07b
4
- data.tar.gz: 9bac101dc1c3d534d2df59f3befe6e57caa5fc382569e44ce640d8b0592e8342
3
+ metadata.gz: 3032e43fad1742429e8961a3bfca1e522c9fcf19714c8cc998d6dea629c30a6e
4
+ data.tar.gz: a51f59c2d0767d18002051827590d31a7ab0b96ae570a1c048d0a37ab4446007
5
5
  SHA512:
6
- metadata.gz: f127818a38285471e57cd97a25d1ed9496dcaa7e464cbd75b6641bd513afcde870ce7e71c2afefc56c00d6f8999a29ee0d3638ac865c4077d592f94d6a216bbe
7
- data.tar.gz: f94a837c0d8a1669acb8b962d056d41c82f1b9ce02464674dab2038349fa9d16c1b7c5d4bf5b8ac7dd0bf46d6f167855f0eb55b44d51c8f6982466f8aee08c7b
6
+ metadata.gz: ede225ce8d0fbb71214411d38366ea43992da7b95428734af5c4134f496c04d2dbf2b4a940f19ffbbf24dde9c4536834b96051bd493ec3476897f6f376b2324a
7
+ data.tar.gz: acc6124e88a4d8e6beced5afc80e7774de78b60858940e579f821ed172ad14f6a033e7b0419c105c233806f94005f98d4dab73f25bbb53e40175d7dca289c9f2
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Caffeinate
2
2
 
3
- A drip mailer and management for Ruby on Rails.
3
+ Ruby on Rails drip campaign engine.
4
4
 
5
- ## Docs
5
+ ## Are there docs?
6
6
 
7
7
  [Since you asked](https://rubydoc.info/github/joshmn/caffeinate).
8
8
 
@@ -2,18 +2,33 @@
2
2
 
3
3
  module Caffeinate
4
4
  class CampaignSubscriptionsController < ApplicationController
5
+ layout 'caffeinate'
6
+
7
+ helper_method :caffeinate_unsubscribe_url, :caffeinate_subscribe_url
8
+
5
9
  before_action :find_campaign_subscription!
6
10
 
7
11
  def unsubscribe
8
12
  @campaign_subscription.unsubscribe!
9
- render plain: 'You have been unsubscribed.'
13
+ end
14
+
15
+ def subscribe
16
+ @campaign_subscription.subscribe!
10
17
  end
11
18
 
12
19
  private
13
20
 
21
+ def caffeinate_subscribe_url(**options)
22
+ Caffeinate::UrlHelpers.caffeinate_subscribe_url(@campaign_subscription, options)
23
+ end
24
+
25
+ def caffeinate_unsubscribe_url
26
+ Caffeinate::UrlHelpers.caffeinate_unsubscribe_url(@campaign_subscription, options)
27
+ end
28
+
14
29
  def find_campaign_subscription!
15
30
  @campaign_subscription = ::Caffeinate::CampaignSubscription.find_by(token: params[:token])
16
- return render plain: '404' if @campaign_subscription.nil?
31
+ raise ::ActiveRecord::RecordNotFound if @campaign_subscription.nil?
17
32
  end
18
33
  end
19
34
  end
@@ -1,7 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # == Schema Information
4
+ #
5
+ # Table name: caffeinate_campaigns
6
+ #
7
+ # id :integer not null, primary key
8
+ # name :string not null
9
+ # slug :string not null
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ #
3
13
  module Caffeinate
4
- # Campaign.
14
+ # Campaign ties together subscribers and mailings, and provides one core model for handling your Drippers.
5
15
  class Campaign < ApplicationRecord
6
16
  self.table_name = 'caffeinate_campaigns'
7
17
  has_many :caffeinate_campaign_subscriptions, class_name: 'Caffeinate::CampaignSubscription', foreign_key: :caffeinate_campaign_id
@@ -1,12 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # == Schema Information
4
+ #
5
+ # Table name: caffeinate_campaign_subscriptions
6
+ #
7
+ # id :integer not null, primary key
8
+ # caffeinate_campaign_id :integer not null
9
+ # subscriber_type :string not null
10
+ # subscriber_id :string not null
11
+ # user_type :string
12
+ # user_id :string
13
+ # token :string not null
14
+ # ended_at :datetime
15
+ # unsubscribed_at :datetime
16
+ # created_at :datetime not null
17
+ # updated_at :datetime not null
18
+ #
3
19
  module Caffeinate
4
- # CampaignSubscription associates an object and its optional user to a Campaign.
20
+ # CampaignSubscription associates an object and its optional user to a Campaign
21
+ # and its relevant Mailings.
5
22
  class CampaignSubscription < ApplicationRecord
6
23
  self.table_name = 'caffeinate_campaign_subscriptions'
7
24
 
8
25
  has_many :caffeinate_mailings, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
9
- has_one :next_caffeinate_mailing, -> { upcoming.unsent.limit(1).first }, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
26
+ has_one :next_caffeinate_mailing, -> { upcoming.unsent.limit(1).first }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
10
27
  belongs_to :caffeinate_campaign, class_name: 'Caffeinate::Campaign', foreign_key: :caffeinate_campaign_id
11
28
  belongs_to :subscriber, polymorphic: true
12
29
  belongs_to :user, polymorphic: true, optional: true
@@ -37,12 +54,12 @@ module Caffeinate
37
54
  !ended? && !unsubscribed?
38
55
  end
39
56
 
40
- # Checks if the CampaignSubscription is not subscribed
57
+ # Checks if the CampaignSubscription is not subscribed by checking the presence of `unsubscribed_at`
41
58
  def unsubscribed?
42
- !subscribed?
59
+ unsubscribed_at.present?
43
60
  end
44
61
 
45
- # Checks if the CampaignSubscription is ended
62
+ # Checks if the CampaignSubscription is ended by checking the presence of `ended_at`
46
63
  def ended?
47
64
  ended_at.present?
48
65
  end
@@ -1,8 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # == Schema Information
4
+ #
5
+ # Table name: caffeinate_mailings
6
+ #
7
+ # id :integer not null, primary key
8
+ # caffeinate_campaign_subscription_id :integer not null
9
+ # send_at :datetime
10
+ # sent_at :datetime
11
+ # skipped_at :datetime
12
+ # mailer_class :string not null
13
+ # mailer_action :string not null
14
+ # created_at :datetime not null
15
+ # updated_at :datetime not null
16
+ #
3
17
  module Caffeinate
4
18
  # Records of the mails sent and to be sent for a given `::Caffeinate::CampaignSubscriber`
5
19
  class Mailing < ApplicationRecord
20
+ CURRENT_THREAD_KEY = :current_caffeinate_mailing.freeze
21
+
6
22
  self.table_name = 'caffeinate_mailings'
7
23
 
8
24
  belongs_to :caffeinate_campaign_subscription, class_name: 'Caffeinate::CampaignSubscription'
@@ -49,7 +65,7 @@ module Caffeinate
49
65
  # The associated drip
50
66
  # @todo This can be optimized with a better cache
51
67
  def drip
52
- @drip ||= caffeinate_campaign.to_dripper.drips.find { |drip| drip.action.to_s == mailer_action }
68
+ @drip ||= caffeinate_campaign.to_dripper.drip_collection[mailer_action]
53
69
  end
54
70
 
55
71
  # The associated Subscriber from `::Caffeinate::CampaignSubscription`
@@ -64,7 +80,7 @@ module Caffeinate
64
80
 
65
81
  # Assigns attributes to the Mailing from the Drip
66
82
  def from_drip(drip)
67
- self.send_at = drip.options[:delay].from_now
83
+ self.send_at = drip.send_at
68
84
  self.mailer_class = drip.options[:mailer_class]
69
85
  self.mailer_action = drip.action
70
86
  self
@@ -0,0 +1,3 @@
1
+ <%= t("caffeinate.campaign_subscriptions.subscribe") %>
2
+ <p><%= t("caffeinate.campaign_subscriptions.changed_your_mind")%></p>
3
+ <p><%= link_to "Unsubscribe", caffeinate_subscribe_url %></p>
@@ -0,0 +1,3 @@
1
+ <h5><%= t("caffeinate.campaign_subscriptions.unsubscribe")%></h5>
2
+ <p><%= t("caffeinate.campaign_subscriptions.changed_your_mind")%></p>
3
+ <p><%= link_to "Resubscribe", caffeinate_subscribe_url %></p>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= Rails.application.class.module_parent_name %></title>
5
+ </head>
6
+ <body>
7
+
8
+ <%= yield %>
9
+
10
+ </body>
11
+ </html>
@@ -0,0 +1,6 @@
1
+ en:
2
+ caffeinate:
3
+ campaign_subscriptions:
4
+ subscribe: "You have been subscribed."
5
+ unsubscribe: "You have been unsubscribed."
6
+ changed_your_mind: "Change your mind?"
@@ -3,6 +3,7 @@
3
3
  require 'rails/all'
4
4
  require 'caffeinate/engine'
5
5
  require 'caffeinate/drip'
6
+ require 'caffeinate/url_helpers'
6
7
  require 'caffeinate/configuration'
7
8
  require 'caffeinate/dripper/base'
8
9
  require 'caffeinate/deliver_async'
@@ -5,8 +5,18 @@ module Caffeinate
5
5
  module Extension
6
6
  def self.included(klass)
7
7
  klass.before_action do
8
- @mailing = Thread.current[:current_caffeinate_mailing] if Thread.current[:current_caffeinate_mailing]
8
+ @mailing = Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY] if Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY]
9
9
  end
10
+
11
+ klass.helper_method :caffeinate_unsubscribe_url, :caffeinate_subscribe_url
12
+ end
13
+
14
+ def caffeinate_unsubscribe_url(**options)
15
+ Caffeinate::UrlHelpers.caffeinate_unsubscribe_url(@mailing.caffeinate_campaign_subscription, **options)
16
+ end
17
+
18
+ def caffeinate_subscribe_url
19
+ Caffeinate::UrlHelpers.caffeinate_subscribe_url(@mailing.caffeinate_campaign_subscription, **options)
10
20
  end
11
21
  end
12
22
  end
@@ -5,7 +5,7 @@ module Caffeinate
5
5
  class Interceptor
6
6
  # Handles `before_send` callbacks for a `Caffeinate::Dripper`
7
7
  def self.delivering_email(message)
8
- mailing = Thread.current[:current_caffeinate_mailing]
8
+ mailing = Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY]
9
9
  return unless mailing
10
10
 
11
11
  mailing.caffeinate_campaign.to_dripper.run_callbacks(:before_send, mailing.caffeinate_campaign_subscription, mailing, message)
@@ -2,14 +2,14 @@
2
2
 
3
3
  module Caffeinate
4
4
  module ActionMailer
5
- # Handles updating the Caffeinate::Message if it's available in Thread.current[:current_caffeinate_mailing]
5
+ # Handles updating the Caffeinate::Message if it's available in Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY]
6
6
  # and runs any associated callbacks
7
7
  class Observer
8
8
  def self.delivered_email(message)
9
- mailing = Thread.current[:current_caffeinate_mailing]
9
+ mailing = Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY]
10
10
  return unless mailing
11
11
 
12
- mailing.update!(sent_at: Caffeinate.config.time_now) if message.perform_deliveries
12
+ mailing.update!(sent_at: Caffeinate.config.time_now, skipped_at: nil) if message.perform_deliveries
13
13
  mailing.caffeinate_campaign.to_dripper.run_callbacks(:after_send, mailing.caffeinate_campaign_subscription, mailing, message)
14
14
  end
15
15
  end
@@ -9,7 +9,7 @@ module Caffeinate
9
9
  has_many :caffeinate_campaigns, through: :caffeinate_campaign_subscriptions, class_name: '::Caffeinate::Campaign'
10
10
  has_many :caffeinate_mailings, through: :caffeinate_campaign_subscriptions, class_name: '::Caffeinate::Mailing'
11
11
 
12
- scope :not_subscribed_to, lambda { |list|
12
+ scope :not_subscribed_to_campaign, lambda { |list|
13
13
  subscribed = ::Caffeinate::CampaignSubscription.select(:subscriber_id).joins(:caffeinate_campaign).where(caffeinate_campaigns: { slug: list }, subscriber_type: name)
14
14
  where.not(id: subscribed)
15
15
  }
@@ -1,40 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'caffeinate/drip_evaluator'
3
4
  module Caffeinate
4
5
  # A Drip object
6
+ #
7
+ # Handles the block and provides convenience methods for the drip
5
8
  class Drip
6
- # Handles the block and provides convenience methods for the drip
7
- class Evaluator
8
- attr_reader :mailing
9
- def initialize(mailing)
10
- @mailing = mailing
11
- end
12
-
13
- def call(&block)
14
- return true unless block
15
-
16
- instance_eval(&block)
17
- end
18
-
19
- # Ends the CampaignSubscription
20
- def end!
21
- mailing.caffeinate_campaign_subscription.end!
22
- false
23
- end
24
-
25
- # Unsubscribes the CampaignSubscription
26
- def unsubscribe!
27
- mailing.caffeinate_campaign_subscription.unsubscribe!
28
- false
29
- end
30
-
31
- # Skips the mailing
32
- def skip!
33
- mailing.skip!
34
- false
35
- end
36
- end
37
-
38
9
  attr_reader :dripper, :action, :options, :block
39
10
  def initialize(dripper, action, options, &block)
40
11
  @dripper = dripper
@@ -43,14 +14,18 @@ module Caffeinate
43
14
  @block = block
44
15
  end
45
16
 
46
- # If the associated ActionMailer uses `ActionMailer::Parameterized` initialization
17
+ # If the associated ActionMailer uses `ActionMailer::Parameterized` initialization instead of argument-based initialization
47
18
  def parameterized?
48
19
  options[:using] == :parameterized
49
20
  end
50
21
 
51
- # If the drip is enabled.
22
+ def send_at
23
+ options[:delay].from_now
24
+ end
25
+
26
+ # Checks if the drip is enabled
52
27
  def enabled?(mailing)
53
- Evaluator.new(mailing).call(&@block)
28
+ DripEvaluator.new(mailing).call(&@block)
54
29
  end
55
30
  end
56
31
  end
@@ -0,0 +1,33 @@
1
+ module Caffeinate
2
+ # Handles evaluating the `drip` block and provides convenience methods for handling the mailing or its campaign.
3
+ class DripEvaluator
4
+ attr_reader :mailing
5
+ def initialize(mailing)
6
+ @mailing = mailing
7
+ end
8
+
9
+ def call(&block)
10
+ return true unless block
11
+
12
+ instance_eval(&block)
13
+ end
14
+
15
+ # Ends the CampaignSubscription
16
+ def end!
17
+ mailing.caffeinate_campaign_subscription.end!
18
+ false
19
+ end
20
+
21
+ # Unsubscribes the CampaignSubscription
22
+ def unsubscribe!
23
+ mailing.caffeinate_campaign_subscription.unsubscribe!
24
+ false
25
+ end
26
+
27
+ # Skips the mailing
28
+ def skip!
29
+ mailing.skip!
30
+ false
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'caffeinate/dripper/drip'
4
+ require 'caffeinate/dripper/inferences'
4
5
  require 'caffeinate/dripper/callbacks'
5
6
  require 'caffeinate/dripper/defaults'
6
7
  require 'caffeinate/dripper/subscriber'
@@ -16,18 +17,9 @@ module Caffeinate
16
17
  include Defaults
17
18
  include Delivery
18
19
  include Drip
20
+ include Inferences
19
21
  include Perform
20
22
  include Subscriber
21
-
22
- # The inferred mailer class
23
- def self.inferred_mailer_class
24
- klass_name = "#{name.delete_suffix('Dripper')}Mailer"
25
- klass = klass_name.safe_constantize
26
- return nil unless klass
27
- return klass_name if klass < ::ActionMailer::Base
28
-
29
- nil
30
- end
31
23
  end
32
24
  end
33
25
  end
@@ -45,7 +45,7 @@ module Caffeinate
45
45
 
46
46
  # The defined slug or the inferred slug
47
47
  def campaign_slug
48
- @_campaign_slug || name.delete_suffix('Campaign')
48
+ @_campaign_slug || inferred_campaign_slug
49
49
  end
50
50
  end
51
51
  end
@@ -23,7 +23,7 @@ module Caffeinate
23
23
  # @param [Hash] options The options to set defaults with
24
24
  # @option options [String] :mailer_class The mailer class
25
25
  def default(options = {})
26
- options.assert_valid_keys(:mailer_class, :mailer)
26
+ options.assert_valid_keys(:mailer_class, :mailer, :using)
27
27
  @defaults = options
28
28
  end
29
29
  end
@@ -14,7 +14,7 @@ module Caffeinate
14
14
  #
15
15
  # @param [Caffeinate::Mailing] mailing The mailing to deliver
16
16
  def deliver!(mailing)
17
- Thread.current[:current_caffeinate_mailing] = mailing
17
+ Thread.current[::Caffeinate::Mailing::CURRENT_THREAD_KEY] = mailing
18
18
 
19
19
  if mailing.drip.parameterized?
20
20
  mailing.mailer_class.constantize.with(mailing: mailing).send(mailing.mailer_action).deliver
@@ -10,21 +10,29 @@ module Caffeinate
10
10
 
11
11
  def initialize(dripper)
12
12
  @dripper = dripper
13
- @drips = []
13
+ @drips = {}
14
14
  end
15
15
 
16
16
  # Register the drip
17
17
  def register(action, options, &block)
18
- @drips << ::Caffeinate::Drip.new(@dripper, action, options, &block)
18
+ @drips[action.to_s] = ::Caffeinate::Drip.new(@dripper, action, options, &block)
19
19
  end
20
20
 
21
21
  def each(&block)
22
- @drips.each { |drip| block.call(drip) }
22
+ @drips.each { |action_name, drip| block.call(action_name, drip) }
23
+ end
24
+
25
+ def values
26
+ @drips.values
23
27
  end
24
28
 
25
29
  def size
26
30
  @drips.size
27
31
  end
32
+
33
+ def [](val)
34
+ @drips[val]
35
+ end
28
36
  end
29
37
 
30
38
  # :nodoc:
@@ -33,9 +41,14 @@ module Caffeinate
33
41
  end
34
42
 
35
43
  module ClassMethods
44
+ # A collection of Drip objects associated with a given `Caffeinate::Dripper`
45
+ def drip_collection
46
+ @drip_collection ||= DripCollection.new(self)
47
+ end
48
+
36
49
  # A collection of Drip objects associated with a given `Caffeinate::Dripper`
37
50
  def drips
38
- @drips ||= DripCollection.new(self)
51
+ drip_collection.values
39
52
  end
40
53
 
41
54
  # Register a drip on the Dripper
@@ -50,6 +63,7 @@ module Caffeinate
50
63
  def drip(action_name, options = {}, &block)
51
64
  options.assert_valid_keys(:mailer_class, :step, :delay, :using, :mailer)
52
65
  options[:mailer_class] ||= options[:mailer] || defaults[:mailer_class]
66
+ options[:using] ||= defaults[:using]
53
67
  options[:step] ||= drips.size + 1
54
68
 
55
69
  if options[:mailer_class].nil?
@@ -57,7 +71,7 @@ module Caffeinate
57
71
  end
58
72
  raise ArgumentError, "You must define :delay in the options for :#{action_name}" if options[:delay].nil?
59
73
 
60
- drips.register(action_name, options, &block)
74
+ drip_collection.register(action_name, options, &block)
61
75
  end
62
76
  end
63
77
  end
@@ -0,0 +1,26 @@
1
+ module Caffeinate
2
+ module Dripper
3
+ module Inferences
4
+ def self.included(klass)
5
+ klass.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ # The inferred mailer class
10
+ def inferred_mailer_class
11
+ klass_name = "#{name.delete_suffix('Dripper')}Mailer"
12
+ klass = klass_name.safe_constantize
13
+ return nil unless klass
14
+ return klass_name if klass < ::ActionMailer::Base
15
+
16
+ nil
17
+ end
18
+
19
+ # The inferred mailer class
20
+ def inferred_campaign_slug
21
+ "#{name.delete_suffix('Dripper')}".underscore
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -15,8 +15,10 @@ module Caffeinate
15
15
  #
16
16
  # @return nil
17
17
  def perform!
18
- campaign.caffeinate_campaign_subscriptions.joins(:next_caffeinate_mailing).includes(:next_caffeinate_mailing).each do |subscriber|
19
- subscriber.next_caffeinate_mailing.process!
18
+ campaign.caffeinate_campaign_subscriptions.active.includes(:next_caffeinate_mailing).each do |subscriber|
19
+ if subscriber.next_caffeinate_mailing
20
+ subscriber.next_caffeinate_mailing.process!
21
+ end
20
22
  end
21
23
  true
22
24
  end
@@ -30,8 +30,8 @@ module Caffeinate
30
30
  # @option [ActiveRecord::Base] :user The associated user (optional)
31
31
  #
32
32
  # @return [Caffeinate::CampaignSubscriber] the created CampaignSubscriber
33
- def subscribe(subscriber, user:)
34
- caffeinate_campaign.subscribe(subscriber, user: user)
33
+ def subscribe(subscriber, **args)
34
+ caffeinate_campaign.subscribe(subscriber, **args)
35
35
  end
36
36
 
37
37
  # :nodoc:
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'caffeinate/helpers'
3
4
  require 'caffeinate/action_mailer'
4
5
  require 'caffeinate/active_record/extension'
5
6
 
@@ -8,6 +9,12 @@ module Caffeinate
8
9
  class Engine < ::Rails::Engine
9
10
  isolate_namespace Caffeinate
10
11
 
12
+ config.to_prepare do
13
+ Dir.glob(Rails.root.join("app/drippers/**/*.rb")).each do |file|
14
+ require file
15
+ end
16
+ end
17
+
11
18
  ActiveSupport.on_load(:action_mailer) do
12
19
  include ::Caffeinate::ActionMailer::Extension
13
20
  ::ActionMailer::Base.register_interceptor(::Caffeinate::ActionMailer::Interceptor)
@@ -17,5 +24,9 @@ module Caffeinate
17
24
  ActiveSupport.on_load(:active_record) do
18
25
  extend ::Caffeinate::ActiveRecord::Extension
19
26
  end
27
+
28
+ ActiveSupport.on_load(:action_view) do
29
+ ApplicationHelper.send(:include, ::Caffeinate::Helpers)
30
+ end
20
31
  end
21
32
  end
@@ -0,0 +1,21 @@
1
+ module Caffeinate
2
+ module Helpers
3
+ def caffeinate_unsubscribe_url(subscription, **options)
4
+ opts = (::ActionMailer::Base.default_url_options || {}).merge(options)
5
+ Caffeinate::Engine.routes.url_helpers.unsubscribe_campaign_subscription_url(token: subscription.token, **opts)
6
+ end
7
+
8
+ def caffeinate_subscribe_url(subscription, **options)
9
+ opts = (::ActionMailer::Base.default_url_options || {}).merge(options)
10
+ Caffeinate::Engine.routes.url_helpers.subscribe_campaign_subscription_url(token: subscription.token, **opts)
11
+ end
12
+
13
+ def caffeinate_unsubscribe_path(subscription, **options)
14
+ Caffeinate::Engine.routes.url_helpers.unsubscribe_campaign_subscription_path(token: subscription.token, **options)
15
+ end
16
+
17
+ def caffeinate_subscribe_path(subscription, **options)
18
+ Caffeinate::Engine.routes.url_helpers.subscribe_campaign_subscription_path(token: subscription.token, **options)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ require 'caffeinate/helpers'
2
+
3
+ module Caffeinate
4
+ class UrlHelpers
5
+ extend Helpers
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Caffeinate
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caffeinate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Brody
@@ -14,22 +14,16 @@ dependencies:
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 6.0.3
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
- version: 6.0.3.4
19
+ version: 5.0.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: 6.0.3
30
24
  - - ">="
31
25
  - !ruby/object:Gem::Version
32
- version: 6.0.3.4
26
+ version: 5.0.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: factory_bot_rails
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +108,7 @@ dependencies:
114
108
  - - ">="
115
109
  - !ruby/object:Gem::Version
116
110
  version: '0'
117
- description: Opinionated drip campaign framework.
111
+ description: Ruby on Rails drip campaign engine. Buzzwords!
118
112
  email:
119
113
  - josh@josh.mn
120
114
  executables: []
@@ -130,8 +124,10 @@ files:
130
124
  - app/models/caffeinate/campaign.rb
131
125
  - app/models/caffeinate/campaign_subscription.rb
132
126
  - app/models/caffeinate/mailing.rb
133
- - app/views/layouts/caffeinate/application.html.erb
134
- - app/views/layouts/caffeinate/campaign_subscriptions/unsubscribe.html.erb
127
+ - app/views/caffeinate/campaign_subscriptions/subscribe.html.erb
128
+ - app/views/caffeinate/campaign_subscriptions/unsubscribe.html.erb
129
+ - app/views/layouts/caffeinate.html.erb
130
+ - config/locales/en.yml
135
131
  - config/routes.rb
136
132
  - db/migrate/20201124183102_create_caffeinate_campaigns.rb
137
133
  - db/migrate/20201124183303_create_caffeinate_campaign_subscriptions.rb
@@ -146,18 +142,22 @@ files:
146
142
  - lib/caffeinate/configuration.rb
147
143
  - lib/caffeinate/deliver_async.rb
148
144
  - lib/caffeinate/drip.rb
145
+ - lib/caffeinate/drip_evaluator.rb
149
146
  - lib/caffeinate/dripper/base.rb
150
147
  - lib/caffeinate/dripper/callbacks.rb
151
148
  - lib/caffeinate/dripper/campaign.rb
152
149
  - lib/caffeinate/dripper/defaults.rb
153
150
  - lib/caffeinate/dripper/delivery.rb
154
151
  - lib/caffeinate/dripper/drip.rb
152
+ - lib/caffeinate/dripper/inferences.rb
155
153
  - lib/caffeinate/dripper/perform.rb
156
154
  - lib/caffeinate/dripper/subscriber.rb
157
155
  - lib/caffeinate/engine.rb
156
+ - lib/caffeinate/helpers.rb
157
+ - lib/caffeinate/url_helpers.rb
158
158
  - lib/caffeinate/version.rb
159
159
  - lib/generators/caffeinate/install_generator.rb
160
- - lib/generators/caffeinate/templates/application_campaign.rb
160
+ - lib/generators/caffeinate/templates/application_dripper.rb
161
161
  - lib/generators/caffeinate/templates/caffeinate.rb
162
162
  homepage: https://github.com/joshmn/caffeinate
163
163
  licenses:
@@ -178,8 +178,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0'
180
180
  requirements: []
181
- rubygems_version: 3.0.3
181
+ rubygems_version: 3.2.0.rc.2
182
182
  signing_key:
183
183
  specification_version: 4
184
- summary: Opinionated drip campaign framework.
184
+ summary: Ruby on Rails drip campaign engine. Buzzwords!
185
185
  test_files: []
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Caffeinate</title>
5
- <%= csrf_meta_tags %>
6
- <%= csp_meta_tag %>
7
-
8
- <%= stylesheet_link_tag "caffeinate/application", media: "all" %>
9
- </head>
10
- <body>
11
-
12
- <%= yield %>
13
-
14
- </body>
15
- </html>
@@ -1 +0,0 @@
1
- <h5>You have been unsubscribed.</h5>