Best Way to Play an Audio File over an Intercom/Paging Extension?

Hey Everyone,

I am trying to set up a custom extension in extensions_custom.conf (e.g. 26669) that when called, will either call an individual extensions with intercom/auto-answer enabled (or a paging group), play a custom-uploaded sound file (e.g. custom/Doorbell) at the remote phone (and not to caller), and then hangup.

My asterisk experience is very limited, however using the syntax from the Page function of asterisk here
https://wiki.asterisk.org/wiki/display/AST/Application_Page

I came up with the following custom Asterisk extension:

exten => 26669,1,Answer
exten => 26669,n,Page(SIP/907,(A(custom/Doorbell),i,q,n,5))
exten => 26669,n,Hangup

Where:
"907" Is a single auto-answer intercom extension I’m using for testing
"i" Ignores attempts to forward the call to another destination
"q" Silences the paging system “beep” sound to the caller and called
"n" Does not play the sound file back to the caller (e.g. custom/Doorbell)
"5" Seconds that the system will attempt to connect a call to a destination

When I dial the number 26669, the custom extension works as intended, however after the playback of the sound, the call session is then connected between the caller and the called extension/page group instead of being terminated.

I am trying to create a custom extension so that I may later be able to interface the FreePBX system with Home Assistant or Hubitat to use the speakerphones in the house to play a doorbell sound when someone is at the door.

How would I terminate the call after playback of the sound over the intercom/paging group? Is there a better way to way to accomplish this?

I’m using FreePBX Distro V14.0.13.33, with the latest modules.

Answering in pure Asterisk terms, you would need to use Originate, to decouple the initiator from the actual Page. The source channel for the Originate would need to be a Local channel.

1 Like

Thank you @david55 for your quick reply and help! I also used the following site to help create both a callable extension as well as an asterisk command line to accomplish playing an audio file over an intercom or paging extension:

How to Dial to Originate a Call from Within the Dialplan?

From there, I came up with the following in extensions_custom.conf:

[from-internal]
exten => 26669,1,Goto(PlayDoorbellContext,OriginateSound,1)

[PlayDoorbellContext]
exten => OriginateSound,1,Answer
exten => OriginateSound,n,System(asterisk -rx "channel originate Local/callpaging@PlayDoorbellContext/n extension playsound-custom@PlayDoorbellContext")
exten => OriginateSound,n,Hangup

;exten => callpaging,1,Set(CALLERID(name)=Doorbell)  ;The system does not accept anonymous phone calls so I had to set callerid. This line is just to set the name. This line is not used.
exten => callpaging,1,Set(CALLERID(all)=Doorbell <PhoneSystem>) ;The system does not accept anonymous phone calls so I had to set callerid. This line sets both name and number fields and is used.
exten => callpaging,2,Page(SIP/903)  ;Calls just my desk phone for testing. Can use multiple extensions by using "&" (e.g. SIP/903&SIP/907) or a ring group (e.g. local/900@from-internal)
exten => callpaging,3,Hangup

exten => playsound-custom,1,Answer
exten => playsound-custom,2,Wait(1)
exten => playsound-custom,3,Playback(custom/Doorbell)
exten => playsound-custom,3,Hangup

The FreePBX system does not accept anonymous calls into the system, I was getting "Got SIP response 433 “Anonymity Disallowed” followed by “Everyone is busy/congested at this time”, so I had to specify a Caller ID string to go with the Page application.

I was able to expand this to other extension numbers with different sounds as well for when I try to automate our post office mailbox to notify us when the mail has been delivered:

[from-internal]
exten => 26670,1,Goto(PlayUSPSMailboxContext,OriginateSound,1)

[PlayUSPSMailboxContext]
exten => OriginateSound,1,Answer
exten => OriginateSound,n,System(asterisk -rx "channel originate Local/callpaging@PlayUSPSMailboxContext/n extension playsound-custom@PlayUSPSMailboxContext")
exten => OriginateSound,n,Hangup

;exten => callpaging,1,Set(CALLERID(name)=Doorbell)  ;The system does not accept anonymous phone calls so I had to set callerid. This line is just to set the name. This line is not used.
exten => callpaging,1,Set(CALLERID(all)=USPS Mailbox <PhoneSystem>) ;The system does not accept anonymous phone calls so I had to set callerid. This line sets both name and number fields and is used.
exten => callpaging,2,Page(SIP/903)  ;Calls just my desk phone for testing. Can use multiple extensions by using "&" (e.g. SIP/903&SIP/907) or a ring group (e.g. local/900@from-internal)
exten => callpaging,3,Hangup

exten => playsound-custom,1,Answer
exten => playsound-custom,2,Wait(1)
exten => playsound-custom,3,Playback(custom/bluesclues_mail)
exten => playsound-custom,3,Hangup

The next step would be to find a way for Hubitat to run a remote shell command to the FreePBX system when a sensor is triggered, but that would be better posted on home automation forums.

Thanks again for your help.

I think that is your ITSP, not FreePBX.

This assumes you were dialling out through a trunk.

To my knowledge, FreePBX has anonymous inbound SIP calling turned off by default:

Most likely it was due to the IP phone itself configured to reject anonymous calls:
IPPhoneConfig

Looks good. One minor suggestion, this part:

can be done in the GUI with a Custom Destination and Misc Application. You would create a Custom Destination using the exact same goto string PlayUSPSMailboxContext,OriginateSound,1, and then a Misc Application of 26670 referencing the Custom Dest. What you’ve done is correct, but perhaps less obvious to anyone logging in after you. Using the GUI also comes with some protection against using that dial sequence (26670) for something else.

There has been a bit of discussion here about automation and node red:
Fun with AMI (node-red)
Fun with AMI Node-Red 2
Open Source Pro Tips #9 - Connecting to & Controlling FreePBX with Node-RED: Part 1
Open Source Pro Tips #10 - Connecting to & Controlling FreePBX with Node-RED: Part 2

Home automation and FreePBX comes up from time to time on the OSS Lounge as well

1 Like

Thank you @lgaetz, I implemented your suggestion by removing the extensions from the custom dial plan and added them with Custom Destinations and Misc Applications. They work great.

Regarding the home automation side of things, I will look into the links you provided. I’m scared to even think about Node-Red and its complexity, but that doesn’t mean I’m not going to try to figure things out and give it a go.

I was able to get some of this to work with my Hubitat with the use of EventGhost set up and configured like this: [PORT] - Send Events to EventGhost
That too works nicely, but eventually I would like to move everything to one platform if I can, so I’ve been looking into Home Assistant and Node-Red for that reason.

Currently I am trying to execute a remote ssh command into the FreePBX system. When I try to run this:

ssh root@IPBXSYSTEM asterisk -rx "channel originate Local/callpaging@PlayDoorbellContext/n extension playsound-custom@PlayDoorbellContext"

I get the following error:

No such command 'channel' (type 'core show help channel' for other possible commands)

I believe it has something to do with the double quotes and ssh trying to evaluate part of the command string instead of the entire string, but I do not have experience of running remote ssh commands.

From the asterisk cli

module show like originate

there should be two modules running, from a shell

ls /usr/lib*/asterisk/modules/*orig*

@dicko Indeed, I see two modules from the output below:

IPBXSYSTEM*CLI> module show like originate
Module Description Use Count Status Support Level
app_originate.so Originate call 0 Running core
res_clioriginate.so Call origination and redirection from th 0 Running core
2 modules loaded

And I see two shared object files as well:

[root@IPBXSYSTEM ~]# ls /usr/lib*/asterisk/modules/*orig*
/usr/lib64/asterisk/modules/app_originate.so
/usr/lib64/asterisk/modules/res_clioriginate.so

I’m not sure on the proper syntax, but when I tried either file, I get a Segmentation Fault:

[root@IPBXSYSTEM ~]# /usr/lib64/asterisk/modules/app_originate.so "Local/callpaging@PlayDoorbellContext/n extension playsound-custom@PlayDoorbellContext"
Segmentation fault

They are not executable, the asterisk command line has ‘tab completion’ so type

channel

(Then hit the tab key a helpful list of options will present so type …)

originate

(then the tab thing again,.) and so on, you should not need any 'newlines (\n) and when you are done the command should be committed , you can wrap the working line with single or double quotes and call the same from a shell

rasterisk -x “channel originate . . . .”

(asterisk -rx “channel originate . . . .”)

@dicko The copy/paste bandit strikes again. :man_facepalming: The /n ‘new line’ was remnants from the code from the StackOverflow page that helped initially.

Once the ‘/n’ was removed, I could run the command successfully locally :

asterisk -rx "channel originate Local/callpaging@PlayDoorbellContext extension playsound-custom@PlayDoorbellContext"

Next, I took your suggestion of encapsulating the asterisk-specific string in the command with single quotes, and now I can successfully execute the command from a remote system:

ssh root@IPBXSYSTEM asterisk -rx '"channel originate Local/callpaging@PlayDoorbellContext extension playsound-custom@PlayDoorbellContext"'

To update everyone with the suggestions and changes, here is the updated functioning code:

[from-internal-custom]
;exten => 26669,1,Goto(PlayDoorbellContext,OriginateSound,1)											;Not used. Instead, I created Custom Destination combined with a Misc. Application with the FreePBX web interface.
;exten => 26670,1,Goto(PlayUSPSMailboxContext,OriginateSound,1)											;Not used. Instead, I created Custom Destination combined with a Misc. Application with the FreePBX web interface.

[PlayDoorbellContext]
exten => OriginateSound,1,Answer
exten => OriginateSound,2,System(asterisk -rx "channel originate Local/callpaging@PlayDoorbellContext extension playsound-custom@PlayDoorbellContext")
exten => OriginateSound,3,Hangup

;exten => callpaging,1,Set(CALLERID(name)=Doorbell)	 													;Some phones are configured not to accept anonymous calls, so I had to set callerid. This line is just to set the name. This line is not used.
exten => callpaging,1,Set(CALLERID(all)=Doorbell <PhoneSystem>)											;Some phones are configured not to accept anonymous calls, so I had to set callerid. This line sets both name and number fields and is used.
exten => callpaging,2,Page(Local/903@from-internal,i,q,n,5)												;Calls just my desk phone for testing. 
;exten => callpaging,2,Page(Local/900@from-internal,i,q,n,5)											;Or, can use a paging/ring group (e.g. local/900@from-internal)
;exten => callpaging,2,Page(SIP/901&SIP/902&SIP/903&SIP/904&SIP/905&SIP/906&SIP/907&SIP/908,i,q,n,5)	;Or, can use multiple extensions by using "&"
exten => callpaging,3,Hangup

exten => playsound-custom,1,Answer																		;This extension plays specific sounds over paging/intercom system
exten => playsound-custom,2,Wait(1)
exten => playsound-custom,n,Playback(custom/House-bell-sound-effect)
;exten => playsound-custom,n,Playback(custom/TOS_commwhistle)
exten => playsound-custom,n,Hangup

[PlayUSPSMailboxContext]
exten => OriginateSound,1,Answer
exten => OriginateSound,2,System(asterisk -rx "channel originate Local/callpaging@PlayUSPSMailboxContext extension playsound-custom@PlayUSPSMailboxContext")
exten => OriginateSound,3,Hangup

;exten => callpaging,1,Set(CALLERID(name)=Doorbell)	 													;Some phones are configured not to accept anonymous calls, so I had to set callerid. This line is just to set the name. This line is not used.
exten => callpaging,1,Set(CALLERID(all)=USPS Mailbox <PhoneSystem>)										;Some phones are configured not to accept anonymous calls, so I had to set callerid. This line sets both name and number fields and is used.
exten => callpaging,2,Page(Local/903@from-internal,i,q,n,5)												;Calls just my desk phone for testing. 
;exten => callpaging,2,Page(Local/900@from-internal,i,q,n,5)											;Or, can use a paging/ring group (e.g. local/900@from-internal)
;exten => callpaging,2,Page(SIP/901&SIP/902&SIP/903&SIP/904&SIP/905&SIP/906&SIP/907&SIP/908,i,q,n,5) 	;Or, can use multiple extensions by using "&"
exten => callpaging,3,Hangup

exten => playsound-custom,1,Answer																		;This extension plays specific sounds over paging/intercom system
exten => playsound-custom,2,Wait(1)
exten => playsound-custom,n,Playback(custom/BlueCluesMail)
;exten => playsound-custom,n,Playback(custom/homermail_here)
exten => playsound-custom,n,Hangup

As suggested by @lgaetz, I created Custom Destinations in the FreePBX web interface:

And a Misc. Application to match via the FreePBX web interface:

Everything works great now! For now I am using EventGhost with a Hubitat port-over method that receives http messages from the Hubitat when a sensor is triggered. From there, it will play a sound over the paging/intercom system in the house depending on what sensor was triggered via the plink.exe application.

I did have to save public ssh keys on the FreePBX server in order for plink to execute the command(s) remotely.

Thank You Everyone for your help!! :grin::grin::grin:

1 Like

Everything good apart from you are enclosing double quotes within single quotes, if there are any system ‘$variables’ in the string you will need to double quote (without single quotes involved). On the other hand if it is purely static string, use single quotes without double quotes or double quotes without single quotes. ( not to mention the need to ‘quote’ single or double quotes in otherwise so quoted strings :wink: )

That might sound like gobbledygook, but please understand that ignorance here will bite you in the butt sooner rather than later.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.