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 +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
|
![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
|
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
|