{"id":13877907,"url":"https://github.com/tarr11/dripper","last_synced_at":"2025-07-16T13:32:51.799Z","repository":{"id":6243335,"uuid":"55174125","full_name":"tarr11/dripper","owner":"tarr11","description":"An opinionated rails drip email engine that depends on ActiveRecord and ActionMailer","archived":false,"fork":false,"pushed_at":"2023-01-25T05:15:53.000Z","size":80,"stargazers_count":32,"open_issues_count":14,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-30T22:37:16.347Z","etag":null,"topics":["actionmailer","drip","drip-campaign","rails"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tarr11.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-31T18:36:44.000Z","updated_at":"2024-05-22T13:58:38.000Z","dependencies_parsed_at":"2023-02-14T04:55:12.419Z","dependency_job_id":null,"html_url":"https://github.com/tarr11/dripper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarr11%2Fdripper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarr11%2Fdripper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarr11%2Fdripper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarr11%2Fdripper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tarr11","download_url":"https://codeload.github.com/tarr11/dripper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226134226,"owners_count":17578778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actionmailer","drip","drip-campaign","rails"],"created_at":"2024-08-06T08:01:34.585Z","updated_at":"2024-11-24T06:31:38.366Z","avatar_url":"https://github.com/tarr11.png","language":"Ruby","readme":"# Dripper\n[![Build Status](https://travis-ci.org/tarr11/dripper.svg?branch=master)](https://travis-ci.org/tarr11/dripper)\n\nDRY up your mailer code with a rules-based drip campaign system that works natively with rails and ActionMailer.\n\n## Benefits:\n * Remove mailer state logic from your controllers\n * Rely on active record scopes \n * Build sophisticated DRIP campaigns in a DRY fashion\n\n## Why:\nI needed a DRIP email service, and as both developer and marketer, I wanted to build something that works easily with rails.  Most DRIP SAAS products are too expensive for websites where visitors don't pay.  I love sites like intercom, but they don't make sense unless are generating revenue.  \n\n## Philosophy\nClean up your email messaging code by creating a rails model for each message. So, instead of trying to navigate through your user to an order, chat, message, or whatever, you just put the rules on the chat, order and message.  \n\n## Get Started\n\n### Step 1: Add to your gemfile and then `bundle install`\n```\ngem 'dripper_mail'\n```\n\n### Step 2: Install Migrations\n```\nrake dripper:install:migrations\nrake db:migrate\n```\n\n### Step 3: Add a simple configuration file\n``` config/initializers/dripper.rb\n  Dripper.config model: :users do\n    # send a welcome message when a user is created\n    dripper mailer: :welcome_mailer, action: :welcome\n  end\n```\n\n### Step 4: Include dripper in your models so emails get sent automatically\n```\nclass Newsletter \u003c ActiveRecord::Base\n  include Dripper::Drippable\n  belongs_to :user\nend\n```\n\nThis example expects you to have a mailer method that looks like this:\n```\nclass UserMailer \u003c ApplicationMailer\n  def newsletter(newsletter)\n    mail to: \"to@example.org\"\n  end\nend\n```\n\n### Step 5: Go! \nSimply create a new model and insert it into your database.  your Mail code will get called automatically. \n```\nrails c\nNewsletter.create(user: User.first, subject: \"Hello!\")\n```\n\n\n## Use Scopes to limit who this gets sent to\n``` config/initializers/dripper.rb\n\n  dripper model: :orders do\n    # send a successful order message\n    dripper mailer: :order_mailer, action: :new_order, scope: -\u003e { paid }\n  end\n```\n\n## Use wait or wait_until to delay messages (see deliver_later on activemailer for details on wait/wait_until syntax)\nUse a proc for wait_until so that it gets evaluated at the correct time.\n```\n dripper model: :users do\n    dripper mailer: :welcome_mailer, action: :welcome, scope: -\u003e { new_user }, wait_until: -\u003e {  Date.tomorrow.noon }\n    dripper mailer: :welcome_mailer, action: :welcome, scope: -\u003e { new_user }, wait: -\u003e {  1.hours }\n end\n```\n\n## Marketing / DRIP Stuff\nDrip messages are designed to get people to take specific actions based on their lifecycle\n\n### Step 1/2/3\nIn this case, we want to sent 3 messages, on day 1,3 and 7.  We only want to send the last message if they haven't subscribed.  \n\nNote that we can nest options (mailer, scope, model, etc) which makes the code cleaner\n\n```\nclass User\n  scope :day_count, -\u003e(day_count) {where(\"created_at \u003c ?\", DateTime.now - day_count.days) }\n  scope :no_customer, -\u003e {where.not(:id =\u003e Subscription.select(:user_id).uniq) }\n  scope :customer, -\u003e {joins(:subscriptions).where(\"subscriptions.is_active = true\") }\nend\n\ndripper model: :users, scope: -\u003e { confirmed } do\n  dripper mailer: :onboarding do\n    dripper action: :day1, scope: -\u003e { day_count(1)  }\n    dripper action: :day3, scope: -\u003e { day_count(3) } \n    dripper action: :day7_no_customer,  scope: -\u003e { day_count(7).merge(-\u003e { no_customer } ) } \n    dripper action: :day7_customer,  scope: -\u003e { day_count(7).merge(-\u003e { customer } ) } \n  end\nend\n```\n\n### User Confirmation\nThis could potentially replace devise's awful mess :)\n```\ndripper model: :users do\n  dripper mailer: :user_mailer, action: :confirmation, scope: -\u003e { unconfirmed }\nend\n```\n\n### Change Password\nThis will send a password changed email if the password has been changed in the last 30 minutes\n```\ndripper model: :users do\n  dripper mailer: :user_mailer, action: :change_password, scope: -\u003e { password_changed(30.minutes.ago) }\nend\n```\n\n### Inactive User\n```\n# define inactive scope\nclass User \n  scope :inactive, -\u003e { where(\"last_session_at \u003c ?\", DateTime.today - 1.months) }\nend\n\n# dripper code uses scope\ndripper model: :users do\n  dripper mailer: :user_mailer, action: :inactive, scope: :inactive, -\u003e { inactive }\nend\n```\n\nNotice in this case, we will only send 1 inactive message, ever.  Also this one would require a rake task , as the user would not be triggering it (since they are inactive)  Alternatively you could have a rake task that sets inactive_at.\n\nIf you want to send more than one, you should create a new model that corresponds to the mailer.  Run a rake task that populates this model.  \n\nThis may sounds like a pain, but things will be cleaner and you will be able to control what gets sent when.   You'll also get the benefit of seeing your inactive users in a nice queryable format.\n\nHere's how that would look:\n\n### Inactive User every few months\n```\nclass InactiveUser\n  # user_id, :integer\n  # inactive_at :datetime\n  \n   belongs_to :user\nend\n\ndripper :inactive_users do\n  dripper :inactive_mailer, -\u003e {:inactive}\nend\n```\n\n### Transactional Message\nThis will send a new email on every chat\n```\ndripper :chat_message do\n  dripper :chat_mailer, :new_chat\nend\n```\n\n### Weekly Digest message\nSimilarly, in this case, if we want to send a weekly digest, we should have a weekly digest AR model that gets populated by a rake task.\n\n```\nclass WeeklyDigest\n  belongs_to :user\n  # week_start_on, week_end_on\n  # other stuff\n  \n  def self.create_weekly_digest(start_on)\n    User.all.each do |u|\n      u.weekly_digests.create week_start_on: start_on, week_end_on: start_on + 1.weeks\n    end\n  end\nend\n\ndripper model: :weekly_digest do\n  dripper mailer: :digest_mailer, action: :weekly_digest \nend\n```\n\n## Rake Task \nNOTE: this doesn't work yet...\n\n```\n# runs all open drippers\nrake dripper:run\n```\n\n\n\n## Details\n\n* We will only send one message per this key [:id, :mailer, :action]\n* By default, we will only send to NEW records (so that you don't spam your entire list on your first deploy)\n* Use scopes to control if a message gets sent\n* Create new models for transactional emails\n\n\nThis project rocks and uses MIT-LICENSE.\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarr11%2Fdripper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarr11%2Fdripper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarr11%2Fdripper/lists"}