kevindiffily / google-voice-sipsorcery-dialplans

Automatically exported from code.google.com/p/google-voice-sipsorcery-dialplans
0 stars 0 forks source link

Setting up GV, Freephoneline.ca and Voip.ms on Sipsorcery #91

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi There!

Just stumbled upon this while doing and a search and noticed that there are 
lots of clever people here! :)

I am in Canada and have the following setup.

GV # 
Freephoneline.ca #
DID with Voip.ms
SPA 3102 ATA

I ditched my home phone and have it setup as such:

GV # is setup to fwd to IPKall
I use this plan for inbound calls:

if sys.IsAvailable() then     # if online
    WP_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'              ###### EDIT THIS LINE WITH White Pages API key

    CNAM = {
      '77812345678' => "My Cell",                                                    
      '12221231234' => 'Work',
      '12223334444' => 'Your Woman'                     

    }
    ##################you shouldnt edit anything below this####################

      if sys.In               ..
        name = req.Header.from.FromURI.User.to_s    
        name = ('1' + name) if name =~ /^[2-9]\d\d[2-9]\d{6}$/
        name.sub!(/^011/,'')
        if !(cname = CNAM[name]) && name =~ /^1([2-9]\d\d[2-9]\d{6})/
          url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3Bapi_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
          if js = sys.WebGet(url,4).to_s
            if !(js =~ /"businessname":"([^"]+)"/ && cname = $1)
            if !(js =~ /"displayname":"([^"]+)"/ && cname = $1)
              cname = %w(city state).collect {|x| js =~ /"#{x}":"([^"]+)"/; $1}.join(', ')
            end
            end
          end
        end
        name.sub!(/^1/,'')
        sys.Log("Caller's number: '#{name}'"); sys.Log("Caller's name = '#{cname}'") if cname

    #     sys.SetFromHeader(formatNum(cname || name), nil, nil)
       sys.SetFromHeader(cname || name, nil, nil)

        # Forward call to bindings. Change FromURI when forwarding to
        # @local, or else Bria won't find contact in its phonebook!
        sys.Dial("#{sys.Username}@local[fu=#{name}]&XXXXXXXXXX@freephoneline[fu=#{name}]")         #####HARDCODE XXXXXXXXXX as FORWARD NUMBER
    #    sys.Dial("#{sys.Username}@local[fu=#{name}]&XXXXXXXXXX@freephoneline[fu=#{name}]&XXXXXXXXXX@freephoneline[fu=#{name}]" 
    ########or you can perform a normal follwme by adding the seconds at the end#####         
    #    sys.Dial("#{sys.Username}@local[fu=#{name}],20")          
    #    sys.Dial("FOLLOWNUMBER2@freephoneline[fu=#{name}],10") #HARDCODE A NUMBER IF U WANT TO USE THIS
    #    sys.Dial("FOLLOWNUMBER3#freephoneline[fu=#{name}],10") #HARDCODE A NUMBER IF U WANT TO USE THIS
    ####### 

        sys.Respond(480, "#{sys.Username} Not available")

        sys.Respond(480, "#{sys.Username} Not online") # switch to voice mail

       end

    else     # if phone is not online.
    sys.Dial("HARDCODE@freephoneline")                                                           #####HARDCODE FORWARD NUMBER
    sys.Respond(480, "#{sys.Username} Not available") 
    end

I use this plan for outbound calls:

GV_USER = 'username@gmail.com'             ###### your GV e-mail address 
(user@gmail.com)
    GV_PASS = 'password'                              ###### my GV password
    CB_NUMBER = 'ipkallnumber'                    ####### your number that google voice forwards to
    sys.Log "** Call from #{req.Header.From} to #{req.URI.User} **"
    case req.URI.User
    when /^1/ then sys.GoogleVoiceCall(GV_USER,GV_PASS,CB_NUMBER,"#{req.URI.User}") #GV Call Via Callback
    ####
    #when /^1/ then sys.GoogleVoiceCall(GV_USER,GV_PASS,CB_NUMBER,"#{req.URI.User},".*",1") #Direct GV Call NoCallbackl
    ####
    when /^411/ then sys.Dial("8004664411@freephoneline")
    else
    sys.Dial("#{req.URI.User}@freephoneline")
    end

