Skip to content

Instantly share code, notes, and snippets.

@andrius
Created February 19, 2013 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrius/4984463 to your computer and use it in GitHub Desktop.
Save andrius/4984463 to your computer and use it in GitHub Desktop.
Old AGI sample of manipulaiton with dynamic agents for asterisk 1.2 and 1.4
#!/usr/bin/ruby
require 'rubygems'
require 'rastman'
require 'AGIServer'
require 'AGISelection'
require 'AGIMenu'
AMI = Rastman::Manager.new(@@config[:manager][:user],
@@config[:manager][:secret],
:port => @@config[:manager][:port],
:host => @@config[:manager][:host])
def rastman_start
if ! AMI.connected? then
AMI.connect
end
end
module Rastman
class Manager
# logging in agent XX to extension YYY at context queuephones
# if expects_answer_before is set to any number, waits up to X seconds and
# return result, unless does not do nothing
def agent_callback_login(agentid, extension, expects_answer_before = nil)
rastman_start
send_action({:action => "AgentCallBackLogin",
:agent => "#{agentid}",
:exten => "#{extension}",
:context => "queuephones",
:ackcall => "false",
:wrapuptime => "4"}, expects_answer_before)
end
def agent_logoff(agentid, expects_answer_before = nil)
rastman_start
send_action({:action => "AgentLogoff", :agent => "#{agentid}"}, expects_answer_before)
end
def queues(expects_answer_before = nil)
rastman_start
send_action({:action => "Queues"}, expects_answer_before)
end
def turn_led(ledname, ledid, state, expects_answer_before = nil)
rastman_start
#state_name = state ? "on" : "off"
#send_action({:action => "originate",
# :channel => "Local/#{ledid}@dummy",
# :context => "#{ledname}_led_#{state_name}",
# :exten => "#{ledid}",
# :priority => 1}, expects_answer_before)
send_action({:action => "DevState", :devstate => "#{ledname}#{ledid}", :value => state ? "2" : "0"}, expects_answer_before)
end
# sets channel variable (if defined) or global variable
def set_variable(variable, value, channel = nil, expects_answer_before = nil)
rastman_start
if channel then
send_action({:action => "SetVar", :channel => "#{channel}", :variable => "#{variable}", :value => "#{value}"}, expects_answer_before)
else
send_action({:action => "SetVar", :variable => "#{variable}", :value => "#{value}"}, expects_answer_before)
end
end
def set_global_variable(variable, value, expects_answer_before = nil)
set_variable(variable, value, nil, expects_answer_before)
end
#Action: Getvar
#Synopsis: Gets a Channel Variable
#Privilege: call,all
#Description: Get the value of a global or local channel variable.
#Variables: (Names marked with * are required)
# Channel: Channel to read variable from
# *Variable: Variable name
# ActionID: Optional Action id for message matching.
def get_variable(variable, channel = nil)
rastman_start
if channel then
send_action({:action => "Getvar", :channel => "#{channel}", :variable => "#{variable}"}, 10)
else
send_action({:action => "Getvar", :variable => "#{variable}"}, 10)
end
end
def db_get(family, key)
rastman_start
send_action({:action => "DBGet", :family => "#{family}", :key => "#{key}"}, 10)
end
#Action: DBPut
#Family: <family>
#Key: <key>
#Value: <value> (note, as of Asterisk 1.4 The Manager API wants Val: <value>)
#Returns:
#Response: Success
#Message: Updated database successfully
def db_put(family, key, value)
rastman_start
send_action({:action => "DBPut", :family => "#{family}", :key => "#{key}", :val => "#{value}"}, 10)
end
def list_agents
send_action({:action => "Agents"}, 10)
end
#Action: QueueAdd
#Queue: queue1
#Interface: sip/2600
#Penalty: 1
#Paused: true
def queue_add(queue, interface, penalty = 0, paused = false, expects_answer_before = nil)
rastman_start
send_action({:action => "QueueAdd",
:queue => queue,
:interface => interface,
:penalty => penalty.to_s,
:paused => paused ? "true" : "false"}, expects_answer_before)
end
#Action: QueueRemove
#Queue: queue1
#Interface: sip/2600
def queue_remove(queue, interface, expects_answer_before = nil)
rastman_start
send_action({:action => "QueueRemove", :queue => queue, :interface => interface}, expects_answer_before)
end
def queue_pause(queue, interface, expects_answer_before = nil)
rastman_start
if queue then
send_action({:action => "QueuePause", :queue => queue, :interface => interface, :paused => true}, expects_answer_before)
else
send_action({:action => "QueuePause", :interface => interface, :paused => true}, expects_answer_before)
end
end
def queue_unpause(queue, interface, expects_answer_before = nil)
rastman_start
if queue then
send_action({:action => "QueuePause", :queue => queue, :interface => interface, :paused => false}, expects_answer_before)
else
send_action({:action => "QueuePause", :interface => interface, :paused => false}, expects_answer_before)
end
end
end
end
# ********************* MAIN CODE *************************
# Usage:
# exten => 37052059911,1,AGI(exten.rb|class=EXT|owner=205|backup=37065529276|location=Vilnius|sequence=227,204,224,secretary,211)
# exten => 37052059911,1,AGI(exten.rb|class=EXT|owner=205|backup=37065529276|location=Vilnius|ringing=on|limit_ringing=300|roundt
rip=227,204,224,secretary,211)
# exten => 205,1,AGI(exten.rb|class=INT|backup=37065529276|location=Vilnius|ringing=moh|limit_ringing=300|roundtrip=227,204,224,s
ecretary,211,backup)
# exten => 227,1,Macro(Dialphones,000,4,sequence,1,${MATH(5 * 12,int)},dont_check,0,Vilnius,start_int,fwd_context,exit_context,
# with_ringback,tTwW,,30,T
# ,SIP/227,16,,SIP/204,16,,SIP/224,16,,
# Local/201@two_phones/n,16,,SIP/211,16,)
# call center processing
class CC < AGIRoute
# public methods
def bridge
@@logger.info("DONE!")
end
def check_agents
agents = get_all_online_agents
@@logger.info("all agents: #{agents.inspect}")
agents.each do |agent|
check_agent(agent)
check_agent(agent, true)
end
check_agent("77")
end
def login_trigger
agi.exec("NOCDR")
if agi.get_variable("SIPURI").to_s =~ /[^\:]+\:([a-z|0-9]+)@/ then
phoneid = $1.to_s
else
# call not from sip account or call transfer etc...
agi.exec("BUSY")
return
end
# here compare and exit if match, channel and sip account
if phoneid != agi.channel_params['channel'].to_s[4,3] then
agi.exec("BUSY")
return
end
agi.answer
if agi.get_full_variable("${DB(agents/#{phoneid}/online)}").to_s == "true" then
# logged in - have to logout!
agentid = agi.get_full_variable("${DB(agents/#{phoneid}/agent_id)}").to_s
agent_logout(agentid, phoneid)
if agi.channel_alive? then
agi.exec("PLAYBACK agent-loggedoff")
agi.exec("PLAYBACK vm-goodbye")
agi.busy_hangup
end
else
agentid = nil
ivr = AGISelection.new({:audio => 'agent-user', :max_digits => 4})
agentid = ivr.read(:agi => agi).to_s
if ! ["01", "02", "03", "04", "05", "06", "07", "08", "09", "11", "12", "13"].index(agentid) then
agi.exec("PLAYBACK vm-goodbye")
return
end
# 1. Logout if same agent are at other sip phone - from that phone
# 2. login
# 3. keep values into asterisk DB, mysql DB, turn on LED's
# 4. playback conformation message
old_location = agi.get_full_variable("${DB(agents/#{agentid}/phoneid)}").to_s
if agi.get_full_variable("${DB(agents/#{old_location}/online)}").to_s == "true" && agi.get_full_variable("${DB(agents/#{old_location}/agent_id)}").to_s == agentid then
@@logger.info("unregistering old agent !!!")
old_agentid = agi.get_full_variable("${DB(agents/#{old_location}/agent_id)}").to_s
agent_logout(old_agentid, old_location)
end
agent_login(agentid, phoneid)
if agi.channel_alive? then
agi.exec("PLAYBACK agent-loginok")
agi.busy_hangup
end
end
end
def agent_login(agentid, phoneid)
queues = get_queues_belongs_to_agent(agentid)
queues.each do |row|
AMI.queue_remove(row[:queue], "SIP/#{phoneid}")
end
queues.each do |row|
AMI.queue_add(row[:queue], "SIP/#{phoneid}", row[:penalty], false)
end
AMI.db_put("agents/#{agentid}", "phoneid", phoneid)
AMI.db_put("agents/#{phoneid}", "agent_id", agentid)
AMI.db_put("agents/#{phoneid}", "online", "true")
db_open
@@dbh.query("INSERT INTO agentactions (agent_id, action_id, start_time, sip_peer) SELECT id, '1', '#{Time.now().strftime("%Y-%m-%d %H:%M:%S")}', '#{phoneid}' FROM agents WHERE extension='#{agentid}'")
agent_unpause(agentid, phoneid)
AMI.turn_led("LOG", phoneid, true)
end
def agent_logout(agentid, phoneid)
queues = get_queues_belongs_to_agent(agentid)
AMI.queue_unpause(nil, "SIP/#{phoneid}")
queues.each do |row|
AMI.queue_remove(row[:queue], "SIP/#{phoneid}")
end
AMI.db_put("agents/#{phoneid}", "online", "false")
db_open
@@dbh.query("UPDATE agentactions SET end_time='#{Time.now().strftime("%Y-%m-%d %H:%M:%S")}' WHERE id=(SELECT MAX(aa.id) FROM agentactions_view aa WHERE aa.extension='#{agentid}' AND aa.action_id=1)")
agent_unpause(agentid, phoneid)
AMI.turn_led("LOG", phoneid, false)
end
end
rastman_start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment