heya 0.0.1 → 0.4.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/LICENSE +661 -0
  4. data/README.md +573 -0
  5. data/Rakefile +14 -14
  6. data/app/mailers/heya/application_mailer.rb +0 -2
  7. data/app/mailers/heya/campaign_mailer.rb +52 -0
  8. data/app/models/heya/campaign_membership.rb +90 -0
  9. data/app/models/heya/campaign_receipt.rb +5 -0
  10. data/app/views/layouts/heya/campaign_mailer.html.erb +20 -0
  11. data/app/views/layouts/heya/campaign_mailer.text.erb +1 -0
  12. data/lib/generators/heya/campaign/USAGE +14 -0
  13. data/lib/generators/heya/campaign/campaign_generator.rb +69 -0
  14. data/lib/generators/heya/campaign/templates/campaign.rb.tt +4 -0
  15. data/lib/generators/heya/campaign/templates/message.html.erb.tt +1 -0
  16. data/lib/generators/heya/campaign/templates/message.md.erb.tt +1 -0
  17. data/lib/generators/heya/campaign/templates/message.text.erb.tt +1 -0
  18. data/lib/generators/heya/campaign/templates/preview.rb.tt +12 -0
  19. data/lib/generators/heya/install/USAGE +10 -0
  20. data/lib/generators/heya/install/install_generator.rb +24 -0
  21. data/lib/generators/heya/install/templates/application_campaign.rb.tt +3 -0
  22. data/lib/generators/heya/install/templates/initializer.rb.tt +16 -0
  23. data/lib/generators/heya/install/templates/migration.rb.tt +29 -0
  24. data/lib/heya.rb +45 -1
  25. data/lib/heya/active_record_extension.rb +37 -0
  26. data/lib/heya/campaigns/action.rb +27 -0
  27. data/lib/heya/campaigns/actions/block.rb +24 -0
  28. data/lib/heya/campaigns/actions/email.rb +24 -0
  29. data/lib/heya/campaigns/base.rb +154 -0
  30. data/lib/heya/campaigns/queries.rb +35 -0
  31. data/lib/heya/campaigns/scheduler.rb +50 -0
  32. data/lib/heya/campaigns/step.rb +35 -0
  33. data/lib/heya/campaigns/step_action_job.rb +34 -0
  34. data/lib/heya/config.rb +17 -0
  35. data/lib/heya/engine.rb +14 -0
  36. data/lib/heya/version.rb +3 -1
  37. data/lib/tasks/heya_tasks.rake +8 -4
  38. metadata +64 -11
