heya 0.10.0 → 0.11.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/CHANGELOG.md +7 -0
- data/README.md +262 -87
- data/app/models/heya/campaign_membership.rb +3 -12
- data/lib/generators/heya/campaign/templates/message.html.erb.tt +1 -1
- data/lib/heya/active_record_extension.rb +2 -2
- data/lib/heya/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c3a56453c65b17eaa7dcc3489bacd9dcdb78da9f134e18e0fa7d3cc818de11
|
4
|
+
data.tar.gz: cd6eb4a27002ebb62307cd44007960cc39637f7ab6b3129d5800061e1bf762c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|

|
3
4
|
[](https://badge.fury.io/rb/heya)
|
4
5
|
[](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
|
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
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
28
|
+
```ruby
|
29
|
+
gem "heya", github: "honeybadger-io/heya"
|
30
|
+
```
|
24
31
|
|
25
32
|
2. Then execute:
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
34
|
+
```bash
|
35
|
+
bundle install
|
36
|
+
rails generate heya:install
|
37
|
+
rails db:migrate
|
38
|
+
```
|
32
39
|
|
33
|
-
|
40
|
+
This will:
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
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
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
72
|
+
```ruby
|
73
|
+
OnboardingCampaign.add(user)
|
74
|
+
```
|
62
75
|
|
63
|
-
|
64
|
-
|
76
|
+
Add the following to your `User` model to send them the campaign
|
77
|
+
when they first sign up:
|
65
78
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
191
|
-
1. Create the directory
|
192
|
-
1. Create email templates inside of
|
193
|
-
1. Create an ActionMailer preview at
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
299
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
55
|
-
|
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 %>
|
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(
|
10
|
-
arel = super(
|
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
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.
|
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-
|
11
|
+
date: 2024-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|