Last active
August 7, 2023 23:10
-
-
Save hgaibor/6a170c150cf9dec607620aa44d78fcd0 to your computer and use it in GitHub Desktop.
targeted-chanSpy-with-levels-and-cos
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
; Feature code + Class of Service implementation to allow certain users to spy/whisper/barge on | |
; a specified extension. | |
; Additionally, levels of spy access have been included in the logic to create roles and restrict | |
; who can spy on what other roles based on a numeric level of access. | |
; | |
; Latest version: | |
; https://gist.github.com/hgaibor/6a170c150cf9dec607620aa44d78fcd0 | |
; | |
; Forked from: | |
; https://gist.github.com/hgaibor/82433116540f15ab345b2914500abb0d | |
; | |
; Usage and install instructions: | |
; 1. On FreePBX/PBXact GUI, Create a Custom Destination that points to the [custom-spy-with-cos-and-levels] context. | |
; Fill the interface fields with the values after the --> : | |
; 1.1 Target --> custom-spy-with-cos-and-levels,s,1 | |
; 1.2 Description --> Put a brief description | |
; 1.3 Notes --> Put your detailed comments here | |
; 1.4 Return --> no | |
; | |
; 2. Create a Misc Application that will point to created custom destination above. | |
; This destination will have the feature code you choose and will allow you to set the permissions over the | |
; Class of Service module. | |
; 2.1 Enable --> Yes | |
; 2.2 Description --> Spy with permissions feature code | |
; 2.3 Feature Code --> *557 (you can change this to whatever code needed) | |
; 2.4 Destination --> SELECT Custom Destination created above | |
; | |
; 3. Create Class of Service rules to DENY all users to use this code and allow the ones you need. | |
; Since you used the Misc Application module to assign the feature code, it will appear under the | |
; Class of Service --> [Feature codes] tab | |
; | |
; 4. Put Custom Dialplan at (GUI can be used using Config edit module): | |
; /etc/asterisk/extensions_custom.conf | |
; Dial feature code assigned under Misc Application to start in spy mode. While spying on | |
; active channel use the following dtmf input to toggle modes: | |
; dtmf 4 - spy mode | |
; 5 - whisper mode | |
; 6 - barge mode | |
; | |
; 5. Set the levels of permissions that can be used on each extension, in the 'accountcode' field at the [advanced] tab. | |
; extensions will be able to spy every other extension that have a lower numeric value on the accountcode, | |
; unless they are prevented from using the feature code by the Class of service module permissions. | |
; | |
; This is default behavior mentioned in https://wiki.asterisk.org/wiki/display/AST/Application_ChanSpy | |
; | |
; License: GNU GPL2 | |
; | |
; Version History | |
; 2023-07-28 First public commit by hgaibor | |
; For testing spy level restrictions without COS, if you don't want to perform steps 1 to 3 mentioned above uncomment this | |
; block of code and use the code combination of your preference | |
;[from-internal-custom] | |
;exten => *557,1,Noop(Entering user defined context custom-spy-with-cos-and-levels in extensions_custom.conf) | |
;exten => *557,n,GoTo(custom-spy-with-cos-and-levels,s,1) | |
[custom-spy-with-cos-and-levels] | |
exten => s,1,Noop(Entering user defined context custom-spy-with-cos-and-levels in extensions_custom.conf) | |
; Get info on the originating extension | |
exten => s,n,Set(__SPY_EXT=${CALLERID(num)}) ; numeric spy level permission, will allow spy if this is greated than the SPIED_EXT accountcode value | |
exten => s,n,noop(Dialer Spy ext: ${SPY_EXT}) | |
; Get info on the extension that will be spied | |
exten => s,n,Read(__SPIED_EXT,please-enter-the&extension&number&followed_pound) | |
exten => s,n,noop(Spied ext: ${SPIED_EXT}) | |
exten => s,n,GoTo(check-access-level,s,1) | |
[check-access-level] | |
; This context will use the number set up in extensions Account Code in order to determine the level of spying access | |
; It will allow spying on levels that are lower than current extensions level | |
exten => s,1,Noop(Entering user defined context check-access-level in extensions_custom.conf) | |
exten => s,n,Set(SPY_LEVEL=${DB(AMPUSER/${SPY_EXT}/accountcode)}) ; Checking SPY level, will allow spy if greater than SPIED_LEVEL | |
exten => s,n,ExecIf($[!${LEN(${SPY_LEVEL})}]?Set(SPY_LEVEL=0)) | |
exten => s,n,noop(Dialer spy level: ${SPY_LEVEL}) | |
; Checking SPIED_EXT spy level | |
exten => s,n,Set(SPIED_LEVEL=${DB(AMPUSER/${SPIED_EXT}/accountcode)}) ; numeric spy level permission, will allow spy if greater than | |
exten => s,n,ExecIf($[!${LEN(${SPIED_LEVEL})}]?Set(SPIED_LEVEL=0)) | |
exten => s,n,noop(Spied ext level: ${SPIED_LEVEL}) | |
;Checking if SPY extension can monitor SPIED extension | |
exten => s,n,GotoIf($[${SPY_LEVEL}>${SPIED_LEVEL}]?AllowSpy:DenySpy) | |
exten => s,n,Hangup() | |
exten => s,n(AllowSpy),noop(Allowed spy from ext ${SPY_EXT} to ${SPIED_EXT}) | |
exten => s,n,GoTo(targeted-chanspy,${SPIED_EXT},1) | |
exten => s,n,Hangup() | |
exten => s,n(DenySpy),noop(DENIED! spy from ext ${SPY_EXT} to ${SPIED_EXT}) | |
exten => s,n,Playback(silence/1&sorry-cant-let-you-do-that&silence/1) | |
exten => s,n,Hangup() | |
exten => h,n,Hangup() | |
exten => s,n,Hangup() | |
exten => T,n,Hangup() ; timeout destination | |
[targeted-chanspy] | |
exten => _.,1,Noop(Entering user defined context targeted-chanspy in extensions_custom.conf) | |
exten => _.,n,Set(TIMEOUT(absolute)=3600) ; prevent hung channel by setting 1 hour timeout recommended if using infinite loop | |
exten => _.,n,Answer | |
exten => _.,n(once-upon-a-time),Wait(1) | |
exten => _.,n,set(spy_target=) ; initialize target var | |
; get list of dialable devices for extension | |
exten => _.,n,Set(DEVS=${DB(AMPUSER/${EXTEN}/device)}) ; & delimited list of devices | |
exten => _.,n,Set(DEVS=${STRREPLACE(DEVS,&,\,)}) ; comma delimited list of devices | |
; step thru each device and look for an active channel | |
exten => _.,n,While($["${SET(DEV=${POP(DEVS)})}" != ""]) | |
exten => _.,n,noop(dev: ${DEV}) | |
; using a regex of SIP/${EXTEN}- will match both SIP and PJSIP channels, and the trailing - character should | |
; help to ensure there is only a single match. If multiple channels are returned the chanspy application will fail | |
exten => _.,n,set(spy_target=${CHANNELS(SIP/${DEV}-)}) | |
exten => _.,n,ExecIf($["${spy_target}"!=""]?ExitWhile) ; if an active channel is found exit the loop | |
exten => _.,n,EndWhile() | |
exten => _.,n,ExecIF($["${spy_target}"!=""]?ChanSpy(${spy_target},dnqE)) ; q option suppresses channel announce on barge | |
exten => _.,n,Hangup() ;comment this line with a semicolon to do infinite loop | |
exten => _.,n,GoTo(once-upon-a-time) | |
exten => _.,n,Hangup() | |
exten => h,n,Hangup() | |
exten => s,n,Hangup() | |
exten => T,n,Hangup() ; timeout destination |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment