How to: Dynamic Agents - External Access to Login/Off

Hey guys,

I’ll start off with saying that I’m not really good at asterisk custom code, but this is working for me.
I set this to a Wiki, so anyone more familiar can brush it up so it’ll be more elegant.

Introduction:
In older versions of FreePBX (still works in FreePBX 13) you were able to login to a Queue by dialing QUEUE*, log off by dialing QUEUE**. This was a great feature for external users who need to set their extension which has followme or their phone number in the queue to be able to “cover the shift”.

How it used to work - and how we set it up is, an IVR pointed to two misc destinations, 1 would dial QUEUE* and the other would dial QUEUE** so the agents calling would have to choose if they want to login or off, then it would ask them for their “agent number” and then for a password to login. (forgot to mention there was also a feature to password protect the queues)

We currently have this in place on older systems and I was shocked to see this features gone.
If we would’ve upgrade these machines without noticing beforehand that these features are deprecated, you could only imagine how that very first day being on the updated system would be.
I’m glad that I was able to confirm this was deprecated and not a bug so I had time to write up something to replace this feature.

I still hope that Sangoma/FreePBX will bring those features back, since these were manageable from the GUI 100%, VS in the guide I’m sharing custom code is involved.

Version 1.

Details:

  • You will need to setup a Custom Destination which targets enter-password,s,1

  • Password I’m using is 1234.

  • I allow max of 11 digits to login (US numbers)

  • I used Queue 500 as an example.

Now add the following to extensions_custom.conf

[enter-password]
exten => s,1,Answer()
exten => s,n,Set(Attempts=1)
exten => s,n(begin),NooP(&&&&&&& Collecting Password info for ${CALLERID(all)} attempt ${Attempts} &&&&&)
exten => s,n,Read(passwd,enter-password,5,,1,5)
exten => s,n,ExecIf($["${passwd}"="1234"]?goto(agent-number,s,1))
exten => s,n,Set(Attempts=${MATH(${Attempts}+1,i)})
exten => s,n,ExecIf($["${Attempts}"="3"]?playback(sorry-youre-having-problems))
exten => s,n,ExecIf($["${Attempts}"="3"]?playback(hangup-try-again))
exten => s,n,ExecIf($["${Attempts}"="3"]?HANGUP())
exten => s,n,ExecIf($["${passwd}"=""]?goto(enter-password,s,1))
exten => s,n,Playback(vm-invalidpassword)
exten => s,n,Goto(enter-password,s,begin)

[agent-number]
exten => s,1,Answer()
exten => s,n,Read(agent,agent-login,11,,1,5)
exten => s,n,Playback(you-entered)
exten => s,n,SayDigits(${agent})
exten => s,n,Read(digi,if-correct-press&digits/1&otherwise-press&digits/2,,1)
exten => s,n,ExecIf($["${digi}"="1"]?goto(agent-login,s,1))
exten => s,n,Playback(please-try-again)
exten => s,n,Goto(agent-number,s,1)

[agent-login]
exten => s,1,Answer()
exten => s,n,Set(QUEUENO=500)
exten => s,n,Set(QUEUEUSER=${agent})
exten => s,n,Goto(app-queue-toggle,s,start)

What it does:

Once you point to an inbound route or an IVR to the Custom destination, callers will be able to try a wrong password twice before the system hangs up on them.

If you enter the password successfully the system will ask you to enter your agent number followed by the pound sign, once entered, the system will confirm the numbers you entered and then ask you to confirm if this is correct, or you want to re-enter.

Finally, once you confirm the numbers are correct, the system will log you in to the queue, and if this is the second time you enter the same agent number it will log log you out of the queue.

In other words, callers/agents will have to go through the same process when logging in and when logging off.


Version 2.

Details:

  • Same as the above.
  • You will need to create a audio named ‘login-1-off-2’ that says “To login press 1 to logoff press 2”

Add the below to extensions_custom.conf

