heya 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8640e8fc2f4d593d85d4417b2f149d0afda39a88ffa3881f5558988c5ddda694
4
- data.tar.gz: 3e4c574c46b7fad452c6a0394fafbab5730e51d3927798c30a38284f8ae35f61
3
+ metadata.gz: d8c3a56453c65b17eaa7dcc3489bacd9dcdb78da9f134e18e0fa7d3cc818de11
4
+ data.tar.gz: cd6eb4a27002ebb62307cd44007960cc39637f7ab6b3129d5800061e1bf762c4
5
5
  SHA512:
6
- metadata.gz: 1a042f0c2280489b968c7882bcc1f850c95c67ab15cd0a2c90cc8adcacd55134628c75a2e2284eb24b2791f20ada01c4b6cd17b1d475d5a7970c9e96d06653ec
7
- data.tar.gz: bef8ea2e36960de46f733eb12418b261a9241698d9d60f4b2277b34a2063b49f54a378f007643c54d49208f92c13612fd37310c2b71cebda720527c389a93608
6
+ metadata.gz: 69aacf834f7a3d02e63aff2dc4be5af386785e2c5172c19dadedb6789c1557332efbbc33db3a2be75382a05f0b746c7c1787fd369bbbc081e655c137006905df
7
+ data.tar.gz: 2d3c1465261ba7b1737aa64e20b00e14f696f401f1abe1a93e31ec3fd6b5133d7f4fc6cee886a817e478a43ca3ae4ec5ba9760a4e62a685f6db9568acddab0b9
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
  ### Added
