How to send various types of notifications on an incoming call in FreePBX

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

PLEASE NOTE: When you look at examples in this article, be aware that WordPress has a nasty habit of changing quotation marks to “prettified” quotes, which WILL NOT WORK. So, unfortunately, if you copy an example line or code block, you may need to go through and change the quotation marks back to the “real” quotes that most software understands. I get SO sick and tired of WordPress changing my articles on me!

Every so often I’ve had someone ask if they could be sent some sort of notification whenever they get an incoming call. It is, although it will send a notification on any incoming call, not just a missed one (if you only want notifications of missed calls, look toward the bottom of this article). The basic technique is as follows:

First, create or edit a Follow-Me for the user’s extension. Let’s say the extension number is 1122. In the Follow-Me, add a line that looks like this:

****1122#

Note you can use about anything in place **** followed by the extension number and # sign — only the trailing # must be there — but I do it that way so I can keep track of what’s going on.  If you are creating the Follow-Me for the first time, be sure to also put your actual extension number in the Follow-Me list (with NO trailing # sign), and check the other Follow-Me options to make sure that they are what you want (for example, that the “Destination if no answer” is your voicemail, if that’s what you want).

Next, in /etc/asterisk/extensions_custom.conf, find the [from-internal-custom] context (it’s right at the top of the file) and add lines similar to the ones shown below to the bottom of that context. Again, we are using 1122 as the extension, but replace it with the actual extension number:

Note that some of these examples depend on certain other software being present. Also, the FIRST line in each sequence must have the line number 1, but if you use more than one of these for an extension, replace the 1 with n in subsequent lines.

To send an e-mail or SMS message (the mail command must function properly from the Linux command prompt for this to work):

exten => ****1122,1,TrySystem(echo "Call from ${CALLERID(name)} at ${CALLERID(number)} received ${STRFTIME(${EPOCH},,%l:%M:%S %p %Z on %A %B %e)}" | mail 9995559999@yourcarrier.com)

Replace 9995559999@yourcarrier.com with the e-mail address (which could be an e-mail to SMS gateway – most wireless carriers have one. Just search for “Email to SMS Gateway” and add your carrier’s name to the search, and you should find the format to use).  You can use “System” or “TrySystem” in the line above, the difference being that TrySystem is non-blocking, so the call should not be delayed if the process of sending the e-mail bogs things down.

To send an instant message using the XMPP/Jabber protocol — for this to work /etc/asterisk/xmpp_custom.conf (/etc/asterisk/jabber.conf in older versions of FreePBX) must be configured correctly, and there must NOT be a noload => res_jabber.so statement in modules.conf:

exten => ****1122,1,JabberSend(asterisk,username@gmail.com,Call from ${CALLERID(name)} at ${CALLERID(number)} received ${STRFTIME(${EPOCH},,%l:%M:%S %p %Z on %A %B %e)})

In the above, asterisk is the account context in xmpp_custom.conf or jabber.conf, and username@gmail.com is the address of the XMPP/Jabber user you want to send the IM to (in this case we assume you and the user are on Google Chat, but you could use any other XMPP/Jabber-based IM service, including a local XMPP/Jabber server set up with Prosody or Openfire or similar software. EDIT: If you are running FreePBX on a Raspberry Pi, see this article and this thread for information on setting up a Prosody server).

If you have Kodi (formerly XBMC) running on a system on your local network, you could use a line such as this to send notifications to it (EDITED to include Kodi Leia, Matrix, and Nexus):

In Eden and other Pre-Frodo versions:

exten => ****1122,1,TrySystem(wget -b -O /dev/null -o /dev/null "http://192.168.0.234:8080/xbmcCmds/xbmcHttp?command=ExecBuiltIn&parameter=XBMC.Notification(Call%20from%20%22${URIENCODE(${CALLERID(name)})}%22%2C${CALLERID(number)}%20calling%20extension%2C15000%2C%2Fhome%2Fusername%2Fphone.png)")

In Frodo through Krypton:

exten => ****1122,1,TrySystem(wget -b -O /dev/null -o /dev/null "http://192.168.0.234:8080/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22GUI.ShowNotification%22,%22params%22:{%22title%22:%22Call%20from%20${URIENCODE(${CALLERID(name)})}%22,%22message%22:%22${CALLERID(number)}%20calling%20extension%22,%22displaytime%22:15000,%22image%22:%22%2Fhome%2Fusername%2Fphone.png%22},%22id%22:1}")

In Leia, Matrix, Nexus and probably later versions, until they decide to change it again:

exten => ****1122,1,TrySystem(curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"Call from ${CALLERID(name)}","message":"${CALLERID(number)} calling extension","displaytime":15000,"image":"/home/username/phone.png"},"id":0}' http://192.168.0.234:8080/jsonrpc)

Note: If you set Kodi to require authentication, then in place of the example http://192.168.0.234:8080/jsonrpc instead use the format http://kodiusername:password@ip-address:port/jsonrpc where kodiusername, password and port are the same values you used when setting up your Settings | Service | Control | Web Server settings in Kodi. Note that “kodiusername” is the user name set up in Kodi’s web server settings, and is probably not the same as “username” in the phone.png icon path (which in that case is the name of the user’s home directory).

Note that each of the above is a single long line, and to see any of those lines in its entirety you will need to copy and paste it to a text editor. The above examples assume that Kodi is configured to allow control via a Web interface, at a fixed IP address and port (192.168.0.234 port 8080 in this example). Phone icon - right click and copy imageIf you happen to still have a Linux version of Boxee, the Eden version line might also work with it, perhaps with a bit of tweaking.  I have no idea if it would work (with appropriate modification) with any other standalone home theater PC equipment.  You will likely need to replace username with the user’s name, extension with the called extension’s number, and change the icon path to wherever you put the phone.png file (which is an icon you need to supply, such as the one at the right). Note that the icon path requires %2F in place of forward slashes in pre-Leia versions (therefore %2Fhome%2Fusername%2Fphone.png really means /home/username/phone.png) and this refers to the icon directory and filename — if you choose not to use an icon then leave out this part, depending on your Kodi version:

Eden and prior: %2C%2Fhome%2Fusername%2Fphone.png
Frodo through Krypton: ,%22image%22:%22%2Fhome%2Fusername%2Fphone.png%22
Leia through Nexus (and beyond?): ,"image":"/home/username/phone.png"

Note the comma at the start; it must be included in the deleted section).  By the way, if you are wondering why it had to be changed again for Kodi Leia, see this thread in the Kodi forum.

If you want to receive Caller ID popup notifications on your computer, see A Perl script to send Caller ID popups from Asterisk to computers running Notify OSD (such as Ubuntu Linux) or any command-line invoked notification system and/or A Perl script to send Caller ID popups from Asterisk to computers running Growl under OS X on a Mac or Growl for Windows.  These articles are a bit dated and may not be compatible with some of the newer notification methods in use (such as the Notification Center used in MacOS that was introduced in OS X 10.8); in such cases it may be easier to just send instant messages to the computer as described above, although it may be possible to ssh into the computer and send a notification from the command line – this article describes how to send a notification from the command line in MacOS.

After using the any of above lines (and, again, remember to change the line number from 1 to n on any lines after the first), you may want to include a statement like this:

exten => ****1122,n,NoCDR()

That should prevent Asterisk from creating a separate, usually unwanted CDR entry for the ****(extension number) call.  There will still be a CDR record created for the actual call. EDIT: Actually, if you are going to use this, you probably should make it line 1, and move it above the other ****(extension number) lines, so that the CDR record is not saved even if the call gets disconnected in the middle of sending the notification. EDIT 2: In recent Asterisk versions NoCDR() has been deprecated and replaced by CDR_PROP(disable) so be sure to make that change if you are getting BUSY lines in the CDR when this runs.

Finally, to end this part of the context, you need to include a statement that ends the call in a “not completed” state, so that any other extensions in the Follow-Me will be called.  A couple of possibilities are:

exten => ****1122,n,Congestion
exten => ****1122,n,Busy

Use one and if it doesn’t work as expected, try the other. On my system it appears either will work. Remember that you must do a configuration reload in FreePBX before any of your changes to extensions_custom.conf will take effect!

One reason you may want to do instant message or SMS notifications is if you are forwarding calls via a trunk that does not preserve the original caller’s Caller ID.  If you were forwarding the call to a smart phone (perhaps one that also has a Jabber client running), you could deliver the original caller’s name and number to the phone via instant message or SMS.  It may or may not arrive in time for you to make a decision on whether to answer the call, but if you chose not to answer you’d at least know within a few seconds to a few minutes who the call was from, and you could decide whether to call them back.

If you have figured out any neat tricks to do other types of notifications, or if you know of a way to send a notification only when a call was not answered, feel free to leave a comment.

EDIT: At one time this page showed a method for sending SMS notifications using Google Voice rather than an e-mail to SMS gateway. Unfortunately it appears that the unofficial API that was used by such applications is no longer functional. If you know of a way to send a SMS message from a Linux command prompt using Google Voice that is currently working, please leave a message in the comments!

EDIT: I did think of a couple of techniques that might work for sending a notification only if the call is “missed” — the first is a bit of a hack, and has a serious limitation in that if the caller hangs up prior to the call going to voicemail, no notification would be sent (which might or might not be what you want). Basically, you would create (or modify) a Follow-Me as described above, but don’t put the ****extension# line in it. Instead of making the “Destination if no answer” your voicemail (for example), you would point it to a Ring Group that you have created, and in that Ring Group you would place the ****extension# line, and make the “Destination if no answer” of the ring group your voicemail. So the Follow-Me would ring your extension(s) for the number of seconds in the “Ring Time” setting, but if that time expires and no one answers, the call would be sent to the Ring Group where the only “extensions” would be your ****, which would do their thing and immediately return a “busy” or “congestion”. Since there are no other extensions to try, the Ring Group should immediately pass the call on to its “Destination if no answer”, which would most likely be your voicemail.

I haven’t tested this but I see no reason why it would not work, and in that case the notification would be sent just as the caller is being transferred to voicemail. If the caller doesn’t stick around that long you don’t get a notification, however, the fact that you do get a notification doesn’t necessarily mean that the caller actually left a voicemail — if they hang up during the voicemail greeting, a notification would still have already been sent.

EDIT: Here is a different technique for sending notifications on ONLY missed calls, and with this one the notification is sent whether the caller sticks around to leave a voicemail or not. You do NOT add anything to your Follow Me list when using this technique, nor do you modify extensions_custom.conf.

Note that this technique probably will not work on extensions that are part of a Ring Group or Follow Me where more than one extension is rung simultaneously (at least not without some modification — it should work if you use a ring strategy that only rings one phone at a time, though, such as firstnotonphone or firstavailable) (2017 EDIT: Some users have reported those two ring strategies are broken in FreePBX 13 and 14). Be aware that this one is a bit riskier since you will need to re-do the first part of the following procedure after any FreePBX upgrade, otherwise things may break!

  • Load the /etc/asterisk/extensions.conf file into a text editor such as nano
  • Search (Control-W in nano) for the string [from-internal] (including the brackets)
  • Copy the entire context (you can omit the comments) to a new open page in a text editor on your local computer
  • Next, search for the string [from-did-direct] (including the brackets)
  • Also copy that entire context (without the comments) to the same open page in your text editor
  • You MAY also need to copy the context [macro-hangupcall] which is found in /etc/asterisk/extensions_additional.conf. You would do that the same way as the previous two. I don’t show it in the examples below, but further down I’ll explain why you might need to do that one.

At this point the open page in your text editor will look something like this, although this may vary depending on your version of FreePBX. It is important that you copy these contexts from YOUR system, and repeat the procedure every time you upgrade FreePBX to a newer version:

[from-internal] include => from-internal-noxfer
include => from-internal-xfer
include => bad-number ; auto-generated

[from-did-direct] include => ext-findmefollow
include => ext-local

Now add these two lines to the bottom of EACH of the above two contexts (or all three if you also added [macro-hangupcall]):

exten => h,1,Macro(missed-call)
exten => h,n,hangup

The above is the part you will need to redo if you upgrade FreePBX. Next, add a new macro that looks something like this (this is just an example, don’t copy it verbatim!):

[macro-missed-call]
exten => s,1,NoOp(Checking to see if we need to send a missed call notification)
exten => s,n,GotoIf($["${CT_EXTEN}" > "1121" & "${CT_EXTEN}" < "1125" & "${CT_EXTEN}" != "" & "${ANSWEREDTIME}" = ""]?notify1)
exten => s,n,MacroExit()
exten => s,n(notify1),NoOp(Sending notification of missed call on extension ${CT_EXTEN})
exten => s,n,ExecIf($["${CALLERID(num)}" > "1121" & "${CALLERID(num)}" < "1125"]?MacroExit())
exten => s,n,ExecIf($["${CALLERID(num)}" = "8005551212"]?MacroExit())
exten => s,n,JabberSend(asterisk,username@gmail.com,Missed call from ${CALLERID(name)} at ${CALLERID(num)} for extension ${CT_EXTEN} received ${STRFTIME(${EPOCH},,%l:%M:%S %p %Z on %A %B %e)})
exten => s,n,MacroExit()

Here’s an explanation of what’s happening in the above Macro, so you can modify it for your specific needs:

  • Line 1 is just a NoOp that tells what the macro is doing.
  • Line 2 says that if the call was for extensions 1122 through 1124 (greater than 1121 and less than 1125), that we didn’t get a null value for the extension, and the call was not answered, go to the label notify1. If we only wanted to test for a single extension such as 1122, instead of “${CT_EXTEN}” > “1121” & “${CT_EXTEN}” < “1125” just use “${CT_EXTEN}” = “1122”. You can add as many lines as you need for various extensions, just be sure to jump to different labels.
  • Line 3 says that if none of the above conditions match, exit the macro.
  • Line 4 is just a NoOp that serves as a placeholder for the label and prepares to send the notification.
  • Line 5 is optional and shows how to exclude notifications for calls if the calling number is within a range, in this case 1122-1124 (so, in this example no notifications would be made on calls from one of your own extensions to another in the 1122-1124 range). You can use as many of these lines as you need to exclude more ranges, or none at all if you don’t want to exclude any ranges. Make sure you get the quotation marks right (and again, if you copy lines from this blog, beware of the quotation marks that WordPress has “prettified” – you’ll need to fix them before the lines will work!).
  • Line 6 is optional and shows how to exclude a specific number from triggering the notification. In this case, if the call comes from 8005551212, no notification would be sent. Note that you could use the ${CALLERID(name) variable as a trigger also, and exclude calls from certain names from triggering a notification. Note you can place multiple tests in the same expression by using the bar character (logical OR in Asterisk) to connect them, for example, “${CALLERID(num)}” = “8005551212” | “${CALLERID(name)}” = “INFORMATION” would match if either condition were true. This line can be omitted completely if you don’t want to exclude calls from any specific numbers.
  • Line 7 is where we actually send the notification. Basically any of the methods mentioned in the previous part of this article can be used here, just replace ****1122,1, in the example lines with s,n,
  • Line 8 is where we gracefully exit the macro. Of course, you can repeat lines 4-7 as many times as needed if you are doing notifications for more than one extension.

Now that you have the three (or four) macros in your text file and edited as they should be, copy the whole mess and paste it into the existing file /etc/asterisk/extensions_override_freepbx.conf — do not just overwrite the existing file! Instead, open it with nano or another text editor and paste in the lines you’ve been working on. Also, do a quick scan to make sure you haven’t duplicated a context that’s already in there (the likelihood of that is pretty remote unless you have done something like this in the past). Note that after you do a FreePBX reload, the contexts in this file will replace the equivalents in the files generated by FreePBX, so that’s why you have to check that the originals haven’t changed each time you upgrade FreePBX.

If you want to know what variables are available for you to trigger on, instead of a line sending a notification you can use a line like this:

exten => s,n,DumpChan

This will show you a lot of information, including how several of the channel variables are set.

One final note, the added macro call under [from-internal] is the one that would be taken after a failed call from another extension, while the one under [from-did-direct] is the one used by failed calls coming in from outside the system. Note that most answered calls (not including ones that go to voicemail) will wind up in [macro-hangupcall] and not go through either of those, BUT in certain circumstances unanswered calls might also end via [macro-hangupcall], such as if they go through a ring group. That is why I mentioned above that you might need to include [macro-hangupcall] along with the other contexts copied into /etc/asterisk/extensions_override_freepbx.conf. However, I have not tested every possible condition, and I do know that some things won’t work — such as if multiple extensions are rung simultaneously, no extension number shows up in the ${CT_EXTEN} variable, so those tests in [macro-missed-call] that depend on that variable being set will fail. You may be able to modify the macro so that it will work in such circumstances by using one or more variables you can find by using DumpChan, but that’s a piece of dialplan I’m not prepared to write, since I personally have no need for it (and have already spent way too much time on this)!

I probably should also include this note about the use of extensions_override_freepbx.conf as taken from this page:

If extensions.conf (or extensions_additional.conf) has a context or macro that you NEED to modify, you place that code here as asterisk will only execute the first occurrences of that code and ignores other occurrences. This file will not be overwritten. Be very careful as replacing an existing piece of code this way is the fastest possible way to break your system. If you are doing this you should probably think about filing for a feature request or bug fix to get it addressed properly.

Of course, my experience is that filing a feature request with FreePBX is a great way to either be ignored, or lectured by some a**h*le on why you don’t need that feature, so I wouldn’t bother. Just be sure that if you upgrade FreePBX, or even just the Core or Framework modules, you check to make sure that the contexts you’ve copied into extensions_override_freepbx.conf haven’t been changed (or if they have, make sure you copy over the changes).

Asterisk 1.8.x and FreePBX users: How to NOT answer Google Voice calls UNTIL the called extension answers

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

EDIT (May, 2018): FreePBX and Asterisk users that wish to continue using Google Voice after Google drops XMPP support should go here: How to use Google Voice with FreePBX and Asterisk without using XMPP or buying new hardware.

This article was originally published in December, 2010 and may contain out-of-date information.

Many folks are experimenting with Asterisk 1.8.x and Google Voice.  In most cases the way it’s set up is that when a Google Voice call arrives, Asterisk answers the call, then sends a touch-tone digit “1” to Google Voice to answer the call, then proceeds to ring the destination extension.  This is necessary because when you configure Google Voice to use a Gtalk destination, they require you to press “1” to accept the call, even if you’ve configured Google Voice not to require that.  I don’t know if this is a bug in Google Voice or if they did it that way deliberately for some reason, but answering the call and accepting it upon arrival at the PBX has a few unintended side effects:

  • If your callers pay for long distance by the minute, they get charged from the moment the called extension begins ringing – even if you never answer the call.
  • You can’t use Google Voice’s Voicemail, nor their transcription service, because you’ve already answered the call.
  • Callers may hear a confusing double ringing tone at the start of ringing — one ring from Google Voice and the rest from Asterisk.

On the other hand, there are some advantages to doing it that way:

  • Because you’ve answered the call, you can let the extension ring as long as you like before sending it to voicemail, and Google Voice won’t snatch it away in 25 seconds and send it to their voicemail.
  • You can use Asterisk’s voicemail, if that’s what you prefer.

For those who’d prefer to let Google Voice handle their voicemail, or who object to making callers pay to listen to up to 25 seconds of ringing, there is a way to not answer the call and send the touch tone “1” until  after the destination extension has actually picked up the call.  If you are using plain vanilla Asterisk, all you have to do is make sure your Dial() command contains two additional options.  Consider this example line of Asterisk dialplan:

exten => gvoicein,n,Dial(SIP/1004,35,rTWtwaD(:1))

The important part here is the aD(:1) — the other options can be whatever you’d normally use, if any, but it’s the aD(:1) that does the magic. Now at this point, if you’re a FreePBX user you may be wondering how on earth you can modify the Dial() string, since the code that generates it is buried deep within the bowels of FreePBX. Fortunately, there is a way. Consider the following piece of code that might be used in extensions_custom.conf to bring in Google Voice calls:

[googlein]
exten => _[0-9a-z].,1,Noop(Incoming Google Voice call for ${EXTEN})
exten => _[0-9a-z].,n,Set(CALLERID(name)=${CUT(CALLERID(name),@,1)})
exten => _[0-9a-z].,n,GotoIf($["${CALLERID(name):0:2}" != "+1"]?notrim)
exten => _[0-9a-z].,n,Set(CALLERID(name)=${CALLERID(name):2})
exten => _[0-9a-z].,n(notrim),Set(CALLERID(number)=${CALLERID(name)})
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,Answer
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,SendDTMF(1)
exten => _[0-9a-z].,n,Goto(from-trunk,gv-incoming-${CUT(EXTEN,@,1)},1)
exten => h,1,Macro(hangupcall,)

With this context you’d use gv-incoming-username (where username is the part of the associated gmail address before the @) as the DID in your inbound route — a DID doesn’t have to be numeric even if FreePBX whines about it, and the advantage is you only need one context to handle incoming calls for all your Google Voice accounts.  This particular context is slightly modified from one found in the PBX in a Flash forum, but note that it contains these four lines that wait ONE second, answer the call, wait ONE second (you do NOT have to wait two seconds, despite what any other article may say, and in fact the one second wait might be unnecessary), and then send the touch tone digit 1:

exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,Answer
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,SendDTMF(1)

You will find those four lines, or some variation on them (sometimes just the last three), in just about every published method for using Google Voice with Asterisk and FreePBX.  But, in FreePBX at least, you can replace them with this:

exten => _[0-9a-z].,n,Set(DIAL_OPTIONS=${DIAL_OPTIONS}aD(:1))

This slides the aD(:1) into the options that will be used with the Dial command, so when the extension answers, the call will be answered and then the touch tone “1” will be immediately sent to Google Voice, and then the audio between Google Voice and the called extension will be bridged as usual.

Unfortunately, or maybe fortunately depending on your point of view, it appears that if the call should go to Asterisk’s voicemail, the call will not be answered and the DTMF 1 will never be sent.  This means that if, for whatever reason, you don’t answer the incoming call, after 25 seconds it will go to Google’s voicemail.  There are doubtless ways around that (and if anyone’s truly interested, leave a comment and I’ll suggest a way that may work, that involves routing the incoming call to a ring group first) but I suspect that the majority of people who want to do this will be doing it because they want to use Gmail’s voicemail.

I’ve tested this and it works for me, though I would not use it on a regular basis because I prefer Asterisk’s voicemail.  If it doesn’t work for you for some reason, the only suggestion I can offer is adding a w before the :1, so the added options look like aD(w:1) – that will add a one-half second delay before the “1” is sent, and more than likely it won’t help one bit, but may cause callers to not hear your “hello” or other greeting.  But, you can try it and see — at least one user has reported it to be necessary.  If that doesn’t work, I probably won’t be able to help you but if you leave a comment, maybe someone else can.

And, should anyone from Google Voice read this, it would be really helpful if you’d do two things:

  1. Give us a way to disable Google Voice’s voicemail so we don’t have to resort to hacks like this to discourage callers from leaving a message there.
  2. Fix the bug (or “feature”) so that when we turn off call screening, it’s off for ALL destinations, including Gtalk!