[enter-password]
exten => s,1,Answer()
exten => s,n,Set(Attempts=1)
exten => s,n(begin),NooP(&&&&&&& Collecting Password info for ${CALLERID(all)} attempt ${Attempts} &&&&&)
exten => s,n,Read(passwd,enter-password,5,,1,5)
exten => s,n,ExecIf($["${passwd}"="1234"]?goto(login-off-selection,s,1))
exten => s,n,Set(Attempts=${MATH(${Attempts}+1,i)})
exten => s,n,ExecIf($["${Attempts}"="3"]?playback(sorry-youre-having-problems))
exten => s,n,ExecIf($["${Attempts}"="3"]?playback(hangup-try-again))
exten => s,n,ExecIf($["${Attempts}"="3"]?HANGUP())
exten => s,n,ExecIf($["${passwd}"=""]?goto(enter-password,s,1))
exten => s,n,Playback(vm-invalidpassword)
exten => s,n,Goto(enter-password,s,begin)

[login-off-selection]
exten => s,1,Answer()
exten => s,n,Read(selection,custom/login-1-off-2,1,,1,5)
exten => s,n,ExecIf($["${selection}"="1"]?goto(agent-login-number,s,1))
exten => s,n,ExecIf($["${selection}"="2"]?goto(agent-logoff-number,s,1))
exten => s,n,Playback(no-valid-response-pls-try-again)
exten => s,n,Goto(queue-selection,s,1)

[agent-login-number]
exten => s,1,Answer()
exten => s,n,Read(agent,agent-login,11,,1,5)
exten => s,n,Playback(you-entered)
exten => s,n,SayDigits(${agent})
exten => s,n,Read(digi,if-correct-press&digits/1&otherwise-press&digits/2,,1)
exten => s,n,ExecIf($["${digi}"="1"]?AddQueueMember(500,Local/${agent}@from-queue/n)
exten => s,n,ExecIf($["${digi}"="1"]?playback(agent-loginok))
exten => s,n,ExecIf($["${digi}"="1"]?SayDigits(${agent}))
exten => s,n,ExecIf($["${digi}"="1"]?playback(goodbye))
exten => s,n,ExecIf($["${digi}"="1"]?Hangup())
exten => s,n,Playback(please-try-again)
exten => s,n,Goto(agent-login-number,s,1)


[agent-logoff-number]
exten => s,1,Answer()
exten => s,n,Read(agent,agent-logoff,11,,1,5)
exten => s,n,Playback(you-entered)
exten => s,n,SayDigits(${agent})
exten => s,n,Read(digi,if-correct-press&digits/1&otherwise-press&digits/2,,1)
exten => s,n,ExecIf($["${digi}"="1"]?RemoveQueueMember(500,Local/${agent}@from-queue/n)
exten => s,n,ExecIf($["${digi}"="1"]?playback(agent-loggedoff))
exten => s,n,ExecIf($["${digi}"="1"]?SayDigits(${agent}))
exten => s,n,ExecIf($["${digi}"="1"]?playback(goodbye))
exten => s,n,ExecIf($["${digi}"="1"]?Hangup())
exten => s,n,Playback(please-try-again)
exten => s,n,Goto(agent-logoff-number,s,1)

What it does:
Similar to version 1, the difference is that in version 2 after you enter the password it asks you if you want to login or to log off.


IMPORTANT DETAILS:
Version 1. seems to be logging you in and out, but it appears not to be calling the members logged in. (I suspect it’s due to the hints not being set correctly)
Version 2. is working fine and calls the members in queue, however, it requires you to setup a custom audio.

I still hope that someone can get version 1 working since it’s more an elegant way of accomplishing this.

Hope this helps someone.

1 Like

I’ve set this up, however any agents I log-in in this manner appear to be “invalid,” and calls entering the queue do not ring the agents. After running asterisk -rx “queue show 500” I get:

500 has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:6, SL:0.0% within 60s
   Members:
      Local/1xxxxxxxxxx@from-queue/n (ringinuse enabled) (dynamic) (Invalid) has taken no calls yet
      Local/xxxxxxxxxx@from-queue/n (ringinuse enabled) (dynamic) (Invalid) has taken no calls yet
   No Callers

Why is this?

I see.

Unfortunately, I can’t think of a way to solve this, it is out of my knowledge zone. I believe it has to do with the hints which is not being set correctly.
I hope someone can reply here how to set it, and I’ll test.

The only other was I can think of is somehow get it to dial *45${agent}*500 from internal

This is old posts I found online.
https://wiki.asterisk.org/wiki/display/AST/Assigning+Agents+to+Queues

I hope someone can get this working…

Appreciate any suggestions.

See the original post, I added version 2. which I tested and it is working fine.