Skip to content

Instantly share code, notes, and snippets.

@peterkeen
Last active August 29, 2015 13:59
Show Gist options
  • Save peterkeen/10987800 to your computer and use it in GitHub Desktop.
Save peterkeen/10987800 to your computer and use it in GitHub Desktop.
Email courses as state machines.

This is a first draft of an idea I had in the shower this morning.

Email courses (aka sequences of email autoresponders) can be trivially modeled as finite state machines. Each state is the last email they were sent (or queued to receive) and each transition queues an email to be sent.

This example implementation builds on top of AASM for the state machine and ActsAsTaggableOn to keep track of states. In a production-ready implementation, likely the state machine implementation would be wrapped in a DSL that streamlines the process a little more.

class Member < ActiveRecord::Base
acts_as_taggable
end
class SomeEmailCourse
include AASM
aasm do
state :new, :initial => true
state :first
state :second
state :third
event :start do
transitions from: :new, to :first
after do
send_email('first', Time.now)
end
end
event :received_first do
transitions from: :first, to: :second
after do
send_email('second', 2.days.from_now)
end
end
event :received_second do
transitions from: :second, to: :third
after do
send_email('third', 2.days_from_now)
end
end
end
def initialize(member)
@member = member
end
def aasm_state=(new_state)
current_state = aasm_state
@member.tag_list.remove("SomeEmailCourse:#{current_state}")
@member.tag_list.add("SomeEmailCourse:#{new_state}")
end
def aasm_state
@member.tag_list.detect { |t| t.starts_with?('SomeEmailCourse') }.gsub('SomeEmailCourse:', '')
end
def send_email(email_name, send_at)
MailWorker.perform_at(send_at, @member.id, email_name)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment