Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
H

heya

> 编程语言
Open source

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 mess

765 stars0 likes2 views
WebsiteGitHub

About

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 mess

Heya

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.

Getting started

Getting started with Heya is easy:

  1. Install the gem
  2. Create a campaign
  3. Run the scheduler

Prerequisites

Heya was built to work with PostgreSQL. Pull requests are welcome to support more databases.

Installing the Heya gem

  1. Add this line to your application's Gemfile:

    gem "heya", github: "honeybadger-io/heya"
    
  2. Then execute:

    bundle install
    rails generate heya:install
    rails db:migrate
    

This will:

  1. Copy Heya's migration files to db/migrate
  2. Copy Heya's default initializer to config/initializers/heya.rb
  3. Create the file app/campaigns/application_campaign.rb
  4. Run local migrations

Note: Heya doesn't store a copy of your user data; instead, it reads from your existing User model (it never writes). If you have a different user model, change the user_type configuration option in config/initializers/heya.rb.

# config/initializers/heya.rb
Heya.configure do |config|
config.user_type = "MyUser"
end

Creating your first campaign

  1. Create a campaign:

    rails generate heya:campaign Onboarding welcome:0
    
  2. Add a user to your campaign:

    OnboardingCampaign.add(user)
    

Add the following to your User model to send them the campaign when they first sign up:

after_create_commit do
  OnboardingCampaign.add(self)
end

Running the scheduler

To start queuing emails, run the scheduler task periodically:

rails heya:scheduler

Heya uses ActiveJob to send emails in the background. Make sure your ActiveJob backend is configured to process the heya queue. For example, here's how you might start Sidekiq:

bundle exec sidekiq -q default -q heya

You can change Heya's default queue using the queue option:

# app/campaigns/application_campaign.rb
class ApplicationCampaign 
Use MailCatcher to see
  emails sent from your dev environment

```ruby
# config/environments/development.rb
Rails.application.configure do
  # ..

  # Use MailCatcher to inspect emails
  # http://mailcatcher.me
  # Usage:
  #   gem install mailcatcher
  #   mailcatcher
  #   # => Starting MailCatcher
  #   # => ==> smtp://127.0.0.1:1025
  #   # => ==> http://127.0.0.1:1080
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {host: "localhost", port: 1025}
end

Use Maildown to write your emails in Markdown

$ bundle add maildown
$ rails generate heya:campaign Onboarding welcome
      create  app/campaigns/application_campaign.rb
      create  app/campaigns/onboarding_campaign.rb
      create  app/views/heya/campaign_mailer/onboarding_campaign/welcome.md.erb

☝️ Notice how only one template was generated; Maildown automatically builds the HTML and text variants from the markdown file.

Use ActionMailer::Preview to preview emails as you write them

Heya's campaign generator generates previews for campaigns at (test|spec)/mailers/previews/*_campaign_preview.rb. To see them, open . If you didn't use the generator, you can still build your own preview:

# test/mailers/previews/onboarding_campaign_preview.rb
class OnboardingCampaignPreview 

## Configuration

You can use the following options to configure Heya (find this file in
_config/initializers/heya.rb_):

```ruby
Heya.configure do |config|
  # The name of the model you want to use with Heya.
  config.user_type = "User"

  # The default options to use when processing campaign steps.
  config.campaigns.default_options = {from: "[email protected]"}

  # Campaign priority. When a user is added to multiple campaigns, they are
  # sent in this order. Campaigns are sent in the order that the users were
  # added if no priority is configured.
  config.campaigns.priority = [
    "FirstCampaign",
    "SecondCampaign",
    "ThirdCampaign"
  ]
end

Campaigns

Creating campaigns

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:

rails generate heya:campaign Onboarding first second third

This will:

  1. Create the file app/campaigns/onboarding_campaign.rb
  2. Create the directory app/views/heya/campaign_mailer/onboarding_campaign/
  3. Create email templates inside of app/views/heya/campaign_mailer/onboarding_campaign/
  4. Create an ActionMailer preview at (test|spec)/mailers/previews/onboarding_campaign_preview.rb

Here's the campaign that the above command generates:

# app/campaigns/application_campaign.rb
class ApplicationCampaign  (user) { ActionMailer::Base.email_address_with_name(user.email, user.nickname) }
end

It is recommended to rely on ActionMailer::Base.email_address_with_name so that sanitization is correctly applied.

If the to param is not provided, Heya will default to:

  1. user#first_name
  2. user#name

If the user object doesn't respond to these methods, it will fallback to a simple user.email in the to field.

Quality control option

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 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:

class OnboardingCampaign (user) { "Heya #{user.first_name}!" }
end

Translations for email subjects (I18n)

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 ..subject to construct the key.

# app/campaigns/onboarding_campaign.rb
class OnboardingCampaign (user) { user.inactive? }
end

When you're checking the value of a single method on the user, the segment can be simplified to the symbol version:

class ActivationCampaign  {
      params[:step].campaign.name
    }
  end
end

This does two things:

  1. has_history enables history tracking for all Heya emails
  2. The track_clicks block appends the name of the campaign to all (non-unsubscribe) links in an email so that each campaign can keep its data separate from the other campaigns.

The result of this is that you can run a command like this in the console:

AhoyEmail.stats "OnboardingCampaign"

...and receive a result:

=> {:sends=>1, :clicks=>2, :unique_clicks=>1, :ctr=>100.0}

Campaigns FAQ

What happens when:

I reorder messages in an active campaign?

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.

I add a message to an active campaign?

Users who have already received a message after the new message will not receive the message.

I remove a message from an active campaign?

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.

I rename a message in an active campaign?

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.

A user skips a message based on its conditions?

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.

I delete an active campaign?

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.

I add a user to multiple campaigns?

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.

To send a campaign concurrent to other active campaigns, use the concurrent option.

I add a user to a campaign they already completed?

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.

I override or combine segment(s)?

When you add a segment to a step in a campaign that also has one or more campaign segments, the message will be sent only when all segments match (return true).

Less frequently asked questions:

Can the same message be delivered twice?

Nope, not without restarting the campaign using the restart option (which will resend all the messages).

Can the same campaign be sent twice?

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.

Can I resend a campaign to a user?

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).

Can I send a user two campaigns at the same time?

Yep. By default, Heya sends campaigns ain order of priority. Use the concurrent option to send campaigns concurrently.

Upgrading Heya

Heya adheres to Semantic Versioning, and should be considered unstable until version 1.0.0. Always check CHANGELOG.md prior to upgrading (breaking changes will always be called out there). Upgrade instructions for breaking changes are in UPGRADING.md.

Roadmap

See here for things we're considering adding to Heya.

Contributing

  1. Fork it.
  2. Create a topic branch git checkout -b my_branch
  3. Make your changes and add an entry to CHANGELOG.md.
  4. Commit your changes git commit -am "Boom"
  5. Push to your branch git push origin my_branch
  6. Send a pull request

Releasing

  1. gem install gem-release
  2. gem bump -v [version] -t -r
  3. Update unreleased heading in CHANGELOG.md (TODO: automate this in gem-release command)
  4. git push origin main --tags

License

Heya is licensed under the LGPL.

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言