Asterisk cmd AgentCallbackLogin


Call agent callback login


Deprecated in 1.4
Removed in 1.6


AgentCallbackLogin([AgentNo][|exten]@context) (1.0-)
AgentCallbackLogin([AgentNo][|Options[|exten[@context]]]) (1.2+)

Asks the agent to login to the system with callback.
The agent's callback extension is called with the specified context. The context must be specified, however the system
will prompt for the Agent number, password, and extension if they have not been supplied.

New in Asterisk v1.2.0: The AgentCallBackLogin application now requires a second '|' before specifying an extension@context. This is to distinguish the options string from the extension, so that they do not conflict. See 'show application AgentCallbackLogin' for more details.

New in Asterisk v1.4.0: (July 2006) Due to various issues with AgentCallbackLogin this feature is deprecated by Digium (according to Kevin P. Fleming). Similar functionality can be achieved through existing dialplan functionatliy using dynamic members: The functionality has been replaced with AEL dialplan logic located in the doc/queues-with-callback-members.txt file within the Asterisk source.

Removed in Asterisk v1.6

Replacement solution without AEL

Take from here

The major advantage of AgentCallBackLogin, is that each agent logs in to the system, set what phone they are sitting at, and start receiving calls from the queue. My method makes use of AstDB, the voicemail.conf and a few dialplan applications. I make use of the voicemail.conf to setup each agent, and with a PIN or password. So here’s my voicemail.conf:

1050 => 1234,Robert,,attach=yes|saycid=yes|envelope=yes|delete=yes|nextaftercmd=no

Within my extensions.conf I created the agent login and logout script and call back:

exten => 701,1,VMAuthenticate(@agent|)
exten => 701,n,AddQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n)
exten => 701,n,AddQueueMember(SUPPORT|local/${AUTH_MAILBOX}@agents/n)
exten => 701,n,Read(AGENT_SIP|agent-newlocation)
exten => 701,n,Set(DB(agent_sip/${AUTH_MAILBOX})=${AGENT_SIP})
exten => 701,n,Playback(agent-loginok)
exten => 701,n,Playback(goodbye)
exten => 701,n,Hangup

exten => 702,1,VMAuthenticate(@agent|)
exten => 702,n,RemoveQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n)
exten => 702,n,RemoveQueueMember(SUPPORT|local/${AUTH_MAILBOX}@agents/n)
exten => 702,n,Set(oldvar=${DB_DELETE(agent_sip/${AUTH_MAILBOX})})
exten => 702,n,Playback(agent-loggedoff)
exten => 702,n,Playback(goodbye)
exten => 702,n,Hangup

exten => 1050,1,Set(AGENT_SIP=${DB(agent_sip/1050)})
exten => 1050,n,Dial(SIP/${AGENT_SIP})

Pipe characters ( | ) have been changed to commas in Asterisk 1.6.
In Asterisk 1.4, either pipes OR commas will work. Using commas will ease future upgrades.

Extension 701 is what logs the agent in. VMAuthenticate prompts them for their agent number, and then their PIN or password, which is from the voicemail.conf. Then they are added to the Queue, with the callback being an extension within another context (local/1050@agents/n). We then READ the new “location”, which we enter into the AstDB for agent 1050. You will notice when the queue dials 1050@agents it pulls the data from AstDB, to know which SIP extension the agent is sitting at. Extension 702 is how the agent logs out of course. It will remove the agent from the Queues, and delete the AstDB entry.

More info

Unlike with AgentLogin the agent is not permanently off-hook (on-line). Instead the agent will be called at the designated extension when a new queue caller has been assigned to him. The agent goes off-hook and if ackcall is set to yes, must confirm with # that she is ready to take the call (it might be smart to include this instruction in the optional queue announcement). Press * to hang-up on the caller.

Please note that context refers to the section of the extensions.conf that contains the extensions for your agents. If you do not properly specify this, logging in will not function! Also make sure to configure Asterisk agents properly.

Sample extensions.conf entry that passes your extension number to the login routine:
exten => 700,1,AgentCallbackLogin(|${CALLERIDNUM}@local)

Sample CLI notice:
Local/ext@default-89d6,1 answered, waiting for '#' to acknowledge

(Note: Without a valid zaptel timing source, the '#' acknowledgement will not happen.)

Logging off the queue manually

  1. call the extension for AgentCallbackLogin --> AgentCallbackLogin(|l)
  2. enter your user id followed by #
  3. enter your password followed by #
  4. when asked for the extension number just press #
You will hear a voice prompt that confirms that the agent has been logged off.

And here's a tiny hack for the lazy people:
This removes the need for the user to press the # key on his/her phone

exten => 905,1,Dial(Local/999/n,,D(#))
exten => 999,1,AgentCallbackLogin(${CALLERIDNUM}|'#')
exten => 999,2,Hangup

Note that this sends '#' as the password, so it won't work if the Agent actually has a password. Also, in Asterisk 1.0.3, AgentCallbackLogin(,'#') doesn't pass extension '#' to the handler - you are still prompted for a new extension.

Another tiny possiblity to logoff
exten => _882.,1,Answer()
exten => _882.,n,System(asterisk -rx "agent logoff Agent/${EXTEN:3}")

Yet another way of doing it
This assumes your passwords are the same as the caller id - not very secure or flexible, but good enough for basic use.

exten => *02,1,AgentCallbackLogin(||${CALLERIDNUM}@phones)
exten => *06,1,Dial(Local/*04@fwtq/n,,D(${CALLERIDNUM}#${CALLERIDNUM}##))
exten => *04,1,AgentCallbackLogin()
exten => *07,1,Dial(Local/*02@fwtq/n,,D(${CALLERIDNUM}#${CALLERIDNUM}#))

Automatic logon / logoff via extensions.conf (it is possible)

In the previous version of this page I described the example for the older Asterisk version 1.0.7. I've replaced it with the description for how to use it with Asterisk 1.2.x by making use of channel variables with inheritance across channels.(prepended with _ underscore) This is needed to carry them on to the local channel which is used in this example. When you want to see the previous description for pre 1.2.x please get an older version of this wiki page.

In this example you need to have the agentcode and pincode available. I did this by writing an AGI script which asks for agentcode and pincode, this script feeds back the values as channel variables. (see AGI: SET VARIABLE command)

Without printing the whole AGI script code, I show how it is used:
In my dialplan there is the following line:

exten => s,1,AGI(My_own_authentication_script.agi)

In my case it is a Unix shell script and it looks like this:

#Major parts of script skipped, it contains too many lines and logic and it is not needed to explain this subject
AGENTCODE="100" #as example set the AGENTCODE to 100
PINCODE="1313" #as example set the PINCODE to 1313
echo "SET VARIABLE _AGENTCODE $AGENTCODE" #push shell variable contents into channel variable with same name
echo "SET VARIABLE _PINCODE $PINCODE" #push shell variable contents into channel variable with same name
exit #return from agi script, all variables delivered to dialplan

After execution of the agi script, the variables are known in the rest of the dialplan.
Now the following stuff in the dialplan will do the job:

exten => s,1,sendDTMF(${PINCODE}#)

exten => s,1,sendDTMF(${PINCODE}##)

exten => login,1,AgentCallbackLogin(${AGENTCODE}||${AGENTCODE}@agent_phones)
exten => logout,1,AgentCallbackLogin(${AGENTCODE}||)

At the location in your dialplan where you want to auto login the agent put the following:

exten => 1,1,Dial(Local/login@localchanneldefs/n,,gM(autologin))

At the location in your dialplan where you want to auto logoff the agent put the following:

exten => 2,1,Dial(Local/logout@localchanneldefs/n,,gM(autologout))

Login / Logout using the Manager API

I had a need to be able to login/Logout agents from management console that I developed to manage ACD queues.

My solution was to setup some extension and use the manager originate command to dial those extensions allowing me to login/logout agents.

To extensions.conf add

exten => 02000000001,1,AgentCallBackLogin(${CALLERIDNUM}|s|${CALLERIDNUM}@to-your-agent-context)
exten => 02000000002,1,Dial(Local/02000000003/n,,D(#))
exten => 02000000003,1,AgentCallbackLogin(${CALLERIDNUM}|s|'#')

; for local channel

exten => 1234,1,Answer
exten => 1234,2,Hangup

use the manager API originate command to login/logout see examplse below

Action: Originate
Channel: Local/02000000001/n
Context: default'
Exten: 1234
Priority: 1
Callerid: <enter caller ID of agent here>
Timeout: 30000'

to logout do exactly the same but change the channel to Local/02000000002/n as per the dial-plan.

Hope other find this useful.


Logging off the queue automatically

Alternatively, you can configure the autologoff setting in Asterisk config agents.conf. This will allow your agents to be automatically removed from the queue after a certain number of seconds if they do not answer calls from the queue. This is very useful for agents who forget to log out.

Finding out the agent ID when they're making calls.

I just don't want anybody picking up the phone and making calls.......

Rather than have to write a whole chunk of code to make an agent log in when they want to make outbound calls, I thought it would be useful if I could use the existing agent authentication scheme to validate the agent when they're trying to make outbound calls. There is no reference to any method of doing this - the above code assumes that the caller ID is the same as the agent ID which (assuming the agents are hotdesking and working in shifts) it most certainly won't.

After much digging, I found that after a successful login, AgentCallBackLogin creates a global variable, 'AGENTBYCALLERID_${CALLERID}' (e.g. if you've registered from a SIP phone with caller ID 'SIPPhone 205 <205>', then the variable is ${AGENTBYCALLERID_SIPPhone 205 <205>}) which contains the agent ID. When AgentCallbackLogin is used to log the agent out, the global variable is deleted.

1.2.14 (not only, perhaps): Global variable is named like 'AGENTBYCALLERID_${CALLERIDNUM}' (in the above case this would be ${AGENTBYCALLERID_205}).

This can then be used when a call is received from a handset to make sure that it belongs to an agent who has successfully logged in.

Unfortunately, this isn't as easy as it sounds. Asterisk only parses the dialplan once for variables, so you can't have variables-within-variables, like ${AGENTBYCALLERID_${CALLERID}}. You have to use the Eval command to work this out. However, it is difficult to construct the string to be eval'd ("${AGENTBYCALLERID_${CALLERID}}"), because it keeps getting parsed. This is my horribly ugly hack:

; login by dialling zero, and then your agent number
exten => _0.,1,Goto(services,100${EXTEN:1},1)

; logout directly by dialing 101
exten => 101,1,Goto(services,101,1)

; anything else, check whether ${AGENTBYCALLERID_${CALLERIDNUM}} is set, and if so, forward to the default context
exten => _X.,n,GotoIf(${ISNULL(${ABCID})}?3:default,${EXTEN},1)
exten => _X.,n,NoOp(Unauthorized call)
exten => _X.,n,Playback(agent-incorrect)
exten => _X.,n,Playback(vm-unknown-caller.gsm)
exten => _X.,n,Hangup

exten => _100.,1,AgentCallbackLogin(${EXTEN:3}||${CALLERIDNUM}@users)

; Agent logout
exten => 101,n,System(asterisk -rx "agent logoff Agent/${ABCID}")
exten => 101,n,Playback(agent-loggedoff)
exten => 101,n,Playback(vm-goodbye)
exten => 101,n,Hangup

The phones must start in 'phonecontext'. This way, the only calls they can make are login/logout. All other calls get matched by the _X., which checks whether they're logged in, and forwards those calls to the default extension, if so. In order to create the string '${AGENTBYCALLERID_${CALLERIDNUM}}', you have to have ${DOLLAR}, ${OQUOTE} and ${CQUOTE}, which get parsed and turned into the bits of that string, which can then be eval'd. If it is set, forward the call on, otherwise say sorry, and hang up.

However.... There are some caveats which could bite you:
  • If an agent is logged in and another agent logs in without the first one logging out, then the variable is updated with the details of the second agent.
  • If two agents are logged in (as above), then either agent logging out will delete the variable
  • If two or more devices with duplicate IDs are used to log agents in, the same variable name is used which renders it useless.

None of these are a real problem if the AgentCallbackLogin code is placed inside a wrapper which ensures a second agent can't log in if one's already logged in.

There is more than one way to do it!

Create a macro:

exten => s,1,GotoIf($["${ISNULL(${ARG1})}" = "1"]?2:4)
exten => s,2,Playback(not-auth-pstn)
exten => s,3,Congestion
exten => s,4,Dial(${ARG2}/${ARG3})

Use the macro when you want to verify that the call is made by a logged agent.

exten => _0NXXXXXXXXXX,3,macro(verifyncall,${AGENTBYCALLERID_${CALLERID(num)}},${TRUNK},${EXTEN})

QueueLog app (July 2006)

Just want to remind you about QueueLog app I posted in bug/patch 7368 - with that you can push AGENTLOGIN and LOGOFF entries through to queue_log. Which resolved one difference between agentcallbacklogon and dynamic members.

Coming features...

See for features coming to AgentLogin and AgentCallbackLogin...

Agent variables

See for a patch which lets you access agent variables in your dialplan
syntax is AGENT(agentid:item)

options for item are:
  • status (default) - The status of the agent
  • password - The password of the agent
  • name - The name of the agent
  • mohclass - MusicOnHold class
  • exten - The callback extension for the Agent (AgentCallbackLogin)
  • channel - The name of the active channel for the Agent (AgentLogin)

Example - retrieving the password for agent number 1234

Example - passwordless logout by dialing extension 8601 (this gets the variables and then passes these to exten 8602 for the actual logout)

exten => 8601,1,Dial(Local/8602/n,,D(${AGENTBYCALLERID_${CALLERIDNUM}}#${AGENT(${AGENTBYCALLERID_${CALLERIDNUM}}:password)}##))
exten => 8602,1,AgentCallbackLogin()

Another example

This is a quick and durty way I came up with. It may help someone out :)

exten=> 8000,1,Answer
exten=> 8000,2,System(asterisk -rx "agent logoff Agent/${AGENTBYCALLERID_${CALLERIDNUM}}")
exten=> 8000,3,Playback(/var/lib/asterisk/sounds/agent-loggedoff)
exten=> 8000,4,Hangup

See also

Asterisk | Applications | Functions | Variables | Expressions | Asterisk FAQ
Created by: oej, Last modification: Mon 19 of Aug, 2013 (09:07 UTC) by lenz
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+