9
+ - Support Rails 7.2 (#270, @jbennett)
10
+
11
+ ### Fixed
12
+ - Fix a typo in message.html.erb.tt.
13
+
14
+ ## [0.10.0] - 2024-03-18
15
+ ### Added
9
16
  - Add lambda support for from, bcc, and reply_to campaign options (#233, @armiiller)
10
17
 
11
18
  ### Fixed
data/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  # Heya 👋
2
+
2
3
  ![Test](https://github.com/honeybadger-io/heya/workflows/Test/badge.svg)
3
4
  [![Gem Version](https://badge.fury.io/rb/heya.svg)](https://badge.fury.io/rb/heya)
4
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/a6416e63ffc426715857/maintainability)](https://codeclimate.com/github/honeybadger-io/heya/maintainability)
5
6
 
6
- Heya is a campaign mailer for Rails. Think of it like ActionMailer, but for timed email sequences. It can also perform other actions like sending a text message.
7
+ Heya is a campaign mailer for Rails. Think of it like ActionMailer, but for
8
+ timed email sequences. It can also perform other actions like sending a text
9
+ message.
7
10
 
8
11
  ## Getting started
12
+
9
13
  Getting started with Heya is easy:
10
14
 
11
15
  1. [Install the gem](#installing-the-heya-gem)
@@ -13,63 +17,73 @@ Getting started with Heya is easy:
13
17
  3. [Run the scheduler](#running-the-scheduler)
14
18
 
15
19
  ### Prerequisites
16
- Heya was built to work with PostgreSQL. Pull requests are welcome to support more databases.
20
+
21
+ Heya was built to work with PostgreSQL. Pull requests are welcome to support
22
+ more databases.
17
23
 
18
24
  ### Installing the Heya gem
25
+
19
26
  1. Add this line to your application's Gemfile:
20
27
 
21
- ```ruby
22
- gem "heya", github: "honeybadger-io/heya"
23
- ```
28
+ ```ruby
29
+ gem "heya", github: "honeybadger-io/heya"
30
+ ```
24
31
 
25
32
  2. Then execute:
26
33
 
27
- ```bash
28
- bundle install
29
- rails generate heya:install
30
- rails db:migrate
31
- ```
34
+ ```bash
35
+ bundle install
36
+ rails generate heya:install
37
+ rails db:migrate
38
+ ```
32
39
 
33
- This will:
40
+ This will:
34
41
 
35
- 1. Copy Heya's migration files to *db/migrate*
36
- 1. Copy Heya's default initializer to *config/initializers/heya.rb*
37
- 1. Create the file *app/campaigns/application_campaign.rb*
38
- 1. Run local migrations
42
+ 1. Copy Heya's migration files to _db/migrate_
43
+ 1. Copy Heya's default initializer to _config/initializers/heya.rb_
44
+ 1. Create the file _app/campaigns/application_campaign.rb_
45
+ 1. Run local migrations
39
46
 
40
- <details><summary>Note: Heya doesn't store a copy of your user data; instead, it reads from your existing <code>User</code> model (it never writes). If you have a different user model, change the <code>user_type</code> configuration option in <em>config/initializers/heya.rb</em>.</summary>
47
+ <details>
48
+ <summary>Note: Heya doesn't store a copy of your user data; instead, it
49
+ reads from your existing <code>User</code> model (it never writes). If you
50
+ have a different user model, change the <code>user_type</code> configuration
51
+ option in <em>config/initializers/heya.rb</em>.</summary>
41
52
 
42
53
  ```ruby
43
54
  # config/initializers/heya.rb
44
55
  Heya.configure do |config|
45
- config.user_type = "MyUser"
56
+ config.user_type = "MyUser"
46
57
  end
47
58
  ```
59
+
48
60
  </details>
49
61
 
50
62
  ### Creating your first campaign
63
+
51
64
  1. Create a campaign:
52
65
 
53
- ```bash
54
- rails generate heya:campaign Onboarding welcome:0
55
- ```
66
+ ```bash
67
+ rails generate heya:campaign Onboarding welcome:0
68
+ ```
56
69
 
57
70
  2. Add a user to your campaign:
58
71
 
59
- ```ruby
60
- OnboardingCampaign.add(user)
61
- ```
72
+ ```ruby
73
+ OnboardingCampaign.add(user)
74
+ ```
62
75
 
63
- Add the following to your `User` model to send them the campaign
64
- when they first signup:
76
+ Add the following to your `User` model to send them the campaign
77
+ when they first sign up:
65
78
 
66
- ```ruby
67
- after_create_commit do
68
- OnboardingCampaign.add(self)
69
- end
70
- ```
79
+ ```ruby
80
+ after_create_commit do
81
+ OnboardingCampaign.add(self)
82
+ end
83
+ ```
71
84
 
72
85
  ### Running the scheduler
86
+
73
87
  To start queuing emails, run the scheduler task periodically:
74
88
 
75
89
  ```bash
@@ -95,7 +109,9 @@ end
95
109
 
96
110
  ### Bonus: tips for working with email in Rails
97
111
 
98
- <details><summary>Use <a href="http://mailcatcher.me">MailCatcher</a> to see emails sent from your dev environment</summary>
112
+ <details>
113
+ <summary>Use <a href="http://mailcatcher.me">MailCatcher</a> to see
114
+ emails sent from your dev environment</summary>
99
115
 
100
116
  ```ruby
101
117
  # config/environments/development.rb
@@ -114,8 +130,11 @@ Rails.application.configure do
114
130
  config.action_mailer.smtp_settings = {host: "localhost", port: 1025}
115
131
  end
116
132
  ```
133
+
117
134
  </details>
118
- <details><summary>Use <a href="https://github.com/codetriage/maildown">Maildown</a> to write your emails in Markdown</summary>
135
+ <details>
136
+ <summary>Use <a href="https://github.com/codetriage/maildown">Maildown</a> to
137
+ write your emails in Markdown</summary>
119
138
 
120
139
  ```sh
121
140
  $ bundle add maildown
@@ -127,12 +146,16 @@ $ rails generate heya:campaign Onboarding welcome
127
146
 
128
147
  ☝️ Notice how only one template was generated; Maildown automatically builds
129
148
  the HTML and text variants from the markdown file.
149
+
130
150
  </details>
131
- <details><summary>Use <a href="https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails">ActionMailer::Preview</a> to preview emails as you write them</summary>
151
+ <details>
152
+ <summary>Use <a
153
+ href="https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails">ActionMailer::Preview</a>
154
+ to preview emails as you write them</summary>
132
155
 
133
156
  Heya's campaign generator generates previews for campaigns at
134
157
  `(test|spec)/mailers/previews/*_campaign_preview.rb`. To see them, open
135
- http://localhost:3000/rails/mailers/. If you didn't use the generator, you
158
+ <http://localhost:3000/rails/mailers/>. If you didn't use the generator, you
136
159
  can still build your own preview:
137
160
 
138
161
  ```ruby
@@ -150,12 +173,13 @@ class OnboardingCampaignPreview < ActionMailer::Preview
150
173
  end
151
174
 
152
175
  ```
176
+
153
177
  </details>
154
178
 
155
179
  ## Configuration
156
180
 
157
181
  You can use the following options to configure Heya (find this file in
158
- *config/initializers/heya.rb*):
182
+ _config/initializers/heya.rb_):
159
183
 
160
184
  ```ruby
161
185
  Heya.configure do |config|
@@ -179,7 +203,10 @@ end
179
203
  ## Campaigns
180
204
 
181
205
  ### Creating campaigns
182
- Heya stores campaigns in *app/campaigns/*, similar to how Rails stores mailers in *app/mailers/*. To create a campaign, run the following command inside your Rails project:
206
+
207
+ Heya stores campaigns in _app/campaigns/_, similar to how Rails stores mailers
208
+ in _app/mailers/_. To create a campaign, run the following command inside your
209
+ Rails project:
183
210
 
184
211
  ```bash
185
212
  rails generate heya:campaign Onboarding first second third
@@ -187,10 +214,10 @@ rails generate heya:campaign Onboarding first second third
187
214
 
188
215
  This will:
189
216
 
190
- 1. Create the file *app/campaigns/onboarding_campaign.rb*
191
- 1. Create the directory *app/views/heya/campaign_mailer/onboarding_campaign/*
192
- 1. Create email templates inside of *app/views/heya/campaign_mailer/onboarding_campaign/*
193
- 1. Create an ActionMailer preview at *(test|spec)/mailers/previews/onboarding_campaign_preview.rb*
217
+ 1. Create the file _app/campaigns/onboarding_campaign.rb_
218
+ 1. Create the directory _app/views/heya/campaign_mailer/onboarding_campaign/_
219
+ 1. Create email templates inside of _app/views/heya/campaign_mailer/onboarding_campaign/_
220
+ 1. Create an ActionMailer preview at _(test|spec)/mailers/previews/onboarding_campaign_preview.rb_
194
221
 
195
222
  Here's the campaign that the above command generates:
196
223
 
@@ -214,16 +241,26 @@ end
214
241
  ```
215
242
 
216
243
  #### Steps
217
- The `step` method defines a new step in the sequence. When you add a user to the campaign, Heya completes each step in the order that it appears.
218
244
 
219
- The default time to wait between steps is *two days*, calculated from the time the user completed the previous step (or the time the user entered the campaign, in the case of the first step).
245
+ The `step` method defines a new step in the sequence. When you add a user to the
246
+ campaign, Heya completes each step in the order that it appears.
220
247
 
221
- Each step has several options available (see the section [Creating messages](#creating-messages)).
248
+ The default time to wait between steps is _two days_, calculated from the time
249
+ the user completed the previous step (or the time the user entered the campaign,
250
+ in the case of the first step).
251
+
252
+ Each step has several options available (see the section [Creating
253
+ messages](#creating-messages)).
222
254
 
223
255
  ### Creating messages
224
- Messages are defined inside Heya campaigns using the `step` method. When you add a user to a campaign, Heya completes each step in the order that it appears.
225
256
 
226
- **The most important part of each step is its name, which must be unique to the campaign.** The step's name is how Heya tracks which user has received which message, so it's essential that you don't change it after the campaign is active (if you do, Heya will assume it's a new message).
257
+ Messages are defined inside Heya campaigns using the `step` method. When you add
258
+ a user to a campaign, Heya completes each step in the order that it appears.
259
+
260
+ **The most important part of each step is its name, which must be unique to the
261
+ campaign.** The step's name is how Heya tracks which user has received which
262
+ message, so it's essential that you don't change it after the campaign is active
263
+ (if you do, Heya will assume it's a new message).
227
264
 
228
265
  Here's an example of defining a message inside a campaign:
229
266
 
@@ -234,9 +271,12 @@ class OnboardingCampaign < ApplicationCampaign
234
271
  end
235
272
  ```
236
273
 
237
- In the above example, Heya will send a message named `:welcome` one day after a user enters the campaign, with the subject "Welcome to my app!"
274
+ In the above example, Heya will send a message named `:welcome` one day after a
275
+ user enters the campaign, with the subject "Welcome to my app!"
238
276
 
239
- The `wait` option tells Heya how long to wait before sending each message (the default is two days). There are a few scheduling options that you can customize for each step:
277
+ The `wait` option tells Heya how long to wait before sending each message (the
278
+ default is two days). There are a few scheduling options that you can customize
279
+ for each step:
240
280
 
241
281
  | Option Name | Default | Description |
242
282
  | :---------- | :-------------------------------- | :------------------------------------------------------- |
@@ -247,16 +287,18 @@ The `wait` option tells Heya how long to wait before sending each message (the d
247
287
 
248
288
  Heya uses the following additional options to build the message itself:
249
289
 
250
- | Option Name | Default | Description |
251
- |-------------|--------------|----------------------------|
252
- | `subject` | **required** | The email's subject |
253
- | `from` | Heya default | The sender's email address |
254
- | `layout` | Heya default | The email's layout file |
255
- | `to` | See below | The recipient's name & email address |
256
- | `bcc` | `nil` | BCC when sending emails |
290
+ | Option Name | Default | Description |
291
+ | ----------- | ------------ | -------------------------------------- |
292
+ | `subject` | **required** | The email's subject |
293
+ | `from` | Heya default | The sender's email address |
294
+ | `layout` | Heya default | The email's layout file |
295
+ | `to` | See below | The recipient's name & email address |
296
+ | `bcc` | `nil` | BCC when sending emails |
257
297
  | `headers` | `{}` | Headers to include when sending emails |
258
298
 
259
- You can change the default options using the `default` method at the top of the campaign. Heya applies default options to each step which doesn't supply its own:
299
+ You can change the default options using the `default` method at the top of the
300
+ campaign. Heya applies default options to each step which doesn't supply its
301
+ own:
260
302
 
261
303
  ```ruby
262
304
  class OnboardingCampaign < ApplicationCampaign
@@ -274,7 +316,8 @@ end
274
316
 
275
317
  #### Customizing the `to` field
276
318
 
277
- You can customize the `to` field by passing a callable object, which Heya will invoke with the user. For instance:
319
+ You can customize the `to` field by passing a callable object, which Heya will
320
+ invoke with the user. For instance:
278
321
 
279
322
  ```ruby
280
323
  class OnboardingCampaign < ApplicationCampaign
@@ -284,19 +327,23 @@ class OnboardingCampaign < ApplicationCampaign
284
327
  end
285
328
  ```
286
329
 
287
- It is recommended to rely on `ActionMailer::Base.email_address_with_name` so that sanitization is correctly applied.
330
+ It is recommended to rely on `ActionMailer::Base.email_address_with_name` so
331
+ that sanitization is correctly applied.
288
332
 
289
333
  If the `to` param is not provided, Heya will default to:
290
334
 
291
335
  1. `user#first_name`
292
336
  1. `user#name`
293
337
 
294
- If the `user` object doesn't respond to these methods, it will fallback to a simple `user.email` in the `to` field.
338
+ If the `user` object doesn't respond to these methods, it will fallback to a
339
+ simple `user.email` in the `to` field.
295
340
 
296
341
  #### Quality control option
297
342
 
298
- You may wish to apply quality control to individual steps of a campaign. For example, when adding a new step to an existing campaign it is
299
- a good idea to inspect real-time results in production. You can do this by using the `bcc:` step option, which would look like this:
343
+ You may wish to apply quality control to individual steps of a campaign. For
344
+ example, when adding a new step to an existing campaign it is a good idea to
345
+ inspect real-time results in production. You can do this by using the `bcc:`
346
+ step option, which would look like this:
300
347
 
301
348
  ```ruby
302
349
  class OnboardingCampaign < ApplicationCampaign
@@ -329,7 +376,9 @@ end
329
376
 
330
377
  #### Translations for email subjects (I18n)
331
378
 
332
- If you don't pass a `subject` to the `step` method, Heya will try to find it in your translations. The performed lookup will use the pattern `<campaign_scope>.<step_name>.subject` to construct the key.
379
+ If you don't pass a `subject` to the `step` method, Heya will try to find it in
380
+ your translations. The performed lookup will use the pattern
381
+ `<campaign_scope>.<step_name>.subject` to construct the key.
333
382
 
334
383
  ```ruby
335
384
  # app/campaigns/onboarding_campaign.rb
@@ -346,7 +395,8 @@ en:
346
395
  subject: "Heya!"
347
396
  ```
348
397
 
349
- To define parameters for interpolation, define a `#heya_attributes` method on your user model:
398
+ To define parameters for interpolation, define a `#heya_attributes` method on
399
+ your user model:
350
400
 
351
401
  ```ruby
352
402
  # app/models/user.rb
@@ -390,7 +440,9 @@ Step blocks receive two optional arguments: `user` and `step`, and are processed
390
440
  in a background job alongside other actions.
391
441
 
392
442
  ### Adding users to campaigns
393
- Heya leaves *when* to add users to campaigns completely up to you; here's how to add a user to a campaign from anywhere in your app:
443
+
444
+ Heya leaves _when_ to add users to campaigns completely up to you; here's how to
445
+ add a user to a campaign from anywhere in your app:
394
446
 
395
447
  ```ruby
396
448
  OnboardingCampaign.add(user)
@@ -402,24 +454,33 @@ To remove a user from a campaign:
402
454
  OnboardingCampaign.remove(user)
403
455
  ```
404
456
 
405
- Adding users to campaigns from Rails opens up some interesting automation possibilities--for instance, you can start or stop campaigns from `ActiveRecord` callbacks, or in response to other events that you're already tracking in your application. [See here for a list of ideas](#automation-ideas).
457
+ Adding users to campaigns from Rails opens up some interesting automation
458
+ possibilities--for instance, you can start or stop campaigns from `ActiveRecord`
459
+ callbacks, or in response to other events that you're already tracking in your
460
+ application. [See here for a list of ideas](#automation-ideas).
406
461
 
407
- Because Heya stacks campaigns by default (meaning it will never send more than one at a time), you can also queue up several campaigns for a user, and they'll receive them in order:
462
+ Because Heya stacks campaigns by default (meaning it will never send more than
463
+ one at a time), you can also queue up several campaigns for a user, and they'll
464
+ receive them in order:
408
465
 
409
466
  ```ruby
410
467
  WelcomeCampaign.add(user)
411
468
  OnboardingCampaign.add(user)
412
469
  EvergreenCampaign.add(user)
413
470
  ```
414
- *Note: you can customize the priority of campaigns via Heya's configuration.*
415
471
 
416
- If you want to send a user two campaigns simultaneously, you can do so with the `concurrent` option:
472
+ _Note: you can customize the priority of campaigns via Heya's configuration._
473
+
474
+ If you want to send a user two campaigns simultaneously, you can do so with the
475
+ `concurrent` option:
417
476
 
418
477
  ```ruby
419
478
  FlashSaleCampaign.add(user, concurrent: true)
420
479
  ```
421
480
 
422
- When you remove a user from a campaign and add them back later, they'll continue where they left off. If you want them to start over from the beginning, use the `restart` option:
481
+ When you remove a user from a campaign and add them back later, they'll continue
482
+ where they left off. If you want them to start over from the beginning, use the
483
+ `restart` option:
423
484
 
424
485
  ```ruby
425
486
  TrialConversionCampaign.add(user, restart: true)
@@ -427,7 +488,8 @@ TrialConversionCampaign.add(user, restart: true)
427
488
 
428
489
  #### Automation ideas
429
490
 
430
- Using `ActiveSupport::Notifications` to respond to lifecycle events (which could be sent from your Stripe controller, for instance):
491
+ Using `ActiveSupport::Notifications` to respond to lifecycle events (which could
492
+ be sent from your Stripe controller, for instance):
431
493
 
432
494
  ```ruby
433
495
  ActiveSupport::Notifications.subscribe("user.trial_will_end") do |*args|
@@ -452,7 +514,10 @@ end
452
514
  ```
453
515
 
454
516
  ### Customizing who gets what
455
- Heya can send individual messages to certain users using the `segment` option. The following campaign will send the message to inactive users--active users will be skipped:
517
+
518
+ Heya can send individual messages to certain users using the `segment` option.
519
+ The following campaign will send the message to inactive users--active users
520
+ will be skipped:
456
521
 
457
522
  ```ruby
458
523
  class ActivationCampaign < ApplicationCampaign
@@ -460,7 +525,8 @@ class ActivationCampaign < ApplicationCampaign
460
525
  end
461
526
  ```
462
527
 
463
- When you're checking the value of a single method on the user, the segment can be simplified to the symbol version:
528
+ When you're checking the value of a single method on the user, the segment can
529
+ be simplified to the symbol version:
464
530
 
465
531
  ```ruby
466
532
  class ActivationCampaign < ApplicationCampaign
@@ -469,7 +535,11 @@ end
469
535
  ```
470
536
 
471
537
  #### Segmenting specific campaigns
472
- You can also narrow entire campaigns to certain users using the `segment` method. For instance, if you have a campaign with a specific goal such as performing an action in your app, then you can send the campaign only to the users who haven't performed the action:
538
+
539
+ You can also narrow entire campaigns to certain users using the `segment`
540
+ method. For instance, if you have a campaign with a specific goal such as
541
+ performing an action in your app, then you can send the campaign only to the
542
+ users who haven't performed the action:
473
543
 
474
544
  ```ruby
475
545
  class UpgradeCampaign < ApplicationCampaign
@@ -481,9 +551,12 @@ class UpgradeCampaign < ApplicationCampaign
481
551
  end
482
552
  ```
483
553
 
484
- If they upgrade half way through the campaign, Heya will stop sending messages and remove them from the campaign.
554
+ If they upgrade half way through the campaign, Heya will stop sending messages
555
+ and remove them from the campaign.
485
556
 
486
- Likewise, you can require that users meet conditions to continue receiving a campaign. Here's a campaign which sends messages only to trial users--non-trial users will be removed from the campaign:
557
+ Likewise, you can require that users meet conditions to continue receiving a
558
+ campaign. Here's a campaign which sends messages only to trial users--non-trial
559
+ users will be removed from the campaign:
487
560
 
488
561
  ```ruby
489
562
  class TrialCampaign < ApplicationCampaign
@@ -496,6 +569,7 @@ end
496
569
  ```
497
570
 
498
571
  #### Segmenting all campaigns
572
+
499
573
  Heya campaigns inherit options from parent campaigns. For example, to make sure
500
574
  unsubscribed users never receive an email from Heya, create a `segment` in the
501
575
  `ApplicationCampaign`, and then have all other campaigns inherit from it:
@@ -527,72 +601,169 @@ See the
527
601
  [Rails documentation](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from)
528
602
  for additional details.
529
603
 
604
+ ### Extending campaign mailers
605
+
606
+ The campaign generator does not create a Mailer class for campaigns. In order to
607
+ enhance a campaign with a macro from another gem (such as for adding analytics),
608
+ you can do so by extending the `Heya::ApplicationMailer` class.
609
+
610
+ 1. Create a new file at `app/mailers/heya/application_mailer.rb`
611
+ 2. Add the following to it:
612
+
613
+ ```ruby
614
+ module Heya
615
+ class ApplicationMailer < ActionMailer::Base
616
+ macro_to_add_to_all_campaign_mailers
617
+ end
618
+ end
619
+ ```
620
+
621
+ For example, here's how to extended `Heya::ApplicationMailer` to include [Ahoy
622
+ Email's](https://github.com/ankane/ahoy_email)
623
+ [has_history](https://github.com/ankane/ahoy_email?tab=readme-ov-file#message-history)
624
+ and
625
+ [track_clicks](https://github.com/ankane/ahoy_email?tab=readme-ov-file#usage)
626
+ macros:
627
+
628
+ ```ruby
629
+ # app/mailers/heya/application_mailer.rb
630
+
631
+ module Heya
632
+ class ApplicationMailer < ActionMailer::Base
633
+ has_history
634
+
635
+ track_clicks campaign: -> {
636
+ params[:step].campaign.name
637
+ }
638
+ end
639
+ end
640
+ ```
641
+
642
+ This does two things:
643
+
644
+ 1. `has_history` enables history tracking for all Heya emails
645
+ 2. The `track_clicks` block appends the name of the campaign to all
646
+ (non-unsubscribe) links in an email so that each campaign can keep its data
647
+ separate from the other campaigns.
648
+
649
+ The result of this is that you can run a command like this in the console:
650
+
651
+ ```irb
652
+ AhoyEmail.stats "OnboardingCampaign"
653
+ ```
654
+
655
+ ...and receive a result:
656
+
657
+ ```irb
658
+ => {:sends=>1, :clicks=>2, :unique_clicks=>1, :ctr=>100.0}
659
+ ```
660
+
530
661
  ### Campaigns FAQ
662
+
531
663
  **What happens when:**
664
+
532
665
  <details><summary>I reorder messages in an active campaign?</summary>
533
666
 
534
- Heya sends the next *unsent* message *after the last message the user received*. When you move a message, the users who last received it will be moved with it, and continue from that point in the campaign. Heya skips messages which the user has already seen.
667
+ Heya sends the next _unsent_ message _after the last message the user received_.
668
+ When you move a message, the users who last received it will be moved with it,
669
+ and continue from that point in the campaign. Heya skips messages which the user
670
+ has already seen.
671
+
535
672
  </details>
536
673
 
537
674
  <details><summary>I add a message to an active campaign?</summary>
538
675
 
539
- Users who have already received a message *after* the new message will *not* receive the message.
676
+ Users who have already received a message _after_ the new message will _not_
677
+ receive the message.
678
+
540
679
  </details>
541
680
 
542
681
  <details><summary>I remove a message from an active campaign?</summary>
543
682
 
544
- Users who last received the message will be moved up to the previously received message, and continue from that point in the campaign. Heya skips messages which the user has already seen.
683
+ Users who last received the message will be moved up to the previously received
684
+ message, and continue from that point in the campaign. Heya skips messages which
685
+ the user has already seen.
686
+
545
687
  </details>
546
688
 
547
689
  <details><summary>I rename a message in an active campaign?</summary>
548
690
 
549
- **Renaming a message is equivalent to removing the message and adding a new one.** Users who are waiting to receive an earlier message in the campaign will receive the new message. Users who last received the old message will also receive the new one since it has replaced its position in the campaign.
691
+ **Renaming a message is equivalent to removing the message and adding a new
692
+ one.** Users who are waiting to receive an earlier message in the campaign will
693
+ receive the new message. Users who last received the old message will also
694
+ receive the new one since it has replaced its position in the campaign.
695
+
550
696
  </details>
551
697
 
552
698
  <details><summary>A user skips a message based on its conditions?</summary>
553
699
 
554
- Heya waits the defined wait time for every message in the campaign. If a user doesn't match the conditions, Heya skips it. If the *next* message's wait time is less than or equal to the skipped message's, it sends it immediately. If the next wait period is longer, it sends it after the new wait time has elapsed.
700
+ Heya waits the defined wait time for every message in the campaign. If a user
701
+ doesn't match the conditions, Heya skips it. If the _next_ message's wait time
702
+ is less than or equal to the skipped message's, it sends it immediately. If the
703
+ next wait period is longer, it sends it after the new wait time has elapsed.
704
+
555
705
  </details>
556
706
 
557
707
  <details><summary>I delete an active campaign?</summary>
558
708
 
559
- Heya will immediately stop sending the campaign; the campaign's data will remain until you manually delete it. If you restore the file before deleting the campaign's data, Heya will resume sending the campaign.
709
+ Heya will immediately stop sending the campaign; the campaign's data will remain
710
+ until you manually delete it. If you restore the file before deleting the
711
+ campaign's data, Heya will resume sending the campaign.
712
+
560
713
  </details>
561
714
 
562
715
  <details><summary>I add a user to multiple campaigns?</summary>
563
716
 
564
- By default, Heya sends each user one campaign at a time. It determines the order of campaigns using the campaign `priority`. When you add a user to a higher priority campaign, the new campaign will begin immediately. Once completed, the next highest priority campaign will resume sending.
717
+ By default, Heya sends each user one campaign at a time. It determines the order
718
+ of campaigns using the campaign `priority`. When you add a user to a higher
719
+ priority campaign, the new campaign will begin immediately. Once completed, the
720
+ next highest priority campaign will resume sending.
565
721
 
566
722
  To send a campaign concurrent to other active campaigns, use the `concurrent` option.
723
+
567
724
  </details>
568
725
 
569
726
  <details><summary>I add a user to a campaign they already completed?</summary>
570
727
 
571
- When you add a user to a campaign that they previously completed, Heya sends new messages which were added *to the end of the campaign*. Skipped messages will *not* be sent. To resend all messages, use the `restart` option.
728
+ When you add a user to a campaign that they previously completed, Heya sends new
729
+ messages which were added _to the end of the campaign_. Skipped messages will
730
+ _not_ be sent. To resend all messages, use the `restart` option.
731
+
572
732
  </details>
573
733
 
574
734
  **Less frequently asked questions:**
735
+
575
736
  <details><summary>Can the same message be delivered twice?</summary>
576
737
 
577
- Nope, not without restarting the campaign using the `restart` option (which will resend all the messages).
738
+ Nope, not without restarting the campaign using the `restart` option (which will
739
+ resend all the messages).
740
+
578
741
  </details>
579
742
 
580
743
  <details><summary>Can the same campaign be sent twice?</summary>
581
744
 
582
- Yep. When you add a user to a campaign that they previously completed, Heya sends new messages which were added *to the end of the campaign*. Skipped messages will *not* be sent. To resend all messages, use the `restart` option.
745
+ Yep. When you add a user to a campaign that they previously completed, Heya
746
+ sends new messages which were added _to the end of the campaign_. Skipped
747
+ messages will _not_ be sent. To resend all messages, use the `restart` option.
748
+
583
749
  </details>
584
750
 
585
751
  <details><summary>Can I resend a campaign to a user?</summary>
586
752
 
587
- Yep. Use the `restart` option to resend a campaign to a user (if they are already in the campaign, the campaign will start over from the beginning).
753
+ Yep. Use the `restart` option to resend a campaign to a user (if they are
754
+ already in the campaign, the campaign will start over from the beginning).
755
+
588
756
  </details>
589
757
 
590
758
  <details><summary>Can I send a user two campaigns at the same time?</summary>
591
759
 
592
- Yep. By default, Heya sends campaigns ain order of `priority`. Use the `concurrent` option to send campaigns concurrently.
760
+ Yep. By default, Heya sends campaigns ain order of `priority`. Use the
761
+ `concurrent` option to send campaigns concurrently.
762
+
593
763
  </details>
594
764
 
595
765
  ## Upgrading Heya
766
+
596
767
  Heya adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and
597
768
  should be considered **unstable** until version 1.0.0. Always check
598
769
  [CHANGELOG.md](./CHANGELOG.md) prior to upgrading (breaking changes will always
@@ -600,18 +771,21 @@ be called out there). Upgrade instructions for breaking changes are in
600
771
  [UPGRADING.md](./UPGRADING.md).
601
772
 
602
773
  ## Roadmap
774
+
603
775
  See [here](https://github.com/honeybadger-io/heya/projects/1) for things we're
604
776
  considering adding to Heya.
605
777
 
606
778
  ## Contributing
779
+
607
780
  1. Fork it.
608
781
  2. Create a topic branch `git checkout -b my_branch`
609
- 3. Make your changes and add an entry to [CHANGELOG.md](CHANGELOG.md).
782
+ 3. Make your changes and add an entry to [CHANGELOG.md](./CHANGELOG.md).
610
783
  4. Commit your changes `git commit -am "Boom"`
611
784
  5. Push to your branch `git push origin my_branch`
612
785
  6. Send a [pull request](https://github.com/honeybadger-io/heya/pulls)
613
786
 
614
787
  ## Releasing
788
+
615
789
  1. `gem install gem-release`
616
790
  2. `gem bump -v [version] -t -r`
617
791
  3. Update unreleased heading in [CHANGELOG.md](./CHANGELOG.md) (TODO: automate
@@ -619,4 +793,5 @@ considering adding to Heya.
619
793
  4. `git push origin main --tags`
620
794
 
621
795
  ## License
796
+
622
797
  Heya is licensed under the [LGPL](./LICENSE).
@@ -50,18 +50,9 @@ module Heya
50
50
  }
51
51
 
52
52
  scope :to_process, ->(now: Time.now, user: nil) {
53
- upcoming
54
- .where(<<~SQL, now: now.utc, user_type: user&.class&.base_class&.name, user_id: user&.id)
55
- ("heya_campaign_memberships".last_sent_at <= (TIMESTAMP :now - make_interval(secs := "heya_steps".wait)))
56
- AND (
57
- (:user_type IS NULL OR :user_id IS NULL)
58
- OR (
59
- "heya_campaign_memberships".user_type = :user_type
60
- AND
61
- "heya_campaign_memberships".user_id = :user_id
62
- )
63
- )
64
- SQL
53
+ query = upcoming.where('heya_campaign_memberships.last_sent_at <= (:now::timestamp - make_interval(secs := "heya_steps".wait))', now: now.utc)
54
+ query = query.where(user: user) if user
55
+ query
65
56
  }
66
57
 
67
58
  def self.migrate_next_step!
@@ -1 +1 @@
1
- This is the <%= @step.downcase %> messsage.
1
+ This is the <%= @step.downcase %> message.
@@ -6,8 +6,8 @@ module Heya
6
6
  module ActiveRecordRelationExtension
7
7
  TABLE_REGEXP = /heya_steps/
8
8
 
9
- def build_arel(aliases = nil)
10
- arel = super(aliases)
9
+ def build_arel(...) # forward all params. Handles differences between 7.1 -> 7.2
10
+ arel = super(...)
11
11
 
12
12
  if table_name == "heya_campaign_memberships" && arel.to_sql =~ TABLE_REGEXP
13
13
  # https://www.postgresql.org/docs/9.4/queries-values.html
data/lib/heya/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Heya
4
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heya
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Wood
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-18 00:00:00.000000000 Z
11
+ date: 2024-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails