How it used to be done: How to use Google Voice for free outgoing calls on an Asterisk/FreePBX system (the no-XMPP way)


This article contains text excerpted from 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. Certain edits, including those in the green boxes below, were made on or after December 1, 2013.

EDIT (May 23, 2018): This post is seriously outdated. For more recent information, see How to use Google Voice with FreePBX and Asterisk without using XMPP or buying new hardware. You may also wish to visit this thread at DSLReports for additional information.

It appears that some people are getting upset because Google is dropping the use of its XMPP protocol with Google Hangouts, and there is much speculation that they might drop XMPP support altogether, which could break the method used by PBX software (such as Asterisk, FreeSWITCH, or Yate) and even some hardware to connect to Google Voice.

We would just like to remind everyone that back in the ancient days of Google Voice, Asterisk users had another way to initiate Google Voice calls that did not involve the use of XMPP. While we do not suggest attempting to use this method today, unless absolutely nothing else works, we are reposting a portion of the original instructions here. Again, please note that this method is being reposted as a matter of historical interest only (see this article for more recent recommendations). It is just intended to show that it used to be possible to connect outgoing calls using Google Voice, but without using XMPP.

This method was used by those using Asterisk and FreePBX that wanted to enable free Google Voice outgoing calls. It was assumed that you already had a Google Voice number and has it coming into your system via an Inbound Route (that is, you had it forwarded to a DID that came into your system, that was then handled by an Inbound Route).

Before you began the process, you had to make sure that your Google Voice account was set up correctly.  In your Google Voice account, under the Settings link, Calls tab, you had to make sure the following four options on that page were set up as follows:

Call Screening: Off
Caller ID (in): Display caller’s number (very important!)
Do Not Disturb: Make sure this is unchecked!
Call Options: Make sure this is unchecked!

You also needed to install some Python additions and the pygooglevoice program, assuming you had not done so previously.  Under CentOS you’d do the following from a command prompt:

cd /root
yum -y install python-setuptools
easy_install simplejson

If (and only if) you receive a series of error messages while attempting to install simplejson, it may be because your system is running an older version of Python, such as version 2.4 (if some of the error lines contain the string “python2.4”, this is almost certainly the problem). In that case, you can try this (note that the first line might be split into two lines on your display, but should be entered as a single line):

tar xzvf simplejson-2.0.9.tar.gz
cd simplejson-2.0.9
sudo python install

You’d then download the latest version of pygooglevoice and install it, using a line similar to this (this is all one line):


Then you’d extract and install pygooglevoice:

tar zxvf pygooglevoice-0.5
cd pygooglevoice-0.5
python install

There was also a patch that needed to be installed (again this is all one line):

sed -i 's||\&continue=|' /usr/lib/python2.4/site-packages/googlevoice/

The above was found in this thread in the PBX in a Flash forum, which explains why the patch was needed.

Then you’d open /etc/asterisk/extensions_custom.conf in a text editor and add two new contexts (assuming you were using Asterisk 1.6 or later):

exten => _X.,1,System(gvoice -e -p userpassword call ${EXTEN} gvregphonenum code &)
exten => _X.,n,Set(DB(gv_dialout_username/channel)=${CHANNEL})
exten => _X.,n,Wait(20)
exten => _X.,n,Noop(Never received callback from Google Voice on channel ${DB_DELETE(gv_dialout_username/channel)} – exiting)
exten => h,1,GotoIf($[“${CHANNEL(state)}” = “Ring”]?:bridged)
exten => h,n,Noop(Hangup on channel ${DB_DELETE(gv_dialout_username/channel)})
exten => h,n,System(gvoice -e -p userpassword cancel &)
exten => h,n,Hangup()
exten => h,n(bridged),Noop(The channel has been bridged successfully)

Replacing username with the name of the user associated with the Google Voice account (the name before in the associated Gmail account), userpassword with the password of the Google Voice account, gvregphonenumber with the registered phone number in Google Voice that you want to forward calls to (this had to be a number that came into your Asterisk/FreePBX box, and that you had already registered it as a destination in Google Voice, NOT your Google Voice number.  And sometimes you had to use just ten digits, other times you had to add the “1” at the start of the number, and that could vary from account to account so you just had to try and see which worked), and code with a single digit that was one of the following:  1-Home, 2-Mobile, or 3-Work (you’d just use the single digit, not the word, and when you registered the destination phone number with Google Voice you had to tell them if the number was a Home, Work, or Mobile, so the code would correspond to what you’d put there. Some people found that they could omit the code and it would still work, but that wasn’t always true).

In the System() calls it was important not to omit the space and ampersand just before the final parenthesis — this allowed the dial plan to move ahead rather than imposing extra and unnecessary delays on the caller.

One strange thing about this context was that the Noop line was NOT optional – things just didn’t work as expected if it was left out or commented out.

On one Asterisk 1.8 system, the following changes were necessary:

  1. The first instance of System(gvoice -e … had to be changed to System(sudo gvoice -e … (adding sudo before gvoice)
  2. In the file /etc/sudoers the following line had to be added: asterisk ALL = NOPASSWD: /usr/bin/gvoice
  3. The hangup portion of the context (everything below the first Noop statement) did not work as intended, and actually cancelled the Google Voice callback!. So it was changed to simply:

exten => h,1,Hangup

As you will see, the line that cancels an abandoned call was added to the second context. The first two changes were necessary because without them, Asterisk could not successfully execute the gvoice program, despite the fact that permissions were set to make it readable and executable by everyone.

The second context that had to be added in /etc/asterisk/extensions_custom.conf was this one:

exten => s,1,NoCDR()
exten => s,n,Bridge(${DB_DELETE(gv_dialout_username/channel)})

On one Asterisk 1.8 system it was found necessary to change the above context to read as follows:

exten => s,1,NoCDR()
exten => s,n,GotoIf($[${ISNULL(${DB(gv_dialout_username/channel)})}]?ext-did-0002,gvregphonenum,1)
exten => s,n,Bridge(${DB_DELETE(gv_dialout_username/channel)})
exten => s,n,System(sudo gvoice -e -p userpassword cancel &)
exten => s,n,Hangup()

The purpose of the line that begins with exten => s,n,GotoIf… is to correctly route the incoming call in case you initiated a callback from the Google Voice web page. The string gvregphonenum is replaced by the registered phone number in Google Voice that you are forwarding calls to, which should also be the same as the DID in your Inbound Route for Google Voice calls – this is NOT your Google Voice number! This line is optional, and note that it sends calls to the context ext-did-0002 in extensions_additional.conf, which could possibly be different in differently-configured versions or future versions of FreePBX. If it doesn’t work for you, you can leave the entire line out, but you won’t be able to initiate callbacks from your Google Voice page.

The purpose of the line that begins with exten => s,n,System… is to cancel the call in case the caller has hung up before the callback from Google Voice is received. If the call is not cancelled, weird stuff happens! You can omit the “sudo” if you did not find it necessary to add it above.

Again replacing all instances of username and userpassword with the name and password of the user associated with the Google Voice account. After saving those changes you would then go into the FreePBX GUI, go to the Tools menu, Custom Destinations module, and create a new Custom Destination. In the Custom Destination: text box you’d enter this string:


In the Description: field, you could use a meaningful description such as Google Voice Bridge username and then click on “Submit Changes.” After saving that you’d go into Trunk settings and create a new CUSTOM trunk with these settings:

Maximum Channels: set to 1
Dial Rules: Use what you like, it’s suggested that you at least add 1+NXXNXXXXXX but if your area allows seven digit dialing, you may also want to add one like 1areacode+NXXXXXX where areacode is replaced with your local three digit area code.
Custom Dial String: Set to Local/$OUTNUM$@custom-gv-trunk-username — once again, replace username with the name of the user associated with the Google Voice account.

Once you had created and saved this trunk, it could be used as a trunk selection for any USA/Canada Outbound Route.

One assumption was that you had already set up Google Voice to send incoming calls to your Asterisk system via a DID that did not change the incoming Caller ID number. Normally this would be accomplished by getting a DID from some provider (either a free one or one you paid for — it didn’t matter as long as they would pass incoming Caller ID number correctly). Once that was working, you’d create a second inbound route for that same DID, without changing the original in any way — this would be a new Incoming Route, which would be set it up as follows:

Description: Anything meaningful, such as Username Google Voice”.

DID Number: Same as on your other Inbound Route that handles your Google Voice traffic.

Caller ID number: This had to be be your Google Voice number (the one associated with your Google Voice account), but depending on how your DID provider sent Caller ID, you might have to specify it as either a ten or eleven digit Caller ID, or even +1 followed by ten digits.  Whatever format your DID provider used, you had to match their format, which sometimes meant watching the Asterisk CLI during a test call to see what format they used. If it didn’t match what they sent, it wouldn’t work.

Destination: the Custom Destination created above (e.g. Custom Destinations: Google Voice Bridge username).

No other settings of the Inbound Route were changed and in particular, you were advised not to set a CID Lookup Source because it would cause an unwanted delay in connection time and was totally useless in this route, and there’s no reason to do so since this route is only triggered when a single Caller ID comes in).

Once you had submitted these changes, you should have been able to add your Google Voice custom trunk as a trunk selection for one or more of your USA/Canada Outbound Routes.

If it didn’t work it was generally one of three things. Either the Custom Trunk hadn’t been specified as a destination in the appropriate Outbound Route, or the incoming Caller ID of the Google Voice call didn’t exactly match what you set up in the Inbound Route you created, or you got something wrong in extensions_custom.conf such as the username or password (or you missed a place where you were supposed to change one of those items).

For test purposes, you could go to a Linux command prompt (not a CLI prompt in Asterisk!) and try entering a gvoice command directly, using this format (note this is all one line):

gvoice -e -p userpassword call numbertocall gvregphonenum code

All of those values are as explained earlier, except for numbertocall, which had to be a USA or Canada phone number in 11 digit format.  Yes, the number to call had to be in 11 digit format (with the leading “1”) whereas the gvregphonenum might (or might not) need to be TEN digits (no leading “1”) – go figure.  If it worked from the command line then you needed to double check your values in extensions_custom.conf.  If it did not work from the command line, then either there was something wrong with your pygooglevoice installation, or with Python on your system (you had to have at least Python version 2.4 or higher), or you could have been using incorrect values (EDIT: Or, on some systems, it might be necessary to execute the gvoice command using sudo from within Asterisk, as described above).  And, some people got confused over the fact that that the “gvregphonenum” value was NOT supposed to be their Google Voice number, but instead the number to which Google Voice forwarded their calls, and it had to be a number that had been previously registered as a destination with Google Voice.

That’s the basics of how it was done. Note this is not intended to be a guide as to how to set this up now, since many things have changed since then. Just because this method worked back then does not mean it will still work today, and it’s definitely slower in the setup of calls than more recent methods. However, it is worth noting that at no point was the XMPP protocol used. It’s also worth mentioning that there are other programs that can interact with Google Voice besides PyGoogleVoice (see for example Google-Voice-PHP-API, google-voice-java, SharpGoogleVoice, voice.js, etc.) that may or may not be more suitable for use in this type of application.

51 thoughts on “How it used to be done: How to use Google Voice for free outgoing calls on an Asterisk/FreePBX system (the no-XMPP way)”

  1. Cam: No problem, feel free to use or modify what you need. Like you, we hope there is never any impetus to revert back to the older method, but it’s good to know that it could be done if circumstances change.

  2. Great. Will try this out. I have Asterisk running on Archlinux with xmpp . Will try this out.

    There are a few steps that you have provided that needs the freePBX GUI. Are you able to give more details on how to do it directly in the asterisk config files without the need for the GUI ? I do not have the GUI and hesitant to complicate my archlinux setup with it.

    1. Great tutorial! I need to make two changes, though.
      1. The new Python installation gives me Python2.7. The sed patch need to apply to /usr/local/lib/python2.7/dist-packages/googlevoice/ (for Debian).
      2. A change need to be made for “galx ,,,,” line in “/usr/local/lib/python2.7/dist-packages/googlevoice/” as described in “”.
      After that I have tested out the Py script and it works (with callcentric as DID).
      However, I have exactly the same question as Vasanth. Can we do this without using FreePBX? Actually, most of the things are straightforward. The only part I am not so sure is about what does the custom destination look like.
      Thanks again for your tutorial.

      1. The custom destination is shown in the article:

        exten => s,1,NoCDR()
        exten => s,n,Bridge(${DB_DELETE(gv_dialout_username/channel)})
        exten => s,n,System(sudo gvoice -e -p userpassword cancel &)
        exten => s,n,Hangup()

  3. i have been Voiping since 2006 (anyone out there remember STANAPHONE) and a $35 unlocked PAP2 then on to Gizmo and Grand Central
    all in all i have not paid for a call to the USA since 2007 but i know the regular easy menthods will dry op as they will not be able to keep their free incoming calls free with the google masses migrating and there are so few left

    i will probably go back to a Asterisk/FreePBX which i ran for fun on an old laptop
    not sure but i think i got lazy with a 2 line PAP2 and an Obi as i have 3 line so i hope its still that easy

  4. O.K. Thanks. So then, what does the FreePBX Tool Menu part:
    ” After saving those changes you would then go into the FreePBX GUI, go to the Tools menu, Custom Destinations module, and create a new Custom Destination. In the Custom Destination: text box you’d this string: custom-gv-inbound-username,s,1 ……”
    really do?
    What modification we need to do in the Asterisk .conf files to mimic this?

    1. FreePBX uses Inbound Routes to direct incoming calls. There is one “general” inbound route that is used for most calls coming in from your Google Voice number, as identified by the DID or the trunk it arrives on or whatever, but then you must create a second one that in addition identifies it by Caller ID. If the Caller ID matches YOUR Google Voice number, it takes an alternate path. As stated above:

      Caller ID number: This had to be be your Google Voice number (the one associated with your Google Voice account), but depending on how your DID provider sent Caller ID, you might have to specify it as either a ten or eleven digit Caller ID, or even +1 followed by ten digits. Whatever format your DID provider used, you had to match their format, which sometimes meant watching the Asterisk CLI during a test call to see what format they used. If it didn’t match what they sent, it wouldn’t work.

      Since you are writing your own dialplan, you’d need to create the “exception” route for calls that match on your GV Caller ID, and then add the NoCDR() and Bridge(${DB_DELETE(gv_dialout_username/channel)}) at the end of that. Since we never do anything in raw Asterisk, except for occasional short contexts in FreePBX’s extensions_custom.conf, we can’t really tell you exactly how to fit this into your dialplan, though it should be easy if you understand what’s happening.

  5. Thanks. I guess I would first install it with FreePBX and then figure out if and how can do using Asterisk only.
    One more question, for the codes inserted in conf files, are they valid for both Asterisk 1.8 and Asterisk 11? I am quite familiar with 1.8 but never using 11. However, it looks like 11 is the future for asterisk.

    1. twinclouds, we’d guess it would still work in Asterisk 11, but that’s only a guess. If you wanted to, you could install Asterisk 11 (perhaps on a virtual machine for temporary testing) and try it.

  6. The easier configuration of extensions.conf in plain asterisk can be as the following sample code with the corresponding sip.conf file. It uses a free Callcentric DID as callback number. All irrelevant functions are removed.

    ; =================sip.conf=====================================================
    context=sip ; Default context for incoming calls.

    register =>

    ;call centric

    ;All users
    ; =================end of sip.conf=====================================================

    ; ====================extensions.conf - the Asterisk dial plan=================================
    clearglobalvars=yes ;important: to clean up gvuser after finishing a call

    gvuser=0 ; initialize

    ;exten => _929xxxxxxx,1,ExecIf(${gvuser}!=0]?Bridge(${gvuser}):Dial(SIP/517,60,D(:1)))
    exten => _929xxxxxxx,1,ExecIf($[$[ "${gvuser}" : ".*517.*" ]!=0]?Bridge(${gvuser}):Dial(SIP/517,60,D(:1)))
    exten => _929xxxxxxx,n,Hangup()

    include => sip
    include => gv-outbound

    exten => _NXXNXXXXXX,1,GoTo(1${EXTEN},1)
    exten => _1NXXNXXXXXX,1,Answer
    exten => _1NXXNXXXXXX,n,Set(GLOBAL(gvuser)=${CHANNEL})
    exten => _1NXXNXXXXXX,n,System(gvoice -e -p mypasswd call ${EXTEN} 929xxxxxxx 1 &)
    exten => _1NXXNXXXXXX,n,Wait(20)

    ; ============end of extensions.conf=====================================================
    1. One error: The line under [sip] should be:

      exten => _929xxxxxxx,1,ExecIf($[$[ “${gvuser}” : “.*517.*” ]!=0]?Bridge(${gvuser}):Dial(SIP/517,60,D(:1)))

      It is supposed to match the extension from which the call is initiated.

      (Admin: Corrected the line in your previous comment. Thanks!)

      1. I tested davidnewt’s conf files. Based on an advanced copy of the scripts from him and with some of his help, I have verified everything works fine on MK802 and Dockstar. Both of them are based on Debian Wheezy/asterisk 1.8. I tested on Dockstar with Squeeze also. The Python (2.6) Scrips worked. His conf files also loaded successfully. Callcentric registered fine. However, when I made a test call, there’s an error in /usr/local/bin/voice during execution but the same file does not have problem in Wheeze. I don’t have enough knowledge to debug this problem so I just gave up.

        Installation is really simple. Wheeze has asterisk 1.8 as a read compiled package. All you need to do is to do an “apt-get install asterisk”. With davidnewt’s conf files, no FreePBX is needed. I think it is ideal for a small number of users.

        Thanks to davidnewt for this effort.

        1. The only minor imperfection I have is that the delay is a little too long. It is about 10 seconds between pushing the soft phone call button and ring back. It is not that bad but not as fast as XMPP. Hope there a way to reduce that.

    2. There is one problem in my posted extensions.conf file: it has no problem to make GV calls, but it has problem to receive calls. The reason is that gvuser variable is set to be a global variable in the outbound context and will always reserve the value from previous channel, which makes the line below [sip] always try to bridge the previous channel. For regular incoming calls after an outgoing call, this will cause error since the gvuser points to an invalid channel . The solution is to reset gvuser to its initial value (a random value) as below. To be safe, it may be helpful to reset this global value after the Wait() line.

      exten => _929xxxxxxx,1,ExecIf($[$[ "${gvuser}" : ".*517.*" ]!=0]?Bridge(${gvuser}):Dial(SIP/517,60,D(:1)))
      exten => _929xxxxxxx,n, Set(GLOBAL(gvuser)=abc)
      exten => _929xxxxxxx,n,Hangup()
      1. Hi Davidnewt …

        exten => _1NXXNXXXXXX,n,System(gvoice -e -p mypasswd call ${EXTEN} 929xxxxxxx 1 &)

        For the above code I assume 929xxxxxxx is the Callcentric DID number. Since this number is not a valid forwarding number in my GV account I get a validation error while making a call. But If I replace this with a valid number in my GV account the call goes through.

        Do you know how to validate the CC DID number into google voice ?

        1. Vasanth Rajkumar: Log into Google Voice and add the number as a new forwarding number. Google Voice should then attempt to verify the number by calling you on it. You punch in a 2-digit code that Google Voice will give you to verify it’s your number, similar to what you had to do when you first set up the Google Voice account.

          After the number has been verified, if for some reason you don’t want Google Voice to try to send calls there you can always uncheck it.

          1. Thank you Admin.

            I do understand the validation process within google voice. But I thought the CC DID being used here is just a dummy number that will be used solely to bridge Asterisk and GV.

            Which phone will ring when gv makes the authentication call to the CC DID ? I am a bit confused.

          2. We just assumed that you already had a CC number that came into your Asterisk server and was then directed to an extension that you could answer. If that’s not the case, then you may have a problem getting this to work.

          3. Or, you can simply use a softphone such as X-Lite to register with CC. Make sure to test if it can receive phone call, by using any phone to call the CC DID number. If it works, you can let Google to send you the code and call this DID number.

          4. Ok thank you Admin.

            Twinclouds. Yes that is what I am going to try. Thanks for the pointer.

      2. It seems work pretty reliably. The only issue is the waiting time is about 8 seconds. It is not unbearable but a little too long. I figured out how to add musiconhold to fill the gap and it works. At least it is a little less boring and give the caller something to hoping for :-). Now I am ready for the day Google pull the plug – if this setup works then. I will keep my fingers crossed.

    3. Is this configuration still working? I have tried to set up and the incoming calls work but the out going calls do not. Any ideas?

  7. Just a request to those posting code. WordPress is REALLY dumb about code in comments. So if you want your code to appear correctly without us needing to edit it, please:

    – Enclose it in <pre> … </pre> blocks rather than <code> … </code> blocks
    – Put a <br> at the end of each line (including blank lines!)
    – Put <br><br> between paragraphs in comments

    When we notice comments not displaying correctly we try to fix them, but we don’t always notice. Thanks!

  8. For anyone having a problem using pygooglevoice, you might want to try the Google Voice PHP API at . Basically you’d need to create a php script (probably in /var/lib/asterisk/agi-bin and be sure to set the permissions and ownership same as other php files in that directory) that would look something like the first part of the Google-Voice-PHP-API / example.php file at , except that rather than hardcoding the values you’d pass them from Asterisk:



    // NOTE: Full email address required.
    $gv = new GoogleVoice('', 'password');

    // Call a phone from one of your forwarding phones.
    $gv->callNumber('9995551212', '5558675309', 'mobile');


    Or to cancel a call if the caller hangs up prematurely, you could use a second script;



    // NOTE: Full email address required.
    $gv = new GoogleVoice('', 'password');

    // Cancel in-progress call placed using callNumber.
    $gv->cancelCall('9995551212', '5558675309', 'mobile');


    NOTE: If you get errors from GoogleVoice.php, try installing the php-xml package

    You could make the actual calls to the php scripts using any method that supports passing variables. There are probably ways to do it using TrySystem(). System(), FastAGI(), AGI(), backticks, etc. but we’ll leave that as an exercise for the reader. It is our understanding that AGI calls consume a lot of system resources so they may run slower than other methods, but it might be easier to pass variables in AGI calls. Examples of FreePBX PHP scripts that are called using an AGI call, and receive variables are “directory” and “queue_devstate.agi”, both in the /var/lib/asterisk/agi-bin directory – you could search for those AGI calls in /etc/asterisk/extensions_additional.conf to see how they are constructed. We realize that doesn’t help anyone that doesn’t have access to a FreePBX system, but there are a number of ways to call PHP scripts from within Asterisk.

  9. If you’ve tried to install this on a newer system and it didn’t work, we feel your pain. We finally found the time to try testing this on an aging Asterisk 1.8 system, and apparently a lot has changed since this article was written. We’ve added some of the changes we had to make in the green-shaded areas above. The good news is that this still worked, at least as of Asterisk 1.8, but the bad news is that there may be slight variations in the actual implementation between Asterisk versions.

    1. I was probably lucky that I made it work without much modifications. I essentially used the original scripts and modified based on Davidnewt’s config files, so no FreePBX was needed. One change that I made was replacing “exten => _1NXXNXXXXXX,n,Wait(60)” by “exten => _1NXXNXXXXXX,n,MusicOnHold(40)” after proper configure the musiconhold. I used the ARM based Dockstar and similar devices for both Squeeze (Asterisk 1.8.24) and Wheezy (Asterisk 1.8.13) Debian. The delays are about 5 to 10 seconds, not as fast as XMPP but still acceptable, especially with musiconhold. If it works after March 2014, I think I will be all set.

      BTW, I found the delay is greatly influenced by callcentric’s DID delay. I found one bad number gave me much longer delay than the other. Eventually, I cancelled it and request another one, which works fine. You can test the delay time by setting up the DID with, e.g., XLite, and make a call to the DID number to see how long before it starts to ring.

        1. The IPKall free DID does not support registration, which may make the callback method in the asterisk more complicated. To use IPKall free DID, the asterisk server has to accept SIP URI calls.

          1. davidnewt, we have found that in such a case you can sometimes create a SIP trunk that will accept the calls, that contains only PEER details that look something like this:

            allow=ulaw (or whatever codec(s) you wish to allow)
            context=from-trunk (or a custom context if necessary)

            The host line is the most important because by specifying the server that’s sending you the traffic (which you can often find by viewing the Asterisk CLI or looking at the Asterisk log after an unsuccessful incoming call attempt, though you may need to enable SIP debugging) you avoid the need to allow anonymous incoming SIP traffic, which is a huge security risk. Note that if the provider has multiple hosts that might send you traffic, you need to specify each in a separate trunk because Asterisk unfortunately doesn’t allow the host parameter to be specified as a range. Also note that you probably will need to open UDP port 5060 (or whatever port they use) in your firewall for traffic from the ip address(es) the provider uses.

            The other problem you might run into is if the provider sends the traffic to you in such a way that the DID isn’t where it’s supposed to be, and therefore never gets to your inbound route. Normally, you specify the DID to use when you set up the account. For example, if you tell a provider to send incoming calls to sip:9876@your_server_address, then 9876 would be the DID to use in your incoming route. Usually you will put your DID number there, for example 8005551212@your_server_address. But some providers might send the DID in a non-standard manner. There is an old article on the FreePBX web site at that might help in such a case. You will know this is the issue if you watch the CLI when the call comes in and it is not rejected as anonymous SIP call, and actually makes it to your frpm-trunk context, but then Asterisk drops it on the floor because it has no place to send it.

            If you get it partially working but still need help, you might want to copy what you see in the Asterisk CLI to a pastebin (after sanitizing any phone numbers or ip addresses you don’t wish to share with the entire Internet) and the post the pastebin link – no guarantees, but perhaps someone can tell you where the call is failing.

            twinclouds, there should not be any need to send the calls through another sip provider first, because while that might make the setup a bit easier, it will add latency to the calls and it gives you an additional possible point of failure that is beyond your control.

          2. Eventually, I made IPKall work directly with my asterisk and DV bridge (no FreePBX). What I did are as follows:
            In sip.conf I added:
            [508] ;IPKall
            In extensions.conf I changed
            exten => _929xxxxxxx,1, Bridge(${gvuser})
            exten => _929xxxxxxx,n,Hangup()
            exten => _508,1, Bridge(${gvuser})
            exten => _508,n,Hangup()
            modified the …System(gvoice -e …) statement to use the IPKall DID number
            (note that I assume the incoming call is always form GV dialback, so there’s no ExecIf statement)
            At IPKall, the number is registered with 508@myipaddress:2xxx1 and forwarded 2xxx1 on my router to my asterisk server’s port 5060.
            It worked and the delay was pretty short. The problem is that I still hear chopping voice from the other side. The result was the same as if I registered IPKall with siptosip or other sip server. If I use callcentric DID number, there’s no such chopping voice.
            Please let me know if I implemented anything incorrectly. Otherwise, I guess I’d better to stick with callcentric DID.

  10. Following what discussed in this note and others’ comments, I put together a step by step guide on how to implement this GV callback scheme with plain Asterisk. As I usually like to do, I kept the implementation minimal yet complete. It was fully tested as much as I can.
    The guide can be found here: Your comments and suggestions will be greatly appreciated.

  11. Has anyone got this to work on Asterisk 11.7 PIAF Green? I got errors like these when making outbound calls:

    [2014-03-09 11:55:21] NOTICE[3436][C-00000020]: pbx.c:4955 pbx_extension_helper: No such label 'bridged' in extension 'h' in context 'custom-gv-trunk-diginet'
    [2014-03-09 11:55:21] WARNING[3436][C-00000020]: pbx.c:12326 pbx_parseable_goto: Priority 'bridged' must be a number > 0, or valid label

    The remote phone rings once then hangs up. I’m wondering if I should re-install my PIAF to use 1.8 as the walk through may not be up to date for this version of Asterisk? Any help would be appreciated.

    1. Did you try making the changes for Asterisk 1.8 shown in the green blocks? Those probably should say to use them in Asterisk 1.8 and above, since we believe this article had been originally written for use with Asterisk 1.6, but we’ve only tried it on Asterisk 1.8. Try making all of those changes and see if it works after that.

      1. I spun up another qemu instance with PIAF purple (Asterisk 1.8) and got similar messages but I believe the notice and warnings in the logs is something of newer Asterisk 11 systems. I’ve been unable to work on it this week as I had to travel for work. When I get a chance to sit down , I’ll throw the logs from the Asterisk 1.8 instance I’m running up so apples to apples comparisons can be made. twinclouds I might spin up a third instance following your blog if I still cannot get Asterisk w/ FreePBX going. Thanks for your help so far.

        1. If you are interested to try my method, it is actually very simple. I tried on RPi with FreePBX preinstalled. I only installed GVPython (which I guess you already did) and replaced two conf files (sip and extensions, save them first!) and fill in your credentials. Once done, you restart Asterisk and everything should work. Nothing else need to change. Your FreePBX should still be intact. If you want get back your FreePBX, you just need to simply replace the two conf files by the saved ones..

      2. Finally got this working! Partly was my fault as I misread the 1.8 instructions for the ‘custom-gv-trunk-username’ . I only figured this out after I couldn’t figure out why gvoice was never giving a call back when dialing out. I ended up having to fully path to gvoice. So my line ended up looking like this:
        exten => _X.,1,System(/usr/bin/gvoice -e -p userpassword call ${EXTEN} gvregphonenum code &)

        Just in case someone misread it like I did, your ‘custom-gv-trunk-username’ should look like this:

        exten => _X.,1,System(/usr/bin/gvoice -e -p userpassword call ${EXTEN} gvregphonenum code &)
        exten => _X.,n,Set(DB(gv_dialout_username/channel)=${CHANNEL})
        exten => _X.,n,Wait(20)
        exten => _X.,n,Noop(Never received callback from Google Voice on channel ${DB_DELETE(gv_dialout_username/channel)} – exiting)
        exten => h,1,Hangup()

  12. I don’t really understand the gvregphonenum code part of this. Can someone explain that better to me? It was noted that the gvregphonenum was the destination in Google Voice as apposed to the actual Google Voice number. I don’t have a destination (e.g. cell phone) assigned to my Google Voice. Mine is simply configured as “Forward calls to Google chat”.

    1. The ability to forward calls to Google Chat is what theoretically will stop working on May 15, although it may be converted to forward calls to Google Hangouts – we don’t know what Google’s plans are, but at present there is no way for Asterisk to interface with Google Hangouts so no matter what they do, what you are using now won’t work.

      So, you will need to have a DID coming into your Asterisk server. It doesn’t matter if it’s a free one such as one you can get from IPKall, IPComms, or Callcentric, or a number you have with a for-pay VoIP provider, or even a PSTN line coming into something like an OBi110 device, there just needs to be a “real” phone number that Google Voice can forward calls to that will come into your Asterisk/FreePBX system via a Trunk and Inbound Route. Note that if you are using online configuration instructions that are intended for Asterisk users (such as these for IPComms), don’t forget that in FreePBX you need to add a context statement (usually context=from-trunk) and the configuration goes in the trunk PEER details, not the USER details (which should be left blank).

      After you configure Google Voice to forward incoming calls to the DID phone number, that is the number you use in place of gvregphonenum.

    2. Others may be able to answer even better but the basic is, if you want this approach to work, GV should forward to a telephone number, here called DID, rather than to the Google chat only. You can have more than one forward number including the chat but this particular DID is used by the PBX. If you are interested to see another example, you can take a look of my blog ( It may help you to understand better. The implementation are slightly different but the principles are the same.

  13. That was very helpful – thanks for clarifying. I was able to get a free NY phone number and apply it to my Google Voice account. I made it through the remaining steps (I think I did it correctly), but when running the command (gvoice -e -p userpassword call numbertocall gvregphonenum code) at the SSH Linux cmd prompt, I see the following error:

    Traceback (most recent call last):
    File "/usr/bin/gvoice", line 129, in
    File "/usr/lib/python2.6/site-packages/googlevoice/", line 117, in call
    'remember': '1'
    File "/usr/lib/python2.6/site-packages/googlevoice/", line 225, in __validate_special_page
    load_and_validate(self.__do_special_page(page, data))
    File "/usr/lib/python2.6/site-packages/googlevoice/", line 65, in load_and_validate
    File "/usr/lib/python2.6/site-packages/googlevoice/", line 59, in validate_response
    raise ValidationError('There was a problem with GV: %s' % response)
    googlevoice.util.ValidationError: There was a problem with GV: {u'data': {u'code': 1}, u'ok': False}
    Logging out of voice...

    I should probably mention too that during the earlier steps of this process, I had to change part of the script above from python2.4 to python2.6. But it completed then without errors.

    Once this is setup properly, can I uncheck the “Forward calls to Google chat” and expect it to work?

  14. I started over with a fresh install/upgrade of the latest PIAF. Since I am now on Asterisk 1.8, I applied the changes noted in the article just for this version. I’m able to receive inbound calls, however outbound don’t go through (it’s just silent when I dial out). Any way to troubleshoot this?

    Also regarding inbound calls, I noticed that it seems to take four rings from the time I dial to the time it starts ringing my phone. Is that normal?

    1. So it finally works! Steps I used:

      1.) I created a Callcentric account and added that number as a mobile number in my Google Voice account.
      2.) I then created a Callcentric trunk in PIAF and was able to receive calls to my softphone.
      3.) I continued by adding a second trunk for my outbound Google calls (with the custom dial string ‘Local/$OUTNUM$@custom-gv-trunk-username’).
      4.) Finally, I added an Outbound route and pointed it to the Google Trunk I created in the previous step.

      My extensions_custom.conf looks like this:

      ;Custom dial plan added for Google Voice without XMPP
      exten => _X.,1,System(sudo gvoice -e -p GooglePassword call ${EXTEN} CallCentric# 2 &)
      exten => _X.,n,Set(DB(gv_dialout_GoogleUsername/channel)=${CHANNEL})
      exten => _X.,n,Wait(20)
      exten => _X.,n,Noop(Never received callback from Google Voice on channel ${DB_DELETE(gv_dialout_GoogleUsername/channel)} – exiting)
      exten => h,1,Hangup()

      exten => s,1,NoCDR()
      exten => s,n,GotoIf($[${ISNULL(${DB(gv_dialout_GoogleUsername/channel)})}]?ext-did-0002,CallCentric#,2)
      exten => s,n,Bridge(${DB_DELETE(gv_dialout_GoogleUsername/channel)})
      exten => s,n,System(sudo gvoice -e -p GooglePassword cancel &)
      exten => s,n,Hangup()

    1. You and us both. Anyone can open the pygooglevoice-0.5.tar.gz file and examine the actual scripts; we are not Python experts but in looking through the various scripts we find no references to XMPP anywhere. On the other hand, in the script (in the googlevoice directory inside the archive) there are references to xml. Perhaps Mr. Mundy is getting XML confused with XMPP? We have no idea, but there are two reasons we think he is just plain wrong in his assertion.

      First, the old method predated any known use of XMPP, at least by Asterisk/FreePBX users. To the best of our knowledge, the first PBX software to offer XMPP connections to Google Voice was FreeSWITCH, and as far as we can tell they came out with their mod_dingaling driver (which definitely used XMPP) right around the time pygooglevoice was released in 2009, but the two projects were unrelated. mod_dingaling used XMPP from the start and made no secret of it, while you can search the pygooglevoice code and documentation and you will not find a single reference to XMPP (nor to Jabber, the old name for the protocol). You can search the documentation at and again you will find mentions of XML, but not XMPP. The API reference page at specifically talks about the ability to “grab the JSON and HTML data”; again no mention of XMPP or Jabber.

      The other reason we think Mr. Mundy may be having a brain fart on this subject is that this older method has been discussed for months now in various forums including, which has some very technically-astute participants, several of whom work for commercial VoIP companies and would probably love nothing more than to be able to say that there is no way you will be able to make outgoing calls using Google Voce past May 15. Some of these guys doubtless know Python much better than we ever will, and you’d think that by now they’d have spoken up if they felt that the old method was doomed. Yet for whatever reason, Mr. Mundy is the only person that is saying that the “old-style connections” utilize XMPP, and our question is, why is he only making this statement now, less than a month from the drop-dead date for XMPP, with (as we are writing this) no corroborating evidence whatsoever?

      Maybe he is talking about a different method of “old-style connections” than the rest of us, or maybe, as we suspect, he’s just getting XML and XMPP confused. We don’t know why he’s saying that, but we are certainly among those that have our doubts about it, and would like to see him produce any evidence he might have to back up that statement.

      And even if it were somehow true for pygooglevoice, there are other ways to do the same thing using different software. For example the Google Voice PHP API at appears to have the same capabilities as pygooglevoice, at least for our purposes, and if you are more familiar with PHP than Python you can examine their code and determine that they do not use XMPP. It would probably take a programmer all of about five minutes to figure out how to substitute the Google Voice PHP API for pygooglevoice in this application.

  15. Thanks. I am sure you are right that pygooglevoice does not use XMPP. I did noticed that there are references to XML rather than XMPP. However, I don’t know if Google can change anything to make the callback approach not work after May 15 by changing API. I hope not, but we will have to wait and see. I will keep my finger crossed.

    1. There is no doubt that Google could make changes that would cause the old method to stop working, but that isn’t something they have announced they are going to do. The only thing they have said is going away is XMPP.

      But sure, Google could discontinue the API, or even the Google Voice service entirely. One would only hope they’d give some advance notice before doing that.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.