Monday, October 7, 2019

Asterisk - limit extension total usage duration

Here's how you an limit the extension duration based on values in a PINSET in the GUI.
This will use a PINSET with the description of "extenmaxduration" (system is hardcoded to this description for this example)
LIMITATION.
This code works with FOUR DIGIT extensions ONLY
Create a PINSET with the description "extensionduration"
In the pins put in pins using the SYNTAX:
Extension*Minutes
Example:
1005*00500
1006*01500
1103*99999
EXPLAINED:
PINSET values are stored in the database using "carriage return" delimitation within the actual column, so we need to parse the data returned by the SQL statement. This means the data MUST be a consistent length for my select statement..
This is why we have leading zero's ( 00 ) in the duration to maintain the length for the SQL script i have. I'm sure there are far smarter people than me who can work this out, but this is what I was able to make work.
In my example,
extension 1005 is allowed 500 minutes "1005*00500"
extension 1006 is allowed 1500 minutes "1006*01500"
extension 1103 is allowed 99999 minutes "1103*99999"
Extensions that are NOT in the list, the code will simply bypass them and allow those calls to continue.
So here is the entire code. Again the "outrt-X" heading will need to be altered to suit your environment.
[outrt-2] ; limit by extensions
include => outrt-2-custom
exten => _.,1,Macro(user-callerid,LIMIT,EXTERNAL,)
exten => _.,n,Set(MOHCLASS=${IF($["${MOHCLASS}"=""]?default:${MOHCLASS})})
exten => _.,n,Set(_NODEST=)
exten => _.,n,Gosub(sub-record-check,s,1(out,${EXTEN},))

;open connection to ASTERISK table to get the pinset data
exten => _.,n,MYSQL(Connect connid localhost root PBXPASS asterisk)
exten => _.,n,MYSQL(Query resultid ${connid} select MID((select passwords from pinsets where description = 'extensionduration'), INSTR ((select passwords from pinsets), "${ampuser}"),10) from pinsets)
exten => _.,n,MYSQL(Fetch fetchid ${resultid} extenmaxduration)
exten => _.,n,MYSQL(Clear ${resultid})
exten => _.,n,MYSQL(Disconnect ${connid})

;If we dont find a matching extension, we'll skip the rest of the checks and just let it dial out.
exten => _.,n,GotoIf($["${extenmaxduration}" = ""]?continue)

;parse the return using an * as the delimiter between extension and minute values
exten => _.,n,Set(extenmaxduration=${CUT(extenmaxduration,*,2)})

;change mins to seconds
exten => _.,n,Set(extenmaxduration=${MATH(${extenmaxduration}*60,int)})

;open a new connection CDR table
exten => _.,n,MYSQL(Connect connid localhost root PBXPASS asteriskcdrdb)
exten => _.,n,MYSQL(Query resultid ${connid} SELECT if(sum(duration) < ${extenmaxduration}, 1, 0) FROM cdr WHERE (calldate between DATE_FORMAT(NOW() ,'%Y-%m-01') AND NOW() ) and src like '${AMPUSER}')
exten => _.,n,MYSQL(Fetch fetchid ${resultid} extenmaxduration)
exten => _.,n,MYSQL(Clear ${resultid})
exten => _.,n,MYSQL(Disconnect ${connid})

;if we dont find any value in pinset, we'll default allow this call to go through.
exten => _.,n(continue),execif($["${extenmaxduration}" = ""]?set(extenmaxduration=1))

;if montly duration is less than pinset duration, go out trunk, else say "time" and hangup
exten => _.,n,execif($["${extenmaxduration}" = "1"]?macro(dialout-trunk,1,${EXTEN},,off))
exten => _.,n,execif($["${extenmaxduration}" = "0"]?playback(time))
exten => _.,n,Macro(outisbusy,)
Save your changes and reload your configs.
Give it a try!

Remember that your values for your extensions need a leading zereo, and those values are stored in MINUTES. The script will do the calculation to change it to SECONDS which the CDR table uses.
In this example, if the extension has not exceed its maximum, the call will proceed out the trunk.
If it has exceeded the max, you will hear the voice "TIME" and then a "all circuits busy"

No comments:

Post a Comment