Created
December 11, 2012 19:06
-
-
Save JeffKatzy/4261123 to your computer and use it in GitHub Desktop.
call model for call center gem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Call < ActiveRecord::Base | |
include CallCenter | |
belongs_to :user | |
attr_accessible :to, :from, :called, :caller | |
attr_accessible :account_sid, :call_sid, :call_status, :digits | |
call_flow :state, :initial => :initial do | |
state :initial do | |
event :incoming_call, :to => :greeting | |
end | |
state :greeting do | |
# TODO if user has a current question id, transition to play_question | |
# TODO else transition to play_lecture | |
event :greeted, :to => :advance_user | |
event :no_classroom, :to => :gather_classroom_number | |
response do |x| | |
if user.classroom_id == nil | |
x.Say "It looks like you are not assigned to a classroom. Let's take | |
care of that now." | |
x.Redirect flow_url(:no_classroom) | |
else | |
x.Say "Welcome back! Let's get back to your classes." | |
x.Redirect flow_url(:greeted) | |
end | |
end | |
end | |
state :gather_classroom_number do | |
event :received_number, :to => :evaluate_classroom_number | |
response do |x| | |
x.Gather :numDigits => '3', :action => flow_url(:received_number) do | |
x.Say "Please enter the 3 digit classroom number given by your teacher. | |
If you do not know this number, press 999 to move on." | |
end | |
end | |
end | |
state :evaluate_classroom_number do | |
event :no_number, :to => :advance_user | |
event :correct_number, :to => :advance_user | |
event :wrong_number, :to => :gather_classroom_number | |
response do |x| | |
if digits == '999' | |
x.Say "Ok, we'll move on." | |
x.Redirect flow_url(:no_number) | |
elsif user.assign_classroom == nil | |
x.Say "Looks like you entered the wrong classroom number. | |
Let's try it again." | |
x.Redirect flow_url(:wrong_number) | |
else | |
user.assign_classroom | |
user.save | |
x.Say "Great you are now in the classroom #{user.classroom.name} which is taught by #{user.classroom.teacher.name}" | |
x.Redirect flow_url(:correct_number) | |
end | |
end | |
end | |
state :determine_current_segment do | |
event :going_to_lecture, :to => :play_lecture | |
event :going_to_question, :to => :play_question | |
response do |x| | |
# x.Say "Determining current segment." | |
if user.on_lecture? | |
#x.Say "Going to lecture #{user.lecture.id}" | |
x.Redirect flow_url(:going_to_lecture) | |
else | |
# x.Say "Going to question #{user.question.id}" | |
x.Redirect flow_url(:going_to_question) | |
end | |
end | |
end | |
state :play_lecture do | |
event :lecture_finished, :to => :repeat_or_advance | |
response do |x| | |
x.Gather :numDigits => '1', :action => flow_url(:lecture_finished) do | |
x.Play user.lecture.soundfile.url | |
user_lecture = user.user_lectures.build(:lecture_id => user.lecture.id) | |
user_lecture.save | |
end | |
#x.Play "http://com.twilio.music.classical.s3.amazonaws.com/Mellotroniac_-_Flight_Of_Young_Hearts_Flute.mp3", | |
#HOLD_MUSIC.sort_by { rand }.each do |url| | |
# x.Play url | |
#end | |
end | |
end | |
# In this state, we should have access to digits | |
state :repeat_or_advance do | |
event :request_repeat, :to => :determine_current_segment | |
event :request_advance, :to => :advance_user | |
response do |x| | |
#x.Say "You pressed #{digits}." | |
if digits == "1" | |
x.Say "Ok, we'll repeat this for you." | |
x.Redirect flow_url(:request_repeat) | |
else | |
x.Redirect flow_url(:request_advance) | |
end | |
end | |
end | |
state :play_question do | |
event :submit_answer, :to => :check_if_correct | |
response do |x| | |
x.Gather :numDigits => '1', :action => flow_url(:submit_answer) do | |
x.Play user.question.soundfile.url | |
end | |
end | |
end | |
state :check_if_correct do | |
event :answer_correct, :to => :advance_user | |
event :answer_incorrect, :to => :question_explanation | |
response do |x| | |
x.Say "You pressed #{digits}." | |
answer = user.user_answers.build(question_id: user.question.id, value: digits, user_lecture_id: user.user_lectures.last.id) | |
answer.assert_correct | |
answer.save | |
if digits == user.question.answer.to_s #you will need to write a function that checks if its correct or not | |
x.Say "Great, that's right. Now we'll move onto the next question." | |
x.Redirect flow_url(:answer_correct) #then send to next question, perhaps by | |
#first writing a state that changes current question to the next question. Then resend to current question. | |
else | |
x.Redirect flow_url(:answer_incorrect) | |
end | |
end | |
end | |
state :question_explanation do | |
event :explanation_end, :to => :advance_user | |
response do |x| | |
x.Play user.question.explanationfile.url | |
x.Redirect flow_url(:explanation_end) | |
end | |
end | |
state :advance_user do | |
event :advancing_user, :to => :determine_current_segment | |
response do |x| | |
user.advance | |
user.save #don't know why this is not working | |
# x.Say "We have advanced you to the next part." | |
x.Redirect flow_url(:advancing_user) | |
end | |
end | |
#write logic for | |
#if question is correct, and | |
# if there is another question, | |
# go to the next question | |
# if there is not another question | |
# go to congrats, | |
#and do you want to go to another lecture | |
# if question is incorrect, play explanation | |
# then play next question | |
# end | |
state :ended do | |
after(:success) do | |
update_attributes(:ended_at => Time.now) | |
#user.update_attributes(:lecture_id => user.lecture.id, :question_id => user.question.id) | |
end | |
end | |
state any do | |
event :hang_up, :to => :ended | |
end | |
end | |
# =============== | |
# = Call Center = | |
# =============== | |
def run(event) | |
send(event) | |
render | |
end | |
def flow_url(event) | |
params = { | |
:call_id => self.id, | |
:event => event.to_s | |
} | |
uri = URI.join(ENV['TWILIO_TUNNEL_URL'], "calls/flow") | |
uri.query = params.to_query | |
uri.to_s | |
end | |
def redirect_to(event, *args) | |
account.calls.get(self.call_sid).update({:url => flow_url(event)}) | |
end | |
def wait_time | |
Time.now - (self.waiting_at || self.created_at) | |
end | |
# ======== | |
# = REST = | |
# ======== | |
def account | |
client.account | |
end | |
def client | |
self.class.client | |
end | |
def self.client | |
@client ||= Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'] | |
end | |
# =========== | |
# = Routing = | |
# =========== | |
MAX_WAIT_TIME = 60 | |
HOLD_MUSIC = [ | |
"http://com.twilio.music.classical.s3.amazonaws.com/ith_chopin-15-2.mp3", | |
"http://com.twilio.music.classical.s3.amazonaws.com/oldDog_-_endless_goodbye_%28instr.%29.mp3", | |
"http://com.twilio.music.classical.s3.amazonaws.com/ClockworkWaltz.mp3", | |
"http://com.twilio.music.classical.s3.amazonaws.com/BusyStrings.mp3", | |
"http://com.twilio.music.classical.s3.amazonaws.com/ith_brahms-116-4.mp3" | |
].freeze | |
serialize :conference_history, Array | |
def can_connect?(call) | |
!conference_history.include?(call.from) | |
end | |
def call_conference_name(call) | |
[self.call_sid, call.call_sid].sort.join('::') | |
end | |
def connect(call) | |
self.conference_name = call_conference_name(call) | |
Rails.logger.info "Creating conference: #{self.conference_name}" | |
self.conference_history << call.from | |
self.save! | |
self.redirect_and_put_in_conference! | |
end | |
def location | |
if caller_states = Carmen::states(self.caller_country) | |
title_and_abbreviation = caller_states.detect { |title, abbr| abbr == self.caller_state } | |
if title_and_abbreviation | |
return "Someone in #{self.caller_city.capitalize}, #{title_and_abbreviation.first}" | |
end | |
end | |
"Someone in #{self.caller_city.capitalize}, #{self.caller_state}" | |
rescue Carmen::StatesNotSupported, Carmen::NonexistentCountry | |
"An Unknown Caller" | |
end | |
def as_json(options = {}) | |
{ | |
:location => location, | |
:conference_name => conference_name | |
} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment