I have tried execute_controller, but get error about missing bg_exec method (it were there!)
Now I building fully managed through API app – ant that including some in-call processing. API might request to "cancel" any active command (invoked Controller) and execute next one.
Below is POC controller that works. I just unjoin calls or originate them or split dial - and sending both of them there to controller Loop with following command 'join_command'
Everything works, bot for example pin command blocking one call leg and I can't interrupt it anytime, have to wait
Screenshot:
Controller:
class Loop < Adhearsion::CallController
attr_accessor :audio, :request, :valid_pin
LOOP_TIMEOUT = 1
def run
# just set metadata and @variables
set_call_data
# instant loop
while call.active?
# API could populate command to the CallRegistry, if it there, process it!
request = CallRegistry.request.pop call.id if request
# update metadata based on API request (say it's Redis store or like that)
update_call_data
command = request.delete(:command)
# stop any audio if playing - prior executing received command
play_stop!
execute_command command, request
else
sleep LOOP_TIMEOUT
end
end
end
# execute any dynamic command through eval
def execute_command(command, request)
begin
@script_name = command.to_s.gsub(/[^0-9a-z]/i, '').downcase
@request = request
eval "#{@script_name}_command"
rescue NameError => e
logger.info "#{self.class} unknown command #{@script_name}_command (#{command})" rescue => e
logger.error "#{self.class} error #{e} #{e.backtrace}"
end
end
def safe(&blk)
begin
yield blk
rescue Adhearsion::Call::Hangup
# nothing to do
rescue => e
logger.error "#{self.class}.#{@script_name}_command error: #{e}: #{e.backtrace}"
end
end
def play_start!(audio_file)
@audio = play! audio_file rescue nil
end
def play_stop!
@audio.stop! rescue nil
end
#################################################################################################################
def join_command
safe do
call.join request.target_call_id
end
end
#################################################################################################################
def unjoin_command
safe do
if request.target_call_id
call.unjoin request.target_call_id
else
call.unjoin
end
end
end
#################################################################################################################
def musiconhold_command
play_start! t(:moh, locale: 'en')
end
#################################################################################################################
def pinlogin_command
safe do
call.unjoin call_data.agent_call_id
CallRegistry.request.push call_data.agent_call_id, command: 'musiconhold'
request_pin
CallRegistry.request.push call.id, command: 'join', target_call_id: call_data.agent_call_id
end
end
def request_pin
call_data.language = get_variable('language') || 'en'
prompt = [t(:login_prompt, locale: call_data.language)]
1.upto(PIN_ATTEMPTS) do |attempt_no|
pin = ask_pin(prompt)
# ...
end
end