data/README.md ADDED
@@ -0,0 +1,573 @@
1
+ # Heya 👋
2
+ ![Test](https://github.com/honeybadger-io/heya/workflows/Test/badge.svg)
3
+ [![Gem Version](https://badge.fury.io/rb/heya.svg)](https://badge.fury.io/rb/heya)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/a6416e63ffc426715857/maintainability)](https://codeclimate.com/github/honeybadger-io/heya/maintainability)
5
+
6
+ [![Twitter Follow](https://img.shields.io/twitter/follow/heyjoshwood?label=Follow%20Josh%20for%20dev%20updates&style=social)](https://mobile.twitter.com/heyjoshwood)
7
+
8
+ 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.
9
+
10
+ ## Getting started
11
+ Getting started with Heya is easy:
12
+
13
+ 1. [Install the gem](#installing-the-heya-gem)
14
+ 2. [Create a campaign](#creating-your-first-campaign)
15
+ 3. [Run the scheduler](#running-the-scheduler)
16
+
17
+ ### Installing the Heya gem
18
+ 1. Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem "heya", github: "honeybadger-io/heya"
22
+ ```
23
+
24
+ 2. Then execute:
25
+
26
+ ```bash
27
+ bundle install
28
+ rails generate heya:install
29
+ rails db:migrate
30
+ ```
31
+
32
+ This will:
33
+
34
+ 1. Copy Heya's migration files to *db/migrate*
35
+ 1. Copy Heya's default initializer to *config/initializers/heya.rb*
36
+ 1. Create the file *app/campaigns/application_campaign.rb*
37
+ 1. Run local migrations
38
+
39
+ <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>
40
+
41
+ ```ruby
42
+ # config/initializers/heya.rb
43
+ Heya.configure do |config|
44
+ config.user_type = "MyUser"
45
+ end
46
+ ```
47
+ </details>
48
+
49
+ ### Creating your first campaign
50
+ 1. Create a campaign:
51
+
52
+ ```bash
53
+ rails generate heya:campaign Onboarding welcome:0
54
+ ```
55
+
56
+ 2. Add a user to your campaign:
57
+
58
+ ```ruby
59
+ OnboardingCampaign.add(user)
60
+ ```
61
+
62
+ Add the following to your `User` model to send them the campaign
63
+ when they first signup:
64
+
65
+ ```ruby
66
+ after_create_commit do
67
+ OnboardingCampaign.add(self)
68
+ end
69
+ ```
70
+
71
+ ### Running the scheduler
72
+ To start queuing emails, run the scheduler task periodically:
73
+
74
+ ```bash
75
+ rails heya:scheduler
76
+ ```
77
+
78
+ Heya uses ActiveJob to send emails in the background. Make sure your
79
+ ActiveJob backend is configured to process the `heya` queue. For example,
80
+ here's how you might start Sidekiq:
81
+
82
+ ```sh
83
+ bundle exec sidekiq -q default -q heya
84
+ ```
85
+
86
+ You can change Heya's default queue using the `queue` option:
87
+
88
+ ```ruby
89
+ # app/campaigns/application_campaign.rb
90
+ class ApplicationCampaign < Heya::Campaigns::Base
91
+ default queue: "custom"
92
+ end
93
+ ```
94
+
95
+ ### Bonus: tips for working with email in Rails
96
+
97
+ <details><summary>Use <a href="http://mailcatcher.me">MailCatcher</a> to see emails sent from your dev environment</summary>
98
+
99
+ ```ruby
100
+ # config/environments/development.rb
101
+ Rails.application.configure do
102
+ # ..
103
+
104
+ # Use MailCatcher to inspect emails
105
+ # http://mailcatcher.me
106
+ # Usage:
107
+ # gem install mailcatcher
108
+ # mailcatcher
109
+ # # => Starting MailCatcher
110
+ # # => ==> smtp://127.0.0.1:1025
111
+ # # => ==> http://127.0.0.1:1080
112
+ config.action_mailer.delivery_method = :smtp
113
+ config.action_mailer.smtp_settings = {host: "localhost", port: 1025}
114
+ end
115
+ ```
116
+ </details>
117
+ <details><summary>Use <a href="https://github.com/codetriage/maildown">Maildown</a> to write your emails in Markdown</summary>
118
+
119
+ ```sh
120
+ $ bundle add maildown
121
+ $ rails generate heya:campaign Onboarding welcome
122
+ create app/campaigns/application_campaign.rb
123
+ create app/campaigns/onboarding_campaign.rb
124
+ create app/views/heya/campaign_mailer/onboarding_campaign/welcome.md.erb
125
+ ```
126
+
127
+ ☝️ Notice how only one template was generated; Maildown automatically builds
128
+ the HTML and text variants from the markdown file.
129
+ </details>
130
+ <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>
131
+
132
+ Heya's campaign generator generates previews for campaigns at
133
+ `(test|spec)/mailers/previews/*_campaign_preview.rb`. To see them, open
134
+ http://localhost:3000/rails/mailers/. If you didn't use the generator, you
135
+ can still build your own preview:
136
+
137
+ ```ruby
138
+ # test/mailers/previews/onboarding_campaign_preview.rb
139
+ class OnboardingCampaignPreview < ActionMailer::Preview
140
+ def welcome
141
+ OnboardingCampaign.welcome(user)
142
+ end
143
+
144
+ private
145
+
146
+ def user
147
+ User.where(id: params[:user_id]).first || User.first
148
+ end
149
+ end
150
+
151
+ ```
152
+ </details>
153
+
154
+ ## Configuration
155
+
156
+ You can use the following options to configure Heya (find this file in
157
+ *config/initializers/heya.rb*):
158
+
159
+ ```ruby
160
+ Heya.configure do |config|
161
+ # The name of the model you want to use with Heya.
162
+ config.user_type = "User"
163
+
164
+ # The default options to use when processing campaign steps.
165
+ config.campaigns.default_options = {from: "user@example.com"}
166
+
167
+ # Campaign priority. When a user is added to multiple campaigns, they are
168
+ # sent in this order. Campaigns are sent in the order that the users were
169
+ # added if no priority is configured.
170
+ config.campaigns.priority = [
171
+ "FirstCampaign",
172
+ "SecondCampaign",
173
+ "ThirdCampaign"
174
+ ]
175
+ end
176
+ ```
177
+
178
+ ## Campaigns
179
+
180
+ ### Creating campaigns
181
+ 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:
182
+
183
+ ```bash
184
+ rails generate heya:campaign Onboarding first second third
185
+ ```
186
+
187
+ This will:
188
+
189
+ 1. Create the file *app/campaigns/onboarding_campaign.rb*
190
+ 1. Create the directory *app/views/heya/campaign_mailer/onboarding_campaign/*
191
+ 1. Create email templates inside of *app/views/heya/campaign_mailer/onboarding_campaign/*
192
+ 1. Create an ActionMailer preview at *(test|spec)/mailers/previews/onboarding_campaign_preview.rb*
193
+
194
+ Here's the campaign that the above command generates:
195
+
196
+ ```ruby
197
+ # app/campaigns/application_campaign.rb
198
+ class ApplicationCampaign < Heya::Campaigns::Base
199
+ default from: "from@example.com"
200
+ end
201
+
202
+ # app/campaigns/onboarding_campaign.rb
203
+ class OnboardingCampaign < ApplicationCampaign
204
+ step :first,
205
+ subject: "First subject"
206
+
207
+ step :second,
208
+ subject: "Second subject"
209
+
210
+ step :third,
211
+ subject: "Third subject"
212
+ end
213
+ ```
214
+
215
+ #### Steps
216
+ 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.
217
+
218
+ 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).
219
+
220
+ Each step has several options available (see the section [Creating messages](#creating-messages)).
221
+
222
+ ### Creating messages
223
+ 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.
224
+
225
+ **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).
226
+
227
+ Here's an example of defining a message inside a campaign:
228
+
229
+ ```ruby
230
+ class OnboardingCampaign < ApplicationCampaign
231
+ step :welcome, wait: 1.day,
232
+ subject: "Welcome to my app!"
233
+ end
234
+ ```
235
+
236
+ 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!"
237
+
238
+ 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:
239
+
240
+ | Option Name | Default | Description |
241
+ | :---------- | :-------------------------------- | :------------------------------------------------------- |
242
+ | `wait` | `2.days` | The duration of time to wait before sending each message |
243
+ | `segment` | `nil` | The segment who should receive the message |
244
+ | `action` | `Heya::Campaigns::Actions::Email` | The action to perform (usually sending an email) |
245
+ | `queue` | `"heya"` | The ActiveJob queue |
246
+
247
+ Heya uses the following additional options to build the message itself:
248
+
249
+ | Option Name | Default | Description |
250
+ | :---------- | :----------- | :------------------------- |
251
+ | `subject` | **required** | The email's subject |
252
+ | `from` | Heya default | The sender's email address |
253
+
254
+ 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:
255
+
256
+ ```ruby
257
+ class OnboardingCampaign < ApplicationCampaign
258
+ default wait: 1.day,
259
+ queue: "onboarding",
260
+ from: "support@example.com"
261
+
262
+ # Will still be sent after one day from the
263
+ # email address support@example.com
264
+ step :welcome,
265
+ subject: "Welcome to my app!"
266
+ end
267
+ ```
268
+
269
+ #### Customizing email subjects for each user
270
+
271
+ The subject can be customized for each user by using a `lambda` instead of a `String`:
272
+
273
+ ```ruby
274
+ # app/campaigns/onboarding_campaign.rb
275
+ class OnboardingCampaign < ApplicationCampaign
276
+ step :welcome,
277
+ subject: ->(user) { "Heya #{user.first_name}!" }
278
+ end
279
+ ```
280
+
281
+ #### Translations for email subjects (I18n)
282
+
283
+ 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.
284
+
285
+ ```ruby
286
+ # app/campaigns/onboarding_campaign.rb
287
+ class OnboardingCampaign < ApplicationCampaign
288
+ step :welcome
289
+ end
290
+ ```
291
+
292
+ ```yaml
293
+ # config/locales/en.yml
294
+ en:
295
+ onboarding_campaign:
296
+ welcome:
297
+ subject: "Heya!"
298
+ ```
299
+
300
+ To define parameters for interpolation, define a `#heya_attributes` method on your user model:
301
+
302
+ ```ruby
303
+ # app/models/user.rb
304
+ class User < ApplicationRecord
305
+ def heya_attributes
306
+ {
307
+ first_name: name.split(" ").first
308
+ }
309
+ end
310
+ end
311
+ ```
312
+
313
+ ```yaml
314
+ # config/locales/en.yml
315
+ en:
316
+ onboarding_campaign:
317
+ welcome:
318
+ subject: "Heya %{first_name}!"
319
+ ```
320
+
321
+ ### Custom Actions
322
+
323
+ You can override the default step behavior to perform custom actions by passing
324
+ a block to the `step` method:
325
+
326
+ ```ruby
327
+ class OnboardingCampaign < ApplicationCampaign
328
+ step :first_email,
329
+ subject: "You're about to receive a txt"
330
+
331
+ step :sms do |user|
332
+ SMS.new(to: user.cell, body: "Hi, #{user.first_name}!").deliver
333
+ end
334
+
335
+ step :second_email,
336
+ subject: "Did you get it?"
337
+ end
338
+ ```
339
+
340
+ Step blocks receive two optional arguments: `user` and `step`, and are processed
341
+ in a background job alongside other actions.
342
+
343
+ ### Adding users to campaigns
344
+ 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:
345
+
346
+ ```ruby
347
+ OnboardingCampaign.add(user)
348
+ ```
349
+
350
+ To remove a user from a campaign:
351
+
352
+ ```ruby
353
+ OnboardingCampaign.remove(user)
354
+ ```
355
+
356
+ 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).
357
+
358
+ 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:
359
+
360
+ ```ruby
361
+ WelcomeCampaign.add(user)
362
+ OnboardingCampaign.add(user)
363
+ EvergreenCampaign.add(user)
364
+ ```
365
+ *Note: you can customize the priority of campaigns via Heya's configuration.*
366
+
367
+ If you want to send a user two campaigns simultaneously, you can do so with the `concurrent` option:
368
+
369
+ ```ruby
370
+ FlashSaleCampaign.add(user, concurrent: true)
371
+ ```
372
+
373
+ 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:
374
+
375
+ ```ruby
376
+ TrialConversionCampaign.add(user, restart: true)
377
+ ```
378
+
379
+ #### Automation ideas
380
+
381
+ Using `ActiveSupport::Notifications` to respond to lifecycle events (which could be sent from your Stripe controller, for instance):
382
+
383
+ ```ruby
384
+ ActiveSupport::Notifications.subscribe("user.trial_will_end") do |*args|
385
+ event = ActiveSupport::Notifications::Event.new(*args)
386
+ if event.payload[:user_id]
387
+ user = User.find(event.payload[:user_id])
388
+ TrialConversionCampaign.add(user, restart: true)
389
+ end
390
+ end
391
+ ```
392
+
393
+ Scheduling campaigns in `ActiveRecord` callbacks:
394
+
395
+ ```ruby
396
+ class User < ApplicationRecord
397
+ after_create_commit do
398
+ WelcomeCampaign.add(self)
399
+ OnboardingCampaign.add(self)
400
+ EvergreenCampaign.add(user)
401
+ end
402
+ end
403
+ ```
404
+
405
+ ### Customizing who gets what
406
+ 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:
407
+
408
+ ```ruby
409
+ class ActivationCampaign < ApplicationCampaign
410
+ step :activate, segment: ->(user) { user.inactive? }
411
+ end
412
+ ```
413
+
414
+ When you're checking the value of a single method on the user, the segment can be simplified to the symbol version:
415
+
416
+ ```ruby
417
+ class ActivationCampaign < ApplicationCampaign
418
+ step :activate, segment: :inactive?
419
+ end
420
+ ```
421
+
422
+ #### Segmenting specific campaigns
423
+ 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:
424
+
425
+ ```ruby
426
+ class UpgradeCampaign < ApplicationCampaign
427
+ segment { |u| !u.upgraded? }
428
+
429
+ step :one
430
+ step :two
431
+ step :three
432
+ end
433
+ ```
434
+
435
+ If they upgrade half way through the campaign, Heya will stop sending messages and remove them from the campaign.
436
+
437
+ 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:
438
+
439
+ ```ruby
440
+ class TrialCampaign < ApplicationCampaign
441
+ segment :trial?
442
+
443
+ step :one
444
+ step :two
445
+ step :three
446
+ end
447
+ ```
448
+
449
+ #### Segmenting all campaigns
450
+ Heya campaigns inherit options from parent campaigns. For example, to make sure
451
+ unsubscribed users never receive an email from Heya, create a `segment` in the
452
+ `ApplicationCampaign`, and then have all other campaigns inherit from it:
453
+
454
+ ```ruby
455
+ class ApplicationCampaign < Heya::Campaigns::Base
456
+ segment :subscribed?
457
+ end
458
+ ```
459
+
460
+ ### Handling exceptions
461
+
462
+ Heya campaigns are [rescuable](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html).
463
+ Use the `rescue_from` method to handle exceptions in campaigns:
464
+
465
+ ```ruby
466
+ class OnboardingCampaign < ApplicationCampaign
467
+ rescue_from Postmark::InactiveRecipientError, with: :log_error
468
+
469
+ private
470
+
471
+ def log_error(error)
472
+ Rails.logger.error("Got Heya error: #{error}")
473
+ end
474
+ end
475
+ ```
476
+
477
+ See the
478
+ [Rails documentation](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from)
479
+ for additional details.
480
+
481
+ ### Campaigns FAQ
482
+ **What happens when:**
483
+ <details><summary>I reorder messages in an active campaign?</summary>
484
+
485
+ 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.
486
+ </details>
487
+
488
+ <details><summary>I add a message to an active campaign?</summary>
489
+
490
+ Users who have already received a message *after* the new message will *not* receive the message.
491
+ </details>
492
+
493
+ <details><summary>I remove a message from an active campaign?</summary>
494
+
495
+ 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.
496
+ </details>
497
+
498
+ <details><summary>I rename a message in an active campaign?</summary>
499
+
500
+ **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.
501
+ </details>
502
+
503
+ <details><summary>A user skips a message based on its conditions?</summary>
504
+
505
+ 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.
506
+ </details>
507
+
508
+ <details><summary>I delete an active campaign?</summary>
509
+
510
+ 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.
511
+ </details>
512
+
513
+ <details><summary>I add a user to multiple campaigns?</summary>
514
+
515
+ 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.
516
+
517
+ To send a campaign concurrent to other active campaigns, use the `concurrent` option.
518
+ </details>
519
+
520
+ <details><summary>I add a user to a campaign they already completed?</summary>
521
+
522
+ 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.
523
+ </details>
524
+
525
+ **Less frequently asked questions:**
526
+ <details><summary>Can the same message be delivered twice?</summary>
527
+
528
+ Nope, not without restarting the campaign using the `restart` option (which will resend all the messages).
529
+ </details>
530
+
531
+ <details><summary>Can the same campaign be sent twice?</summary>
532
+
533
+ 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.
534
+ </details>
535
+
536
+ <details><summary>Can I resend a campaign to a user?</summary>
537
+
538
+ 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).
539
+ </details>
540
+
541
+ <details><summary>Can I send a user two campaigns at the same time?</summary>
542
+
543
+ Yep. By default, Heya sends campaigns ain order of `priority`. Use the `concurrent` option to send campaigns concurrently.
544
+ </details>
545
+
546
+ ## Upgrading Heya
547
+ Heya adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and
548
+ should be considered **unstable** until version 1.0.0. Always check
549
+ [CHANGELOG.md](./CHANGELOG.md) prior to upgrading (breaking changes will always
550
+ be called out there). Upgrade instructions for breaking changes are in
551
+ [UPGRADING.md](./UPGRADING.md).
552
+
553
+ ## Roadmap
554
+ See [here](https://github.com/honeybadger-io/heya/projects/1) for things we're
555
+ considering adding to Heya.
556
+
557
+ ## Contributing
558
+ 1. Fork it.
559
+ 2. Create a topic branch `git checkout -b my_branch`
560
+ 3. Make your changes and add an entry to [CHANGELOG.md](CHANGELOG.md).
561
+ 4. Commit your changes `git commit -am "Boom"`
562
+ 5. Push to your branch `git push origin my_branch`
563
+ 6. Send a [pull request](https://github.com/honeybadger-io/heya/pulls)
564
+
565
+ ## Releasing
566
+ 1. `gem install gem-release`
567
+ 2. `gem bump -v [version] -t -r`
568
+ 3. Update unreleased heading in [CHANGELOG.md](./CHANGELOG.md) (TODO: automate
569
+ this in gem-release command)
570
+ 4. `git push origin master --tags`
571
+
572
+ ## License
573
+ Heya is licensed under the [AGPL](./LICENSE).