caffeinate 2.5.0 → 2.6.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 +4 -4
- data/README.md +14 -1
- data/app/controllers/caffeinate/campaign_subscriptions_controller.rb +4 -0
- data/app/models/caffeinate/campaign_subscription.rb +4 -3
- data/app/models/caffeinate/mailing.rb +3 -2
- data/config/routes.rb +2 -1
- data/lib/caffeinate/dripper_collection.rb +1 -1
- data/lib/caffeinate/mail_ext.rb +2 -1
- data/lib/caffeinate/version.rb +1 -1
- data/lib/generators/caffeinate/install_generator.rb +37 -0
- data/lib/generators/caffeinate/templates/migrations/create_caffeinate_campaign_subscriptions.rb.tt +4 -4
- data/lib/generators/caffeinate/templates/migrations/create_caffeinate_campaigns.rb.tt +5 -1
- data/lib/generators/caffeinate/templates/migrations/create_caffeinate_mailings.rb.tt +2 -2
- metadata +74 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 768001daf3c0272130745b6749648d136118f4c8a24c2e1b4bca19e77d2883b6
|
|
4
|
+
data.tar.gz: ae9c61c07b543ec15fd3b6e7c7ea09ccdc199c52c54e37f83fc2894717725776
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6311c1a5b9d62542770f7551eff109b7b3f50d6075c8df0462ada136b0f60048da667dcbdf3703a5d847edb5abd0db8ae37cdf38f847ddeb1609d999798dd17f
|
|
7
|
+
data.tar.gz: 943a81a8b7f2a3cefbc4862a8da7c031b00426ec0f4e271eecb0e74b72a6d48e896a3ee9dbb98f64e2363be37a5df7dd57bb8c6f3e2f9f7770e34a25d8127e3e
|
data/README.md
CHANGED
|
@@ -152,6 +152,19 @@ $ rails g caffeinate:install
|
|
|
152
152
|
$ rake db:migrate
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
+
Optionally, use different flags for supporting `bigint` or `uuid`:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# UUID with pgcrypto (PostgreSQL < 13)
|
|
159
|
+
rails g caffeinate:install --uuid
|
|
160
|
+
|
|
161
|
+
# UUID without pgcrypto (PostgreSQL 13+)
|
|
162
|
+
rails g caffeinate:install --uuid --skip-pgcrypto
|
|
163
|
+
|
|
164
|
+
# Or via primary-key-type
|
|
165
|
+
rails g caffeinate:install --primary-key-type=uuid --skip-pgcrypto
|
|
166
|
+
```
|
|
167
|
+
|
|
155
168
|
### Clean up the business logic
|
|
156
169
|
|
|
157
170
|
Assuming you intend to use Caffeinate to handle emails using ActionMailer, mailers should be responsible for receiving context and creating a `mail` object. Nothing more. (If you are looking for examples that don't use ActionMailer, see [Without ActionMailer](docs/6-without-action-mailer.md).)
|
|
@@ -216,7 +229,7 @@ a `Caffeinate::CampaignSubscription`.
|
|
|
216
229
|
```ruby
|
|
217
230
|
class User < ApplicationRecord
|
|
218
231
|
after_commit on: :create do
|
|
219
|
-
OnboardingDripper.subscribe
|
|
232
|
+
OnboardingDripper.subscribe(self)
|
|
220
233
|
end
|
|
221
234
|
end
|
|
222
235
|
```
|
|
@@ -8,8 +8,12 @@ module Caffeinate
|
|
|
8
8
|
|
|
9
9
|
before_action :find_campaign_subscription!
|
|
10
10
|
|
|
11
|
+
skip_before_action :verify_authenticity_token, only: [:unsubscribe], if: -> { request.post? }
|
|
12
|
+
|
|
11
13
|
def unsubscribe
|
|
12
14
|
@campaign_subscription.unsubscribe!(true)
|
|
15
|
+
|
|
16
|
+
head :ok if request.post?
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
def subscribe
|
|
@@ -27,8 +27,8 @@ module Caffeinate
|
|
|
27
27
|
class CampaignSubscription < ApplicationRecord
|
|
28
28
|
self.table_name = 'caffeinate_campaign_subscriptions'
|
|
29
29
|
|
|
30
|
-
has_many :caffeinate_mailings, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
|
|
31
|
-
has_many :mailings, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
|
|
30
|
+
has_many :caffeinate_mailings, -> { order(send_at: :asc) }, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
|
|
31
|
+
has_many :mailings, -> { order(send_at: :asc) }, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
|
|
32
32
|
has_many :future_mailings, -> { upcoming.unsent }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
|
|
33
33
|
|
|
34
34
|
has_one :next_caffeinate_mailing, -> { joins(:caffeinate_campaign_subscription).where(caffeinate_campaign_subscriptions: { ended_at: nil, unsubscribed_at: nil }).upcoming.unsent.order(send_at: :asc) }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
|
|
@@ -38,7 +38,8 @@ module Caffeinate
|
|
|
38
38
|
has_one :previous_mailing, -> { sent.order(sent_at: :desc) }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
|
|
39
39
|
|
|
40
40
|
belongs_to :caffeinate_campaign, class_name: 'Caffeinate::Campaign', foreign_key: :caffeinate_campaign_id
|
|
41
|
-
|
|
41
|
+
alias_method :campaign, :caffeinate_campaign
|
|
42
|
+
alias_method :campaign=, :caffeinate_campaign=
|
|
42
43
|
|
|
43
44
|
belongs_to :subscriber, polymorphic: true
|
|
44
45
|
belongs_to :user, polymorphic: true, optional: true
|
|
@@ -20,9 +20,10 @@ module Caffeinate
|
|
|
20
20
|
self.table_name = 'caffeinate_mailings'
|
|
21
21
|
|
|
22
22
|
belongs_to :caffeinate_campaign_subscription, class_name: 'Caffeinate::CampaignSubscription'
|
|
23
|
-
|
|
23
|
+
alias_method :subscription, :caffeinate_campaign_subscription
|
|
24
|
+
alias_method :subscription=, :caffeinate_campaign_subscription=
|
|
24
25
|
has_one :caffeinate_campaign, through: :caffeinate_campaign_subscription
|
|
25
|
-
|
|
26
|
+
alias_method :campaign, :caffeinate_campaign
|
|
26
27
|
|
|
27
28
|
scope :upcoming, -> { joins(:caffeinate_campaign_subscription).where(caffeinate_campaign_subscription: ::Caffeinate::CampaignSubscription.active).unsent.unskipped.where('send_at < ?', ::Caffeinate.config.time_now).order('send_at asc') }
|
|
28
29
|
scope :unsent, -> { unskipped.where(sent_at: nil) }
|
data/config/routes.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Caffeinate
|
|
|
25
25
|
# get truncated). This resets the appropriate class-variables between specs
|
|
26
26
|
def clear_cache!
|
|
27
27
|
drippers.each do |dripper|
|
|
28
|
-
dripper.safe_constantize
|
|
28
|
+
dripper.safe_constantize&.instance_variable_set(:@caffeinate_campaign, nil)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
data/lib/caffeinate/mail_ext.rb
CHANGED
|
@@ -12,7 +12,8 @@ module Mail
|
|
|
12
12
|
def caffeinate_mailing=(mailing)
|
|
13
13
|
@caffeinate_mailing = mailing
|
|
14
14
|
if mailing.is_a?(::Caffeinate::Mailing)
|
|
15
|
-
header['List-Unsubscribe'] = "<#{Caffeinate::UrlHelpers.
|
|
15
|
+
header['List-Unsubscribe'] = "<#{Caffeinate::UrlHelpers.caffeinate_unsubscribe_url(mailing.subscription)}>"
|
|
16
|
+
header['List-Unsubscribe-Post'] = 'List-Unsubscribe=One-Click'
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
|
data/lib/caffeinate/version.rb
CHANGED
|
@@ -8,6 +8,43 @@ module Caffeinate
|
|
|
8
8
|
|
|
9
9
|
desc 'Creates a Caffeinate initializer and copies migrations to your application.'
|
|
10
10
|
|
|
11
|
+
class_option :uuid, type: :boolean, default: false,
|
|
12
|
+
desc: 'Use UUID primary keys'
|
|
13
|
+
|
|
14
|
+
class_option :primary_key_type, type: :string, default: nil,
|
|
15
|
+
desc: 'Primary key type: uuid, bigint, or integer (default)'
|
|
16
|
+
|
|
17
|
+
class_option :skip_pgcrypto, type: :boolean, default: false,
|
|
18
|
+
desc: 'Skip pgcrypto extension (PostgreSQL 13+ has gen_random_uuid built-in)'
|
|
19
|
+
|
|
20
|
+
def primary_key_type
|
|
21
|
+
return :uuid if options[:uuid]
|
|
22
|
+
return options[:primary_key_type].to_sym if options[:primary_key_type]
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def primary_key_option
|
|
27
|
+
return '' unless primary_key_type
|
|
28
|
+
", id: :#{primary_key_type}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def foreign_key_type
|
|
32
|
+
return '' unless primary_key_type
|
|
33
|
+
", type: :#{primary_key_type}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def column_type_for_polymorphic
|
|
37
|
+
case primary_key_type
|
|
38
|
+
when :uuid then :uuid
|
|
39
|
+
when :bigint then :bigint
|
|
40
|
+
else :integer
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def enable_pgcrypto?
|
|
45
|
+
primary_key_type == :uuid && !options[:skip_pgcrypto]
|
|
46
|
+
end
|
|
47
|
+
|
|
11
48
|
# :nodoc:
|
|
12
49
|
def copy_initializer
|
|
13
50
|
template 'caffeinate.rb', 'config/initializers/caffeinate.rb'
|
data/lib/generators/caffeinate/templates/migrations/create_caffeinate_campaign_subscriptions.rb.tt
CHANGED
|
@@ -4,12 +4,12 @@ class CreateCaffeinateCampaignSubscriptions < ActiveRecord::Migration<%= migrati
|
|
|
4
4
|
def change
|
|
5
5
|
drop_table :caffeinate_campaign_subscriptions if table_exists?(:caffeinate_campaign_subscriptions)
|
|
6
6
|
|
|
7
|
-
create_table :caffeinate_campaign_subscriptions do |t|
|
|
8
|
-
t.references :caffeinate_campaign, null: false, index: { name: :caffeineate_campaign_subscriptions_on_campaign }, foreign_key: true
|
|
7
|
+
create_table :caffeinate_campaign_subscriptions<%= primary_key_option %> do |t|
|
|
8
|
+
t.references :caffeinate_campaign, null: false, index: { name: :caffeineate_campaign_subscriptions_on_campaign }, foreign_key: true<%= foreign_key_type %>
|
|
9
9
|
t.string :subscriber_type, null: false
|
|
10
|
-
t
|
|
10
|
+
t.<%= column_type_for_polymorphic %> :subscriber_id, null: false
|
|
11
11
|
t.string :user_type
|
|
12
|
-
t
|
|
12
|
+
t.<%= column_type_for_polymorphic %> :user_id
|
|
13
13
|
t.string :token, null: false
|
|
14
14
|
t.datetime :ended_at
|
|
15
15
|
t.string :ended_reason
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
class CreateCaffeinateCampaigns < ActiveRecord::Migration<%= migration_version %>
|
|
4
4
|
def change
|
|
5
|
-
|
|
5
|
+
<% if enable_pgcrypto? -%>
|
|
6
|
+
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
|
|
7
|
+
|
|
8
|
+
<% end -%>
|
|
9
|
+
create_table :caffeinate_campaigns<%= primary_key_option %> do |t|
|
|
6
10
|
t.string :name, null: false
|
|
7
11
|
t.string :slug, null: false
|
|
8
12
|
t.boolean :active, default: true, null: false
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
class CreateCaffeinateMailings < ActiveRecord::Migration<%= migration_version %>
|
|
4
4
|
def change
|
|
5
|
-
create_table :caffeinate_mailings do |t|
|
|
6
|
-
t.references :caffeinate_campaign_subscription, null: false, foreign_key: true, index: { name: 'index_caffeinate_mailings_on_campaign_subscription' }
|
|
5
|
+
create_table :caffeinate_mailings<%= primary_key_option %> do |t|
|
|
6
|
+
t.references :caffeinate_campaign_subscription, null: false, foreign_key: true, index: { name: 'index_caffeinate_mailings_on_campaign_subscription' }<%= foreign_key_type %>
|
|
7
7
|
t.datetime :send_at, null: false
|
|
8
8
|
t.datetime :sent_at
|
|
9
9
|
t.datetime :skipped_at
|
metadata
CHANGED
|
@@ -1,17 +1,58 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: caffeinate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josh Brody
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 5.0.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 5.0.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: actionpack
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 5.0.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 5.0.0
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: actionmailer
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 5.0.0
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 5.0.0
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: actionview
|
|
15
56
|
requirement: !ruby/object:Gem::Requirement
|
|
16
57
|
requirements:
|
|
17
58
|
- - ">="
|
|
@@ -94,6 +135,20 @@ dependencies:
|
|
|
94
135
|
- - ">="
|
|
95
136
|
- !ruby/object:Gem::Version
|
|
96
137
|
version: '0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: pg
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
type: :development
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
97
152
|
- !ruby/object:Gem::Dependency
|
|
98
153
|
name: sqlite3
|
|
99
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,6 +163,20 @@ dependencies:
|
|
|
108
163
|
- - ">="
|
|
109
164
|
- !ruby/object:Gem::Version
|
|
110
165
|
version: '0'
|
|
166
|
+
- !ruby/object:Gem::Dependency
|
|
167
|
+
name: sprockets-rails
|
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: '0'
|
|
173
|
+
type: :development
|
|
174
|
+
prerelease: false
|
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
111
180
|
- !ruby/object:Gem::Dependency
|
|
112
181
|
name: timecop
|
|
113
182
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -213,7 +282,6 @@ homepage: https://github.com/joshmn/caffeinate
|
|
|
213
282
|
licenses:
|
|
214
283
|
- MIT
|
|
215
284
|
metadata: {}
|
|
216
|
-
post_install_message:
|
|
217
285
|
rdoc_options: []
|
|
218
286
|
require_paths:
|
|
219
287
|
- lib
|
|
@@ -228,8 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
228
296
|
- !ruby/object:Gem::Version
|
|
229
297
|
version: '0'
|
|
230
298
|
requirements: []
|
|
231
|
-
rubygems_version:
|
|
232
|
-
signing_key:
|
|
299
|
+
rubygems_version: 4.0.1
|
|
233
300
|
specification_version: 4
|
|
234
301
|
summary: Create, manage, and send scheduled email sequences and drip campaigns from
|
|
235
302
|
your Rails app.
|