Skip to content

Instantly share code, notes, and snippets.

@lgaetz
Last active June 27, 2024 11:18
Show Gist options
  • Save lgaetz/78c4e114952e79596c1ed4123559d3d3 to your computer and use it in GitHub Desktop.
Save lgaetz/78c4e114952e79596c1ed4123559d3d3 to your computer and use it in GitHub Desktop.
FreePBX Feature code prefix to allow spy/whisper/barge on the specified extension
; FreePBX Feature code prefix to allow spy/whisper/barge on
; the specified extension.
;
; Latest version:
; https://gist.github.com/lgaetz/78c4e114952e79596c1ed4123559d3d3
;
; Usage:
; Dialplan goes in the file:
; /etc/asterisk/extensions_custom.conf
; Dial local extension with 556 prefix to spy. While spying on
; active channel use the following dtmf input to toggle modes:
; dtmf 4 - spy mode
; 5 - whisper mode
; 6 - barge mode
;
; License: GNU GPL2
;
; Version History
; 2018-11-23 First commit by lgaetz
; 2019-03-05 update regex to prevent channels from returning multiple channel matches
; 2019-10-10 added support to loop thru all dialable devices for the extension, now supports Zulu/webrtc clients
; 2020-04-12 COVID-19 edition - supports prompt to request spyee extension
; 2020-07-23 add E option to ChanSpy application and add timeout
; 2021-03-08 add example line to block spying access to certain extensions
[from-internal-custom]
exten => 556,1,Noop(Entering user defined context from-internal-custom in extensions_custom.conf)
exten => 556,n,Read(spyee,please-enter-the&extension&number&followed_pound)
exten => 556,n,GoTo(targeted-chanspy,${spyee},1)
exten => _556.,1,Noop(Entering user defined context from-internal-custom in extensions_custom.conf)
exten => _556.,n,GoTo(targeted-chanspy,${EXTEN:3},1) ;strip off prefix
[targeted-chanspy]
exten => _.,1,Noop(Entering user defined context targeted-chanspy in extensions_custom.conf)
; exten => _.,n,ExecIF($["${EXTEN}"="100"]?Hangup) ; if you want to block spying access to certain extensions you can do that with this line, one per ext
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,1,Hangup()
exten => s,1,Hangup()
exten => T,1,Hangup() ; timeout destination
@XcamaroX
Copy link

@lgaetz Great code, it works as intended. Thank you so much for your hard work on this.

One quick question, this only seems to work when the extensions are on the same PBX, but how would it work if I have 2 PBX's, connected via a PJSIP trunk?

When I try to barge on the remote extensions, it just hangs up.

The exteniosn are OK, as I can make calls to and from and it works.

Would this code work for this instance, any modifications that I might have to do?

Thank you again!

@clletizia
Copy link

Greetings and thanks for the code. Is it expected that the exclusion statement < ExecIF($["${EXTEN}"="100"]?Hangup) > will handle traditional dialplan wild cards? for instance ExecIF($["${EXTEN}"="1xx"]?Hangup). Thanks

@lgaetz
Copy link
Author

lgaetz commented Nov 29, 2023

exclusion statement ... will handle traditional dialplan wild cards?

No. To do that you'll want to investigate the REGEX dialplan function.

@clletizia
Copy link

clletizia commented Nov 29, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment