SUGGESTIONS Old Fashioned Google Voice calls

Cam__

Member
Joined
May 22, 2013
Messages
43
Reaction score
8
Ward's article on Send SMS Messages w/o Google got me to thinking that in the past we had a way to make Google Voice calls before Asterisk offered any kind of Google Voice support. It took a few more seconds for the call to go through, but it worked. The basic idea was that you would send a command to Google Voice using an API, then Google Voice would first call you, and then when you answered it would call the other party. In order for this to work you had to have a number that came in through some other means than Google Voice. Back then there were several ways to get a free DID, but I don't know how many of those are still available. When the callback came, it would be bridged to the original caller.

I was reading a thread on the Obihai forum where a user (giqcass) said this: "Actually Callcentric doesn't have to cost any money. I'm using it now and paying nothing. When you sign up for Callcentric use your real address but say you don't plan to use Callcentric in the US. Then you won't be forced to buy E911 and you won't be charged anything." So that might be one option to get an inbound number from someone other than Google Voice. I am neither encouraging nor discouraging that, since I have no experience with Callcentric. Even if you decide to pay for a DID, they are cheaper now than they used to be, but that's a discussion for another thread.

But to get to the point, I was searching through some notes from way back when and some Google-fu brought me to this:

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

Although that's very close to what I used to use, the only thing I don't like about that method now is that it uses PyGoogleVoice, which for some reason I've always had problems with. I prefer the Google-Voice-PHP-API by aaronpk. The only thing you need to do if you are going to use that is first install php-xml - you can do yum install php-xml or whatever would be the correct way of installing it on a system running another OS. Then you can copy the GoogleVoice.php script to a directory and run it from there.

I ran a quick test to see if that API could be used the way the old PyGoogleVoice script was used, by creating a quick PHP script in the same directory as GoogleVoice.php:

PHP:
<?php
include('/root/GoogleVoice.php');
$gv = new GoogleVoice('[email protected]', 'mypassword');
$gv->callNumber('8005551212', '9999999999', 'mobile');
?>

Replace 8005551212 with the number you want to call, 9999999999 with the DID you are using as a Google Voice destination, and 'mobile' with the type of number you registered that number as with Google Voice - the options are 'mobile', 'work', or 'home'. This did cause Google Voice to initiate a call to the '9999999999' number (obviously not the actual number) and then when I answered it extended the call to the '8005551212' number. So this is a method that could work if you can't get PyGoogleVoice to install or have issues using it. Now that I think about it, PyGoogleVoice might come with PBX in a Flash, and if so perhaps the original method would work without change. But I still prefer the PHP solution.

This isn't a full solution because I am not among those that are going into full panic mode, believing that Google Voice will totally shut down XMPP access without any warning. But if I am wrong, it shouldn't take more than a few minutes to go back to the old method, except that I would likely call GoogleVoice.php rather than the script from PyGoogleVoice. I even went ahead and added a "call cancel" function into GoogleVoice.php, which was an interesting exercise, just to be prepared in case we do need to go back to the old ways. If it looks like they are really going to pull the plug on XMPP, check back and I might have a more developed PHP script that accepts variables from Asterisk and sends them on to GoogleVoice.php - it should be a very simple thing to write.

I totally understand those who are just fed up with Google Voice and want to move on, and this isn't for those people. But if you have people on your system that make about one outgoing call a week through Google Voice like I do, it's just not worth it to move their number to a paid account.
 

Cam__

Member
Joined
May 22, 2013
Messages
43
Reaction score
8
In the article I mentioned it had two new contexts placed in extensions_custom conf, and the first of those contained two calls to the gvoice component of PyGoogleVoice. To place the call it used:

exten => _X.,1,System(gvoice -e username@gmail.com -p userpassword call ${EXTEN} gvregphonenum code &)

And to cancel the call if the user hung up it used:

exten => h,n,System(gvoice -e username@gmail.com -p userpassword cancel &)

My thought was that instead of using those system calls you instead created two PHP scripts, gvoicecall.php and gvoicecancel.php. Then the first call might become:

exten => _X.,1,System(php gvoicecall.php username@gmail.com userpassword ${EXTEN} gvregphonenum type &)

And the second might become

exten => h,n,System(php gvoicecancel.php username@gmail.com userpassword ${EXTEN} gvregphonenum type &)

Where type is the word mobile, work or home rather than a numeric code as in the original.

And gvoicecall.php might look something like this:

PHP:
<?php
 
// When called, arguments are as follows:
// $argv[0] - program name (not used)
// $argv[1] - Google Voice account full e-mail address
// $argv[2] - Google Voice password
// $argv[3] - Phone number being called
// $argv[4] - Callback number registered as Google Voice destination
// $argv[5] - Callback number type (mobile, work or home)
 
include('/root/GoogleVoice.php');
 
$gv = new GoogleVoice("$argv[1]", "$argv[2]");
$gv->callNumber("$argv[3]", "$argv[4]", "$argv[5]");
?>

And gvoicecancel.php would be an exact copy of the above, except for the next to last line where callNumber would be replaced by cancelCall. Or you could get a bit fancier and have a single script with an extra argument (call or cancel), and then use some if/else code to decide whether the callNumber or cancelCall function should be invoked.

That article did mention using a custom trunk which among other settings contained a Custom Dial String that was set to Local/$OUTNUM$@custom-gv-trunk-username but there was a little bit more to it than that. The particular issue was intercepting the callback from Google Voice and bridging that call to the original caller. Also, in the time before the callback came, the caller might abandon the call and hang up. Unless the cancel message was sent to Google Voice, the call would be put through anyway.

I hate to say it but the way we do it now, using XMPP, is quite an improvement over the older method so I'm really hoping that all the recent articles and posts suggesting that it is going away is just so much FUD. But in case it isn't, it never hurts to consider alternatives.
 

wardmundy

Nerd Uno
Joined
Oct 12, 2007
Messages
19,159
Reaction score
5,192
If I'm not mistaken, a working version of the gvoice python script now comes preinstalled (and working) in all versions of PBX in a Flash and Incredible PBX. This includes the Raspberry Pi edition. So...

We should be able to make this virtually transparent with the call bridging functionality in new versions of Asterisk. So you'd place a call like you do now. Behind the scenes...
  • Caller dials number
  • Simulate ringing to caller
  • Google Voice script is run
  • Call is bridged to existing caller
  • Outbound call is placed through GV script
Here's the old script from Best of Nerd Vittles:

Code:
#!/bin/bash
 
clear
echo "This script installs Google Voice support on your PBX."
echo "You must have a system that is compatible with PBX in a Flash."
echo "WARNING: No error checking is provided."
echo "By using this script, you agree to assume ALL RISK."
echo "NO WARRANTY, EXPRESS OR IMPLIED, OF ANY KIND IS PROVIDED."
echo " "
echo "If you make a typo while entering values below, press Ctrl-C and start over."
echo " "
echo "Your Google Voice entries are stored in /etc/asterisk/extensions_custom.conf."
echo "Edit that file and reload your Asterisk dialplan if you make future changes."
echo " "
echo -n "10-digit Google Voice phone number (e.g. 9871234567): "
read gvnum
echo "GVNUM: $gvnum"
echo -n "Google Voice email address: "
read acctname
echo "ACCTNAME: $acctname"
echo -n "Google Voice password: "
read acctpass
echo "ACCTPASS: $acctpass"
echo -n "11-digit Ring Back DID (e.g. 16781234567): "
read ringback
echo "RINGBACK: $ringback"
echo -n "Parking Lot Magic Number: "
read callpark
echo "CALLPARK: $callpark"
echo " "
echo "We're now ready to begin the installation."
echo "Check your entries above and then press Enter key to proceed."
echo "Or press Ctrl-C to abort and try again."
read readysetgo
clear
echo "Installing Google Voice support for your PBX. One moment please..."
echo " "
 
echo " " >> /etc/asterisk/extensions_custom.conf
echo "[custom-gv]" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,1,Wait(1)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Set(ACCTNAME=$acctname)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Set(ACCTPASS=$acctpass)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Set(RINGBACK=$ringback)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Set(CALLPARK=$callpark)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Background(pls-wait-connect-call)" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,System(gvoice -e \${ACCTNAME} -p \${ACCTPASS} call \${EXTEN} \${RINGBACK})" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Set(PARKINGEXTEN=\${CALLPARK})" >> /etc/asterisk/extensions_custom.conf
echo "exten => _X.,n,Park()" >> /etc/asterisk/extensions_custom.conf
echo " " >> /etc/asterisk/extensions_custom.conf
echo "[custom-park]" >> /etc/asterisk/extensions_custom.conf
echo "exten => s,1,Wait(4)" >> /etc/asterisk/extensions_custom.conf
echo "exten => s,2,Set(GVNUM=$gvnum)" >> /etc/asterisk/extensions_custom.conf
echo "exten => s,3,Set(CALLPARK=$callpark)" >> /etc/asterisk/extensions_custom.conf
echo "exten => s,4,NoOp(**CALLERID: \${CALLERID(number)})" >> /etc/asterisk/extensions_custom.conf
echo 'exten => s,5,GotoIf($["${CALLERID(number)}"="${GVNUM}"]?6:7)' >> /etc/asterisk/extensions_custom.conf
echo "exten => s,6,ParkedCall(\${CALLPARK})" >> /etc/asterisk/extensions_custom.conf
echo "exten => s,7,Goto(from-trunk,gv-incoming,1)" >> /etc/asterisk/extensions_custom.conf
echo " " >> /etc/asterisk/extensions_custom.conf
 
echo "Reloading Asterisk dialplan..."
asterisk -rx "dialplan reload"
echo " "
 
if [ -e "/usr/bin/gvoice" ]
then
  echo "pygooglevoice is already installed on your system. Skipping."
  echo "Be sure you have removed the original [custom-gv] context!!!"
  echo " "
else
echo "Installing Python add-ons..."
cd /root
#yum install mercurial
yum -y install python-setuptools
easy_install simplejson
#hg clone https://pygooglevoice.googlecode.com/hg/ pygooglevoice
 
echo " "
echo "Installing pygooglevoice..."
 
wget http://bestof.nerdvittles.com/applications/gv/pygooglevoice.tgz
tar zxvf pygooglevoice.tgz
 
cd pygooglevoice
python setup.py install
 
#sed -i 's|    help(|#    help(|' /usr/bin/gvoice
 

Cam__

Member
Joined
May 22, 2013
Messages
43
Reaction score
8
Right, Ward. If I recall correctly, the need to use the Parking Lot ended with Asterisk 1.4, and the bridge method became available starting with Asterisk 1.6. The article I referenced used two contexts, the first of which was run after the user dialed the call - note this shows the original calls to the PyGoogleVoice gvoice program, which I would replace with calls to GoogleVoice.php as I mentioned in my previous post:

[custom-gv-trunk-username]
exten => _X.,1,System(gvoice -e username@gmail.com -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 username@gmail.com -p userpassword cancel &)
exten => h,n,Hangup()
exten => h,n(bridged),Noop(The channel has been bridged successfully)

When the call gets to the Wait(20) it is waiting for the callback from Google Voice and for the incoming call to be bridged. That call was sent to this context:

[custom-gv-inbound-username]
exten => s,1,NoCDR()
exten => s,n,Bridge(${DB_DELETE(gv_dialout_username/channel)})

That second context is the one that would bridge the incoming call from Google Voice to the waiting caller. The key to this seems to have been storing the channel designator temporarily in the database so that the incoming call would be bridged to the correct waiting caller. You would need to duplicate the above two contexts for each Google Voice account and user on your system, changing the bolded information as necessary. If you wanted to use GoogleVoice.php rather than PyGoogleVoice then the second context would stay the same, but the first would become:

[custom-gv-trunk-username]
exten => _X.,1,System(php gvoicecall.php username@gmail.com userpassword ${EXTEN} gvregphonenum type &)
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(php gvoicecancel.php username@gmail.com userpassword ${EXTEN} gvregphonenum type &)
exten => h,n,Hangup()
exten => h,n(bridged),Noop(The channel has been bridged successfully)

And you would need the two scripts gvoicecall.php and gvoicecancel.php as explained in my previous message, but you would only need one copy of each - those would not need to be duplicated for each GV account.

Seems like should it become necessary, it would be easy enough to rewrite your setup script to write the above contexts for each Google Voice user, and to install GoogleVoice.php, gvoicecall.php, and gvoicecancel.php if they don't already exist. I'm still hoping it doesn't become necessary, though.

One thing I sadly recall about some of the scripts from the "Parking Lot" days was that they did a lot of unnecessary waiting. The unnecessary waits and/or playing a "Please wait while I connect your call" recording only further delayed call progress, and Google Voice is slow enough to call back to begin with. The only wait that is actually necessary starting with Asterisk 1.6 is when you are waiting for the Google Voice callback. I don't know if any of those other waits were really necessary under Asterisk 1.4. My strong suspicion is that some were not necessary even back then, but I know from experience that they were not necessary in Asterisk 1.6.

Also, if you must add some type of audible comfort noise such as Music on Hold for the caller, you would do that AFTER the "exten => _X.,n,Set(DB(gv_dialout_username/channel)=${CHANNEL})" line, in place of or just prior to the Wait(20), so that call processing is not delayed and the incoming callback from Google Voice can break into your audible interlude. I could never understand the thinking behind those scripts that delayed the call to play "Please wait while I complete your call!" My thought whenever I heard that was, "Just get on with processing the call already, before I fall asleep here!" :sleep1:
 

Geo(Recovered)

New Member
Joined
May 24, 2013
Messages
13
Reaction score
4
I was reading a thread on the Obihai forum where a user (giqcass) said this: "Actually Callcentric doesn't have to cost any money. I'm using it now and paying nothing. When you sign up for Callcentric use your real address but say you don't plan to use Callcentric in the US. Then you won't be forced to buy E911 and you won't be charged anything." So that might be one option to get an inbound number from someone other than Google Voice. I am neither encouraging nor discouraging that, since I have no experience with Callcentric. Even if you decide to pay for a DID, they are cheaper now than they used to be, but that's a discussion for another thread.

CallCentric has a free IP Freedom account (residential or business use) that can be used to make inbound and outbound calls (in-network, SIP, and SIP Broker) _without_ funding the account. :)

CallCentric also offers a free NY state DID (residential or business use). A call must be received from the PSTN once every 90 days to keep the DID active (I use a cron based call file).

Free iNUM, too.

The interesting thing about CallCentric - they have divisions that are a CLEC, an IXC, and an ISP - inter-ties on the PSTN along with internet peering (redundant networks).

Other developments:
Automated account attendant and unified (voice, video and data) switching platform upgrade.
Private generator (instead of shared generator with NYSE), and additional locations (west coast and Europe).
 

Cam__

Member
Joined
May 22, 2013
Messages
43
Reaction score
8
Too bad they won't let you port numbers to the IP freedom account. That would make this a lot more interesting!

Care to share what you put in that call file? I don't mean the exact numbers, just would be curious to know how you do it.
 

Geo(Recovered)

New Member
Joined
May 24, 2013
Messages
13
Reaction score
4
Care to share what you put in that call file? I don't mean the exact numbers, just would be curious to know how you do it.

On Monday mornings, cron calls a shell script:

KeepCCNYNumber.sh:
Code:
cp /root/KeepFreeNumbers/KeepCCNYNumber.call /root/KeepFreeNumbers/KeepCCNYNumber.call.use
mv /root/KeepFreeNumbers/KeepCCNYNumber.call.use /var/spool/asterisk/outgoing/KeepCCNYNumber.call

Copy, then move, is used to prevent file caching issues.

This is the call file I use for my CallCentric DID:

KeepCCNYNumber.call
Code:
Channel: Local/610@from-internal
Context: extensions
CallerID: "KeepFreeNumbers" <301>
Account: 301
Application: Playback
Data: silence/2&eletelephony

610 is a ring group with one phone number - the NY DID.

Once the call is answered, there are 2 seconds of silence, followed by the eletelephony message.
 

Cam__

Member
Joined
May 22, 2013
Messages
43
Reaction score
8
Geo and Ward, those are both good approaches to the problem. Thanks!
 

Danyo

New Member
Joined
Sep 19, 2010
Messages
1
Reaction score
0
I have been using the Google-Voice-PHP-API by aaronpk mentioned. I just recently had to replace (line 43)
PHP:
if(preg_match('/name="GALX"\s*value="([^"]+)"/', $html, $match))
with
PHP:
if(preg_match('/name="GALX"\s+type="hidden"\s+value="([^"]+)"/', $html, $match))
 

twinclouds

Guru
Joined
Feb 20, 2010
Messages
54
Reaction score
2
I was able to run GoogleVoice.php using the basic script by Cam__ on my Debian Linux on Dockstar to make calls. If I want to call the scripts gvoicecall and gvoicecancell inside Asterisk, where I should put these scripts? Appreciate if anyone can help. Thanks.
 

twinclouds

Guru
Joined
Feb 20, 2010
Messages
54
Reaction score
2
Another question. I tried to rum the scripts on Openwrt. For either php-cgi or php-cli, I always get the error "Fatal error: Uncaught exception 'Exception' with message 'Could not parse for GALX token' in /root/GoogleVoice.php:46" The GALX problem has been fixed in the scripts and the same scripts run fine on Debian. Any one know why? Thank.s
 

grimloch

New Member
Joined
Apr 9, 2014
Messages
12
Reaction score
1
Hi Everyone!

I've been using pbxes.org with (GV forwarded) Callcentric DIDs inbound and their GTalk trunk for outbound for quite a while, but since Google's turning off XMPP in about a month I decided it's about time for me to roll my own, especially after learning about the low cost RPi and BBB. I got a Raspberry Pi on Tuesday and have spent the last couple days figuring all this out. It was hell getting Callcentric inbound to work [without] turning on anonymous SIP, but I finally got the right settings today after combing the internet and winding up on another thread in this forum.

As to the topic here, I'd like to try out pygooglevoice for outgoing calls, but I'm having trouble finding an updated-ish tutorial. It sounds like pygooglevoice is included in Incredible Pi now, but I can't tell where to find it or if it's connected at all to the GV settings under "Connectivity", though I suspect it is not. There seem to have been multiple iterations of pygooglevoice and changes of it's implementation as Asterisk has advanced, and since all the info out there is quite dated I'm hoping someone here can point me in the right direction. This is all relatively new to me, but I think after figuring out the callcentric stuff I will be able to do this, too. Thanks in advance!
 

twinclouds

Guru
Joined
Feb 20, 2010
Messages
54
Reaction score
2
I think since I'm running Incredible PBX then I should try your first link, yes? The tech.iprock.com site seems to be down at the moment, though :(
Yes. However, you might need to experiment somewhat because it is not a step by step guide.
 

grimloch

New Member
Joined
Apr 9, 2014
Messages
12
Reaction score
1
Using the following entries in custom_extensions.conf works for me (Raspberry Pi/Incredible PBX(FreePBX 2.11.0.34/Asterisk 11)):

Code:
[custom-gv-trunk-user]
exten => _X.,1,System(/usr/local/bin/gvoice -e [email protected] -p gmailpassword call ${EXTEN} Callcentric# 1 &)
exten => _X.,n,Set(DB(gv_dialout_user/channel)=${CHANNEL})
exten => _X.,n,Wait(20)
exten => _X.,n,Noop(Never received callback from Google Voice on channel ${DB_DELETE(gv_dialout_user/channel)} – exiting)
exten => h,1,Hangup()
 
[custom-gv-inbound-user]
exten => s,1,NoCDR()
exten => s,n,GotoIf($[${ISNULL(${DB(gv_dialout_user/channel)})}]?ext-did-0002,Callcentric#,1)
exten => s,n,Bridge(${DB_DELETE(gv_dialout_user/channel)})
exten => s,n,System(/usr/local/bin/gvoice -e [email protected] -p gmailpassword cancel &)
exten => s,n,Hangup()

Callbacks initiated from the Google Voice web page do NOT work, though. I believe it's because of the following line:

exten => s,n,GotoIf($[${ISNULL(${DB(gv_dialout_user/channel)})}]?ext-did-0002,Callcentric#,1)

The article here mentions that line and that it may change in future versions of FreePBX/Asterisk. From what I can tell there is no "ext-did-0002" context or "extensions_additional.conf" in this most recent version of FreePBX/Asterisk, or if there is it's hidden and I'm too new at this to figure it out.

Anyone know what context I can replace "ext-did-0002" with to make this work?
 

grimloch

New Member
Joined
Apr 9, 2014
Messages
12
Reaction score
1
To clarify my post above, I'm using pygooglevoice, which is built in to the latest versions of Incredible PBX so no installation is required. The file /etc/sudoers has also already been modified to include the "asterisk ALL = NOPASSWD" line except gvoice is now in /usr/local/bin/ rather than /usr/bin/ as indicated in the iprock article that's been linked to several times. I mention this because once I included the full path to gvoice in the contexts added to extensions_custom.conf it finally started working. Someone mentioned doing that in the comments of the twinclouds article, and for that I thank them :cheers2:.

Now I just need to fix the context in my post above so callbacks initiated from the GV web site work. Any help would be greatly appreciated.
 

wardmundy

Nerd Uno
Joined
Oct 12, 2007
Messages
19,159
Reaction score
5,192
Just an FYI that the old-style connections still use XMPP to complete the calls. This most probably will not work after May 15. You still will be able to receive inbound calls forwarded to a DID you own using your Google Voice numbers, but outbound calling is probably going to die. So... make some alternative arrangements before Crisis Time arrives. :gnorsi:
 

grimloch

New Member
Joined
Apr 9, 2014
Messages
12
Reaction score
1
Just an FYI that the old-style connections still use XMPP to complete the calls. This most probably will not work after May 15. You still will be able to receive inbound calls forwarded to a DID you own from your Google Voice numbers, but outbound calling is probably going to die. So... make some alternative arrangements before Crisis Time arrives. :gnorsi:

Oh don't say that! Isn't that contrary to the idea behind this thread and every other post herein mentioning XMPP and how this method does not require it?
 

Members online

No members online now.

Forum statistics

Threads
25,770
Messages
167,441
Members
19,181
Latest member
ejrubin
Get 3CX - Absolutely Free!

Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.
Top