This is what I have setup:

When I dial out any 10 digits - it goes through Freephoneline for free local 
calls
When I dial 1+10 digits - it dials out through GV for free LD with NA
When I dial 011-xxxxx - It dials out through Voip.ms as a gateway on ATA for 
cheap LD outside of NA

I use a dial plan in the ATA:

(911S0|[2-9]xxxxxxxxxS0|1[2-9]xx[2-9]xxxxxxS0|011[2-9]xx.<:@gw1>|<#1,:>xx.<:@gw1
>|<:18004664>411S0|<:416>310xxxxS0|1900!|*xx|<**,:>[x*][x*].<:@sipbroker.com>)

Questions I have:

Is there a better way to do this? 
How safe is my GV User id and pwd on Sipsorcery?
What else can I do? I like tinkering with this stuff an dam open to adding more 
features and play around.

Thanks!

Original issue reported on code.google.com by shafar...@gmail.com on 27 Jul 2010 at 6:52

GoogleCodeExporter commented 9 years ago
Oh, and how do I test 911??? 

Original comment by shafar...@gmail.com on 27 Jul 2010 at 6:52

GoogleCodeExporter commented 9 years ago
Did you recently signup at IPKall, or do you also happen to have a sipgate 
number? I've heard that IPKall can occasionally flake out on inbound caller ID, 
sometimes showing you your own IPKall phone number on the caller ID instead of 
the party calling your IPKall number.

I'm not sure if your needs and usage pattern had you evolve towards this setup, 
but the community you stumbled across here has been growing from a much simpler 
start. Most of us here tend to only have an outbound dialplan at SIP Sorcery. 
No inbound dial plan since we route all inbound calls to whatever SIP client is 
connected to your SIP Sorcery account. Also typically no scripts at the ATA as 
we tend to reformat dial strings programmatically in the out dial plan.

Click the Source tab up top, then click on SIP Sorcery Dial Plans in the chain 
and check out Contrib. We have a variety of dial plans here, all them outbound 
only. Most everyone uses the Simple Dialplan from the Sources tab landing page. 
We have a script that dials 911 via sipgate since they support e911. We also 
have CNAM lookups with the white pages api in our complex dial plan.

In short, if you'd like to get in line with the community, we welcome you with 
open arms. If you'd like to help expand our knowledge of the functionality and 
purpose of both inbound and outbound dialplans, we are all ears! Otherwise, if 
you don't mind starting over and following along as we grow and incorporate new 
features, please grab the Simple Dialplan, the Complex Dialplan or any of those 
in Contrib that are often testing small, specific features.

Original comment by easter...@gmail.com on 27 Jul 2010 at 7:59

GoogleCodeExporter commented 9 years ago
1. I disapprove your choice of ATA. SPA3102 has FXO port which is pretty 
useless since you don't have PSTN line at home ("I ditched my home phone...")

2. I can't agree with your approach where you split provider selection between 
the ATA and Sipsorcery's "Out" dialplan. First, it's very inconvenient, because 
every time you need to change routing of outbound calls, you need to edit both 
dialplans (at Sipsorcery and the ATA). Second, if you need to add another IP 
telephone, or you want to call from SIP-enabled cell phone, you'll have to edit 
the dialplans and/or add yet another Sipsorcery SIP account. I'd rather have a 
very basic dialplan in the SPA3102 (forwarding all calls to Sipsorcery "as is") 
and do all the job at Sipsorcery. Probably I'd make one exception: 911 calls 
should be dialed directly from the ATA, just in case Sipsorcery server is down.

3. You don't need two sys.Respond(480...) in a row, because the first will 
abort the dialplan.

As to Sipsorcery dialplans, there is one more (it hasn't made it to this site 
yet):

http://forum.sipsorcery.com/viewtopic.php?f=15&t=2623

Original comment by mte...@gmail.com on 27 Jul 2010 at 8:28

GoogleCodeExporter commented 9 years ago
I signed up on IPKall a while back. I don't have a sipgate account.

Here is why I have an inbound plan. If some one in the US want to call me, they 
can call my GV # and it would get routed to IPKall then to my home phone in 
Toronto.
If someone calls my home phone in Toronto, Sipsorcery directs the call. That 
way there are two ways to reach me - via US # or a Canadian #.

As for the SPA3102 - I got that so that I can use the gateway feature.

Original comment by shafar...@gmail.com on 28 Jul 2010 at 1:16

GoogleCodeExporter commented 9 years ago
Another question... why is it that when anyone calls me, the caller id has a 
comma before the number?

Original comment by shafar...@gmail.com on 28 Jul 2010 at 1:57

GoogleCodeExporter commented 9 years ago
I assume your home phone number is actually SIP-compatible VoIP DID? When you 
registered at IPKall did you register to SIP Sorcery or your Canadian line? All 
inbound SIP calls get routed to all connected SIP clients with SIP Sorcery so I 
still don't see a need for the inbound plan... unless you have multiple phones 
and you only want a subset to ring based on which line is ringing.

I can't help you with the comma. Does it appear on every inbound call or only 
those routed to your canadian DID? No one in the community here has reported 
that as far as I recall.

Original comment by easter...@gmail.com on 28 Jul 2010 at 3:29

GoogleCodeExporter commented 9 years ago
I can help with the comma :-) You borrowed one of the first versions of my CNAM 
lookup code, it had a minor bug. I wrote it on page 3 of:

http://forum.sipsorcery.com/viewtopic.php?f=15&t=2007&start=20

thread (post dated March 23). There have been some other minor changes, like 
removing leading '+' from the caller ID (Gizmo5). Just borrow the code from one 
of my latest dialplans:

http://forum.sipsorcery.com/viewtopic.php?f=15&t=2623

If it won't fix the problem, please show the Console trace (event *) for 
incoming call.

Original comment by mte...@gmail.com on 28 Jul 2010 at 4:23

GoogleCodeExporter commented 9 years ago
Thx!

I have replaced:
if !(cname = CNAM[name]) && name =~ /^1([2-9]\d\d[2-9]\d{6})/
url = 
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20ur
l%3D'htt p%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0 
%2F%3Fphone%3D#{$1}%3Bapi_key%3D#{WP_key}'%20and%2 
0itemPath%3D'wp.listings.listing'&format=json"
if js = sys.WebGet(url,4).to_s
if !(js =~ /"businessname":"([^"]+)"/ && cname = $1)
if !(js =~ /"displayname":"([^"]+)"/ && cname = $1)
cname = %w(city state).collect {|x| js =~ /"#{x}":"([^"]+)"/; $1}.join(', ')

with this:

if !(@cname = keys_to_ENUM(CNAM)[@cid]) && @cid =~ /^1([2-9]\d\d[2-9]\d{6})$/ 
&& defined?(WP_key)
url = 
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20ur
l%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3B
api_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
if js = sys.WebGet(url,4).to_s
@cname, dname, city, state = %w(businessname displayname city state).map {|x| 
js =~ /"#{x}":"([^"]+)"/; $1}
@cname ||= dname; @cname ||= "#{city}, #{state}" if city && state

I now get an error in my syntax :( This was not there before. Here is the error:

NewCall 17:07:17:080 sip1: Executing script dial plan for call to shaf77.
DialPlan 17:07:17:127 sip1: There was a syntax error in your dial plan on line 
44, please check.
DialPlan 17:07:17:565 sip1: Dial plan execution completed without answering and 
had an execution error message of Dial plan syntax error.
DialPlan 17:07:17:565 sip1: UAS call failed with a response status of 500 and 
Dial plan syntax error.

Here is my plan:

if sys.IsAvailable() then # if online
WP_key = 'd08e0820e8eef3b14976fb172960d98c' ###### EDIT THIS LINE WITH White 
Pages API key

CNAM = {
'xxxxxxxx' => "My Cell", 
'xxxxxxxx' => 'F' 

}
##################you shouldnt edit anything below this####################

if sys.In ..
name = req.Header.from.FromURI.User.to_s 
name = ('1' + name) if name =~ /^[2-9]\d\d[2-9]\d{6}$/
name.sub!(/^011/,'')
if !(@cname = keys_to_ENUM(CNAM)[@cid]) && @cid =~ /^1([2-9]\d\d[2-9]\d{6})$/ 
&& defined?(WP_key)
url = 
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20ur
l%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3B
api_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
if js = sys.WebGet(url,4).to_s
@cname, dname, city, state = %w(businessname displayname city state).map {|x| 
js =~ /"#{x}":"([^"]+)"/; $1}
@cname ||= dname; @cname ||= "#{city}, #{state}" if city && state
end
end
end
end
name.sub!(/^1/,'')
sys.Log("Caller's number: '#{name}'"); sys.Log("Caller's name = '#{cname}'") if 
cname

# sys.SetFromHeader(formatNum(cname || name), nil, nil)
sys.SetFromHeader(cname || name, nil, nil)

# Forward call to bindings. Change FromURI when forwarding to
# @local, or else Bria won't find contact in its phonebook!
sys.Dial("#{sys.Username}@local[fu=#{name}]&XXXXXXXXXX@freephoneline[fu=#{name}]
") #####HARDCODE XXXXXXXXXX as FORWARD NUMBER
# 
sys.Dial("#{sys.Username}@local[fu=#{name}]&XXXXXXXXXX@freephoneline[fu=#{name}]
&XXXXXXXXXX@freephoneline[fu=#{name}]" 
########or you can perform a normal follwme by adding the seconds at the 
end##### 
# sys.Dial("#{sys.Username}@local[fu=#{name}],20") 
# sys.Dial("FOLLOWNUMBER2@freephoneline[fu=#{name}],10") #HARDCODE A NUMBER IF 
U WANT TO USE THIS
# sys.Dial("FOLLOWNUMBER3#freephoneline[fu=#{name}],10") #HARDCODE A NUMBER IF 
U WANT TO USE THIS
####### 

sys.Respond(480, "#{sys.Username} Not available")

sys.Respond(480, "#{sys.Username} Not online") # switch to voice mail

end

else # if phone is not online.
sys.Dial("7783174545freephoneline") #####HARDCODE FORWARD NUMBER
sys.Respond(480, "#{sys.Username} Not available") 
end 

Hmmm... Does this have anything to do with the fact that these are Canadian 
numbers?

Original comment by shafar...@gmail.com on 28 Jul 2010 at 5:09

GoogleCodeExporter commented 9 years ago
Syntax error?! Definitely not! The above post is hard to read (no indents) but 
I guess you have an extra "end" before "name.sub!(/^1/,'')".

As to Canadian numbers: I've never tried this code on Canadian numbers but 
WhitePages' reverse lookup works... maybe it's a different format of City/State.

I'll probably experiment with Canadian numbers on the weekend.

Original comment by mte...@gmail.com on 28 Jul 2010 at 7:51

GoogleCodeExporter commented 9 years ago
I'm not saying that you have a syntax error. I copied and pasted you CNAM setup 
(below) and I get an syntax error way below in my plan... :(

if !(@cname = keys_to_ENUM(CNAM)[@cid]) && @cid =~ /^1([2-9]\d\d[2-9]\d{6})$/ 
&& defined?(WP_key)
url = 
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20ur
l%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3B
api_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
if js = sys.WebGet(url,4).to_s
@cname, dname, city, state = %w(businessname displayname city state).map {|x| 
js =~ /"#{x}":"([^"]+)"/; $1}
@cname ||= dname; @cname ||= "#{city}, #{state}" if city && state

Original comment by shafar...@gmail.com on 28 Jul 2010 at 8:17

GoogleCodeExporter commented 9 years ago
You didn't copy / paste the whole of my dialplan, right? ;-) When you paste 
snippets to your own code, you're on your own.

It's absolutely normal for Ruby interpreter to report the error way below it 
actually is, happens all the time. Version you copied before had 3 ifs and 3 
ends. Newer version - only 2 ifs; I believe you forget to delete extra "end".

Original comment by mte...@gmail.com on 28 Jul 2010 at 8:41

GoogleCodeExporter commented 9 years ago
I've checked, Canadian numbers are detected correctly, with one exception:

DialPlan 03:14:59:382 sip1: Caller's number: '14036128888'
DialPlan 03:14:59:382 sip1: Caller's name:   'Calgary, Ab, AB'

For some reason, published numbers in Calgary return "Calgary" in "city" field 
while unpublished have "Calgary, Ab" in there. The "state" field contains "AB" 
for all entries. Generally, I could get rid of the "extra Ab", but it's not 
bothering me much.

JFYI: DNS records for www.whitepages.com and www.whitepages.ca point to the 
same IP address.

One more thing: the best way to explore all this is the YQL Console:

select * from xml where 
url='http://api.whitepages.com/reverse_phone/1.0/?phone=10_DIGIT_NUM;api_key=API
_KEY_HERE' and itemPath='wp.listings.listing'

Original comment by mte...@gmail.com on 29 Jul 2010 at 3:26

GoogleCodeExporter commented 9 years ago
Thanks mtelis!!!

I took your link 
(http://api.whitepages.com/reverse_phone/1.0/?phone=10_DIGIT_NUM;api_key=API_KEY
_HERE), added my phone # and api key and it worked fine in a browser.

Out of curiosity, why does each person have to have their own API key???

If I want to use your CNAM section from teh dial plan, is this what I need to 
copy?

 # Check CNAM first. If not found and US number, try to lookup caller's name in Whitepages

    if !(@cname = keys_to_ENUM(CNAM)[@cid]) && @cid =~ /^1([2-9]\d\d[2-9]\d{6})$/ && defined?(WP_key)
      url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3Bapi_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
      if js = sys.WebGet(url,4).to_s
        @cname, dname, city, state = %w(businessname displayname city state).map {|x| js =~ /"#{x}":"([^"]+)"/; $1}
        @cname ||= dname; @cname ||= "#{city}, #{state}" if city && state
      end
    end

Original comment by shafar...@gmail.com on 29 Jul 2010 at 6:40

GoogleCodeExporter commented 9 years ago
API key is required because White Pages API imposes certain limitations on the 
total number of requests per day and per second. I don't recall exact numbers 
but they are generous enough for any normal person.

I suggest that you read API docs (one page, won't take you long) and explore 
how it works using YQL Console.

As to the code: yes, this portion deals with CNAM. You need to define CNAM hash 
table, WP_key and @cid must contain caller's number in ENUM format.

One more thing: you're posting the same questions here and at Sipsorcery forum. 
Since I first replied to it here I'm not going to duplicate replies in the 
forum.

Original comment by mte...@gmail.com on 29 Jul 2010 at 7:34

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Thanks again for your help.

Original comment by shafar...@gmail.com on 30 Jul 2010 at 6:48

GoogleCodeExporter commented 9 years ago
There is no simple solution to your problem, because Google Voice has a quite 
short voice mail time-out (if the call isn't answered within 25 seconds, it 
gets forwarded to GV voice-mail). Unfortunately, there is no way you can change 
the time-out, and Google isn't going to add corresponding setting :-(

What I'm saying, if the call isn't answered on your ATA at home, you simply 
don't have enough time to forward it to your cell.

Yet another problem: if you forward incoming call using some other GV account 
or a regular VoIP provider (such as Sipgate or Future-nine), you're going to 
lose caller ID of the original caller, because VoIP providers do not allow you 
to transmit arbitrary caller ID.

There are two ways:

1. Add your cell phone to your Google Voice account. The call will ring your 
home phone and cell phone simultaneously (no very convenient, but...). You may 
also raise your voice and ask Google to add delayed ringing and adjustable 
voice-mail time-out, but it's proven futile so far. Just in case, "delayed 
ringing" means that incoming call rings one of the phones (GV / Settings / 
Voice / Phone) right away and the other(s) after say, 20 seconds... so you 
could ring your home phone immediately and your cell would start ringing 20 sec 
later, if nobody answers at home.

2. Forward incoming call to some media server, answer it there (so that it 
doesn't go to voice-mail) and then transfer to your cell phone. I use Tropo.com 
for this purpose. Incoming call gets forwarded to my ATA right away and to 
Tropo in 15 seconds (using sys.Dial's [dt=15] option). Tropo application calls 
my cell phone, reads caller's name and/or number and asks whether I want to 
take the call. If yes, it transfers call to my cell, otherwise it transfers it 
to VM or just hangup on the caller.

The problem with this approach is that I actually have to answer incoming call 
and therefore, the caller gets billed for it.

As you can see, there is no 100% good solution...

Original comment by mte...@gmail.com on 30 Jul 2010 at 6:57

GoogleCodeExporter commented 9 years ago
Thanks.

I can't add my cell phone number to GV because it's Canadian :(

Still trying to find the one pager on API. On the CNAM setting, do I just copy 
and paste your line? Do I have to add anything else aside from WP API Key?

Original comment by shafar...@gmail.com on 30 Jul 2010 at 7:04

GoogleCodeExporter commented 9 years ago
Then you have no other choice but to forward incoming call to your cell using 
some other provider (some other GV account, for example).

The problem with GV account is that you can't use multi-forwarding 
(sys.Dial("#{sys.Username}@local&cellnumber@provider") and yet, you can't use 
"try home first, forward to cell if no answer" approach because of that silly 
25-sec timeout.

The only solution that I know of is converting Google Voice into regular 
provider, read about it here:

http://forum.sipsorcery.com/viewtopic.php?f=15&t=1689

Original comment by mte...@gmail.com on 30 Jul 2010 at 7:16

GoogleCodeExporter commented 9 years ago
Oops, forgot about CNAM question... the answer is a couple of posts above:

"You need to define CNAM hash table, WP_key and @cid must contain caller's 
number in ENUM format".

Original comment by mte...@gmail.com on 30 Jul 2010 at 7:18

GoogleCodeExporter commented 9 years ago
Thanks. I need to learn what is meant by CNAM hast table. I have a WP Key and 
also need to learn what is meant by @cid must contain caller's number in ENUM 
format.

Time to read up :)

Original comment by shafar...@gmail.com on 30 Jul 2010 at 7:25

GoogleCodeExporter commented 9 years ago
Here's your CNAM hash:

CNAM = {
'xxxxxxxx' => "My Cell", 
'xxxxxxxx' => 'F' 

}

@cid is an instance variable, I renamed name -> @cid. There have been some 
other minor changes from the older version. And... RTFM! :-)

Original comment by mte...@gmail.com on 30 Jul 2010 at 7:34

GoogleCodeExporter commented 9 years ago
I will look for and RTFM. Thanks.

Original comment by shafar...@gmail.com on 30 Jul 2010 at 7:41

GoogleCodeExporter commented 9 years ago
Closing due to inactivity

Original comment by easter...@gmail.com on 8 Feb 2011 at 1:42