Created
March 6, 2014 20:24
-
-
Save neerajnagi/9398891 to your computer and use it in GitHub Desktop.
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
# encoding: utf-8 | |
require_relative '../media/aws.rb' | |
require 'mechanize' | |
require 'json' | |
require 'redis' | |
require 'openssl' | |
GET_COMPANY_ID = "#{API_URL}/api/export_companies?number=" | |
GET_COMPANY_AGENTS = "#{API_URL}/api/export_agents?company=" | |
GET_ALL_AGENTS = "#{API_URL}/api/export_agents" | |
POST_CALL_RECORDING = "#{API_URL}/api/update_calls" | |
POST_VOICEMAIL_RECORDING = "#{API_URL}/api/create_voicemail" | |
LETMECALLU_RECORDING_BUCKET = "https://s3-us-west-2.amazonaws.com/letmecallu-recordings/" | |
$redis = Redis.new | |
class ConfirmationController < Adhearsion::CallController | |
def run | |
begin | |
redis = Redis.new | |
logger.info "metadata passed on -> #{metadata}" | |
logger.info "========= notification ========\n dial_result , answered \n ===============================" | |
redis.publish "notification" , JSON.pretty_generate({from:metadata[:from] , to:metadata[:to] , event:{name:"dial_result", data:"answer"} }) | |
record async: true do |event| | |
aws = Aws.new | |
browser = Mechanize.new | |
browser.agent.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
browser.keep_alive = false | |
logger.info "Async recording for call id #{metadata[:sip_call_id]} saved to #{event.recording.uri}" | |
`#{SOX} #{event.recording.uri.gsub(/^.*usr/,'/usr')} -c 1 -b 16 -t .wav -r 16000 #{event.recording.uri.gsub(/^.*usr/,'/usr').gsub(/\.wav$/,'_mono.wav')}` | |
aws.push_recording("#{metadata[:sip_call_id]}.wav" , "#{event.recording.uri.gsub(/^.*usr/,'/usr').gsub(/\.wav$/,'_mono.wav')}") | |
logger.info "posted data to update_call" + browser.post(POST_CALL_RECORDING,{"call_id"=> metadata[:sip_call_id] ,"file_path"=>LETMECALLU_RECORDING_BUCKET+metadata[:sip_call_id]+".wav" }).content | |
end | |
rescue Exception => e | |
end | |
end | |
end | |
class Incomming < Adhearsion::CallController | |
@from_username = "" | |
@to_username = '' | |
def run | |
begin | |
answer | |
#call metadata calculation | |
from_number = '' | |
to_number = '' | |
company_id = '' | |
from_username = "" | |
to_username = '' | |
origin_ip = call.variables["x_variable_sip_received_ip"]||'_blank' | |
to_number = call.to.gsub(/\@.*$/,'').gsub(/^[^:]*\:/,'') | |
domain = call.from.gsub(/^[^@]*\@/,'') | |
from_number = call.from.gsub(/^[^:]*\:|\@.*$/,'') | |
sip_agent = call.variables[:x_variable_sip_user_agent]||'Vox' | |
sip_call_id = call.id.to_s | |
route = call.variables[:x_route] | |
logger.info "call metadata is #{call.variables.inspect}" | |
logger.info "#{from_number} -------------------------------> #{to_number}" | |
@from_username = from_username = from_number | |
@to_username = to_username = to_number | |
logger.info "sip agent is --------------- #{sip_agent}" | |
#company metadata calculation | |
begin | |
aws = Aws.new | |
browser = Mechanize.new | |
browser.agent.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
rescue Exception => e | |
end | |
#first segregate call treatment based on sip agent , one category is calls from sipML5 and second is everything else | |
# if( (INCOMING_PROVIDERS.include? sip_agent[0,6]) || from_number == 'neerajnagi' ) | |
if route=="PUBLIC"||from_number =="neerajnagi" | |
company_details = get_available_agents(to_number) | |
available_agents = company_details[:available_agents] | |
$company_id = company_details[:company_id] | |
company_metadata = company_details[:company_metadata] | |
logger.info "************************************************ #{$company_id} ********" | |
#play_audio "silence_stream://10000" | |
logger.info "company_id result is #{($company_id!="" && !$company_id.nil?)}" | |
if ($company_id!="" && !$company_id.nil?) | |
if Dir["/var/punchblock/prompts/#{$company_id}*" ].length > 0 | |
play Dir["/var/punchblock/prompts/#{$company_id}*" ].grep /.*general.*/ | |
end | |
end | |
# play "/var/punchblock/system/connecting.mp3" | |
#moh = play! "/var/punchblock/system/moh.wav" | |
#handle the scenario where there is no one to handle request | |
if available_agents.length ==0 | |
# begin | |
# moh.stop! | |
# rescue Exception => e Exception=>e | |
# end | |
play "/var/punchblock/system/leave_message.mp3" | |
play "/var/punchblock/system/beep.mp3" | |
voicemail_start_time = Time.now.to_i | |
event = record max_duration:120000, interruptible:true | |
voicemail_end_time = Time.now.to_i | |
logger.info "voicemail recording for call id #{sip_call_id} saved to #{event.recording.uri}" | |
begin | |
aws.push_recording("#{sip_call_id}.wav" , event.recording.uri.gsub(/^.*usr/,'/usr')) | |
logger.info "voicemail saved to #{LETMECALLU_RECORDING_BUCKET+sip_call_id+".wav"}" | |
logger.info "recording data posted to update_call" + browser.post(POST_VOICEMAIL_RECORDING,{call_id: sip_call_id ,company_id:$company_id, from:from_number, to:to_number, recording_url:LETMECALLU_RECORDING_BUCKET+sip_call_id+".wav" , start_timestamp:voicemail_start_time, end_timestamp:voicemail_end_time }).content | |
rescue Exception => e | |
end | |
hangup | |
else | |
for i in 1..2 do | |
agent_decision = who_serves_this_time(company_metadata, available_agents, to_number) | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:agent_decision[:dest_username] ,event:{name:"dial"} } ) | |
rescue Exception => e | |
end | |
dial_status = dial agent_decision[:dest] , from: from_number , confirm:ConfirmationController , confirm_metadata:{sip_call_id:sip_call_id , from:from_username, to:agent_decision[:dest_username]} , for: company_metadata['companies'][0]['preference']['redirect_after'].to_i , ringback:"/var/punchblock/system/moh.wav" | |
logger.info "))))))))))))))))))))))))))))) last dial attempt resulted in #{dial_status.result}" | |
if dial_status.result != :answer | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:agent_decision[:dest_username] , event:{name:"dial_result", data:dial_status.result.to_s}}) | |
rescue Exception => e | |
end | |
if i==2 | |
begin | |
moh.stop! | |
rescue Exception => e | |
end | |
play "/var/punchblock/system/leave_message.mp3" | |
play "/var/punchblock/system/beep.mp3" | |
voicemail_start_time = Time.now.to_i | |
event = record max_duration:120000 | |
voicemail_end_time = Time.now.to_i | |
logger.info "Async recording for call id #{sip_call_id} saved to #{event.recording.uri}" | |
begin | |
aws.push_recording("#{sip_call_id}.wav" , event.recording.uri.gsub(/^.*usr/,'/usr')) | |
logger.info "voicemail saved to #{LETMECALLU_RECORDING_BUCKET+sip_call_id+".wav"}" | |
logger.info "recording data posted to update_call" + browser.post(POST_VOICEMAIL_RECORDING,{call_id: sip_call_id ,company_id:$company_id, from:from_number, to:to_number, recording_url:LETMECALLU_RECORDING_BUCKET+sip_call_id+".wav" , start_timestamp:voicemail_start_time, end_timestamp:voicemail_end_time }).content | |
rescue Exception => e | |
end | |
end | |
else | |
break | |
end | |
end | |
hangup | |
end | |
#outbound section | |
else | |
logger.info "call from #{sip_agent} agent" | |
logger.info "original called id is #{from_number}" | |
begin | |
all_agents = JSON.parse(browser.get(GET_ALL_AGENTS).body)['agents']||[] | |
all_agents.each do |agent| | |
if agent['email'] == from_number.gsub(/_at_/i, '@') | |
logger.info "agent metadata is #{agent.inspect}" | |
if agent['caller_id'] | |
from_number = agent['caller_id'].gsub(/[ ]*/,'') | |
else | |
from_number = from_number.gsub(/_at_/i, '@') | |
end | |
end | |
end | |
rescue Exception => e | |
end | |
logger.info "updated caller id is #{from_number}" | |
answer | |
# ringback = play! "/var/punchblock/system/ringback.wav" | |
to = to_number | |
if( !to.match(/^00.*$/).nil? ) | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username ,event:{name:"dial"} } ) | |
rescue Exception => e | |
end | |
dial_status = dial "sofia/external/#{OUTGOING_PROVIDER_PREFIX}#{to.strip.gsub(/^00/,'')}@#{OUTGOING_PROVIDER}" , from: from_number, confirm:ConfirmationController , confirm_metadata:{from:from_username, to:to_username , sip_call_id:sip_call_id } , ringback:"/var/punchblock/system/ringback.wav" | |
if dial_status.result != :answer | |
logger.info "====== notification ======\n dial_result \n =============================\n" | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username , event:{name:"dial_result", data:dial_status.result.to_s}}) | |
rescue Exception => e | |
end | |
end | |
hangup | |
elsif ( !to.match(/^\+.*$/).nil? ) | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username ,event:{name:"dial"} } ) | |
rescue Exception => e | |
end | |
dial_status = dial "sofia/external/#{OUTGOING_PROVIDER_PREFIX}#{to.strip.gsub(/^\+/,'')}@#{OUTGOING_PROVIDER}" , from: from_number , confirm:ConfirmationController , confirm_metadata:{ sip_call_id:sip_call_id , from:from_username, to:to_username} , ringback:"/var/punchblock/system/ringback.wav" | |
if dial_status.result != :answer | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username , event:{name:"dial_result", data:dial_status.result.to_s}}) | |
rescue Exception => e | |
end | |
end | |
hangup | |
else | |
logger.info "#{FS_CLI} -x \"sofia_contact #{call.to.gsub(/\:.*/,'')}\"" | |
sip_uri = `#{FS_CLI} -x \"sofia_contact #{call.to.gsub(/\:.*/,'')}\"`.strip | |
logger.info "attempting dial to #{sip_uri}" | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username ,event:{name:"dial"} } ) | |
rescue Exception => e | |
end | |
dial_status = dial "{hangup_after_bridge=false}#{sip_uri}" , from: from_number , confirm:ConfirmationController , confirm_metadata:{ sip_call_id:sip_call_id , from:from_username, to:to_username} , ringback:"/var/punchblock/system/ringback.wav" | |
if dial_status.result != :answer | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:from_username, to:to_username , event:{name:"dial_result", data:dial_status.result.to_s}}) | |
rescue Exception => e | |
end | |
end | |
logger.info "dial_status is #{dial_status.inspect }" | |
hangup | |
end | |
end | |
end | |
end | |
def who_serves_this_time(company_metadata, available_agents, to_number) | |
case (company_metadata['companies'][0]['call_distribution']) | |
when 'roundrobin' | |
dest='' | |
dest_username='' | |
available_agents = available_agents.sort_by { |hsh| hsh[:sip_user] }.reverse | |
logger.info "available agents in alphabetical order are -----> #{available_agents}" | |
begin | |
who_served_last_time = $redis.get(to_number) | |
rescue Exception => e | |
end | |
who_serves_this_time = {} | |
if who_served_last_time.nil? | |
who_serves_this_time = available_agents[0] | |
begin | |
$redis.set(to_number, who_serves_this_time['sip_user']) | |
rescue Exception => e | |
end | |
else | |
indx=0 | |
available_agents.each do | a_agent | | |
logger.info "+++++ #{who_served_last_time} #{a_agent['sip_user']}" | |
if (a_agent['sip_user'].to_s == who_served_last_time.to_s) | |
logger.info "match found" | |
if indx < (available_agents.length-1) | |
indx = indx+1 | |
elsif indx==available_agents.length-1 | |
indx = 0 | |
end | |
break | |
end | |
indx = indx+1 | |
end | |
if indx==available_agents.length | |
indx=0 | |
end | |
logger.info "agent with index #{indx} from available agents will server" | |
who_serves_this_time = available_agents[indx] | |
begin | |
$redis.set(to_number, who_serves_this_time['sip_user']) | |
rescue Exception => e | |
end | |
end | |
logger.info "who serves this time ------------------> #{who_serves_this_time}" | |
if !(who_serves_this_time['forward_calls'] ) #&& (who_serves_this_time['status']=="offline")) | |
dest = `#{FS_CLI} -x "sofia_contact #{who_serves_this_time['sip_user']}"`.strip | |
dest_username = who_serves_this_time['sip_user'] | |
else | |
dest = "sofia/external/#{OUTGOING_PROVIDER_PREFIX}#{who_serves_this_time['phone'].gsub(/^\+|^00/,'')}@#{OUTGOING_PROVIDER}" | |
dest_username = who_serves_this_time['phone'] | |
end | |
when 'simultaneous' | |
dest = [] | |
dest_username= "" | |
available_agents.each do |agent| | |
if !(agent['forward_calls'])# && (agent['status']=="offline")) | |
dest.push "sofia/external/#{OUTGOING_PROVIDER_PREFIX}#{agent['phone'].gsub(/^\+|^00/,'')}@#{OUTGOING_PROVIDER}" | |
dest_username = dest_username + agent['phone'] | |
else | |
dest.push `#{FS_CLI} -x "sofia_contact #{agent['sip_user']}"`.strip | |
dest_username = dest_username + agent['sip_user'] | |
end | |
end | |
else | |
dest = [] | |
dest_username="" | |
available_agents.each do |agent| | |
if !(agent['forward_calls']) #&& (agent['status']=="offline")) | |
dest.push "sofia/external/#{OUTGOING_PROVIDER_PREFIX}#{agent['phone'].gsub(/^\+|^00/,'')}@#{OUTGOING_PROVIDER}" | |
dest_username = dest_username + agent['phone'] | |
else | |
dest.push `#{FS_CLI} -x "sofia_contact #{agent['sip_user']}"`.strip | |
dest_username = dest_username + agent['sip_user'] | |
end | |
end | |
end | |
{ dest:dest , dest_username:dest_username} | |
end | |
#get available agents | |
def get_available_agents(to_number) | |
begin | |
browser = Mechanize.new | |
browser.agent.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
logger.info "fetching company metadata at #{GET_COMPANY_ID+to_number.to_s}" | |
company_metadata = JSON.parse(browser.get(GET_COMPANY_ID+to_number.to_s).body) | |
logger.info "company metadata is #{company_metadata}" | |
company_id = "" | |
if company_metadata['status'] != 'fail' | |
logger.info company_metadata.inspect | |
company_id = company_metadata['companies'][0]['id'] | |
agents = JSON.parse(browser.get(GET_COMPANY_AGENTS+company_metadata['companies'][0]['id'].to_s).body)['agents']||[] | |
available_agents = [] | |
if !agents.nil? | |
agents.each do |agent| | |
logger.info "=========:::::=========\n#{agent}\n=======================" | |
if ( (`#{FS_CLI} -x "sofia status profile internal reg #{agent['sip_user']}"`.match(/Total items returned:.*\n/)[0].match(/\d/)[0].to_i > 0 ) || (agent['forward_calls'] ))# && (agent['status']=="offline")) ) | |
available_agents.push(agent) | |
logger.info "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ agent available #{agent['sip_user']} status #{agent['status']} forward call #{agent['forward_calls']}" | |
end | |
end | |
end | |
end | |
rescue Exception => e | |
end | |
if available_agents.nil? | |
available_agents=[] | |
end | |
{ company_id:company_id , available_agents:available_agents, company_metadata:company_metadata} | |
end | |
after_call do | |
logger.info "after call reached ================================================" | |
begin | |
$redis.publish "notification" , JSON.pretty_generate({from:@from_username, to:@to_username, event:{name:"hangup"}}) | |
rescue Exception => e | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment