Was this page helpful?

GoogleVoice

    Table of contents
    No headers

    Here is the code for 0.0.5 .. see attachments at the bottom for newer builds.

    Thanks,

     

    Graham 

     

    Rebol [
    	title: "GoogleVoice"
    	author: "SynapseDirect"
    	date: 29-Aug-2010
    	file: %googlevoice.r
            version: 0.0.5
    	rights: 'LGPL
    ]
    
    ; user settings
    pass:  "********" ; <<<<<< your gmail password
    gmail: reboler@gmail.com ;<<<<<<< your gmail id
    forwarding-number: "+1000000000"  ;<<<<< your googlevoice forwarding number
    
    ; API endpoints
    login-url: https://www.google.com/accounts/ClientLogin
    voice-api: https://www.google.com/voice
    
    ; globals
    token: none
    rnr_se: none
    
    if not value? 'load-json [
    	do http://www.ross-gill.com/r/altjson.r
    ]
    
    if not value? 'to-webform [
    	do http://www.ross-gill.com/r/altwebform.r
    ]
    
    if not value? 'ctx-list-view [
    	do http://hmkdesign.dk/data/projects/list-view/downloads/release/list-view.r
    ]
    
    url-encode: func [
        "URL-encode a string" 
        data "String to encode" 
        /local new-data
    ] [
        new-data: make string! "" 
        normal-char: charset [
            #"A" - #"Z" #"a" - #"z" 
            #"@" #"." #"*" #"-" #"_" 
            #"0" - #"9"
        ] 
        if not string? data [return new-data] 
        forall data [
            append new-data either find normal-char first data [
                first data
            ] [
                rejoin ["%" to-string skip tail (to-hex to-integer first data) -2]
            ]
        ] 
        new-data
    ] 
    
    login: func [  uidfld [object!] passfld [object!] 
    	/local payload uid pass phone tmp
    ][
    	uid: get-face uidfld
    	pass: get-face passfld
    
    	; get the token
    	if none? token [
    		payload: rejoin  [ "accountType=GOOGLE&Email=" uid "&Passwd=" pass "&service=grandcentral&source=REBOL" ]
    		if error? set/any 'err try [
    			result: read/custom login-url reduce [ 'POST payload ]
    			either parse result [ thru "Auth=" copy token to end ][
    				trim/head/tail token
    			][
    				alert "Unable to get login token!"
    				return
    			]
    		][
    			probe mold disarm err
    			probe payload
    			return
    		]
    	]
    	; now get the _rnr_se value
    	if error? set/any 'err try [
    		result: read/custom join voice-api "#history" compose/deep [ header [ Authorization: (join "GoogleLogin auth=" token) ]] 
    		; probe result
    		either find result "Sign in with your" [
    			alert "History view failed"
    			write %result.html result
    			browse %result.html
    			return
    		][
    			either tmp: find result "_rnr_se" [
    				parse tmp [ thru {value="} copy rnr_se to {"/} to end ]
    			][
    				alert "Can not find _rnr_se!"
    				return
    			]			
    		]
    	][
    		probe mold disarm err
    		alert "Unable to login to history page"
    		return
    	]
    	; has _rnr_se, so load all our contacts
    	either parse result [ thru {var _gcData =} copy json to ";" to end ][
    		;?? json
    		if error? set/any 'err  try [
    			gcontacts: load-json replace/all json {'} {"}
    			contact-data: copy []
    			; get the contactPhones object
    			contacts: get in gcontacts 'contacts
    			foreach id next first contacts [
    				if contact: get in contacts id [
    					repend/only contact-data [ contact/name contact/phoneNumber contact/phoneTypeName ]   
    				]
    			]
    			either empty? contact-data [
    				alert "no contacts!"
    			][
    				set-face lv contact-data				
    			]
    		][
    			probe mold disarm err
    			alert "JSON error"
    			return
    		]
    	][
    		alert "failed to load contacts"
    	]
    
    ] 
    
    ; /voice/sms/send/ id=&phoneNumber=[number to text]&text=[URL Encoded message]&_rnr_se=[pull from page]
    
    send-sms: func [ data 
    	/local err payload txt
    ][
    	if any [ 
    		none? rnr_se 
    		none? token
    	][
    		alert "You need to login first!"
    		return
    	]
    	if data/3 <> "mobile" [
    		alert "Not a mobile number!"
    		return
    	]	
    
    	if not txt: request-text [
    		alert "cancelled1"
    		return
    	]
    
    	payload: to-webform context [
    		phoneNumber: next next data/2
    		text: txt
    		_rnr_se: rnr_se
    		id: ""
    	]
    	
    	payload: rejoin [
    		"_rnr_se=" url-encode rnr_se
    		"&phoneNumber=" url-encode next data/2
    		"&text=" url-encode txt
    		"&id=" ""
    	]
    	
    	probe payload
    	if error? set/any 'err try [
    		result: read/custom join voice-api "/sms/send/"  compose/deep [ POST (payload) header [ Authorization: (join "GoogleLogin auth=" token) ]]
    		probe result
    	][
    		probe mold disarm err
    	]
    ]
    
    ; POST /voice/call/connect/ outgoingNumber=[number to call]&forwardingNumber=[forwarding number]&subscriberNumber=undefined&phoneType=[phone type]&remember=0&_rnr_se=[pull from page]
    
    call-phone: func [ data 
    	/local err payload pt
    ][
    	if any [ 
    		none? rnr_se 
    		none? token
    	][
    		alert "You need to login first!"
    		return
    	]
    
    	PT: switch/default data/3 [
    		"home" [ 1 ]
    		"mobile" [ 2 ]
    		"work" [ 3 ]
    		"gizmo" [ 7 ]
    	][ 1 ]
    	
    	payload: to-webform context [
    		outgoingNumber: data/2
    		forwardingNumber: forwarding-number
    		subscriberNumber: "undefined"
    		phoneType: PT
    		remember: 0
    		_rnr_se: rnr_se
    	]
    	
    	probe payload
    	if error? set/any 'err try [
    		result: read/custom join voice-api "/call/connect/" compose/deep [ POST (payload) header [ Authorization: (join "GoogleLogin auth=" token) ]]
    		probe result
    	][
    		probe mold disarm err
    	]
    ]
    
    view center-face layout compose/deep [
    	across
    	label "UID: " uidfld: field (form gmail) return
    	label "PASS: " passfld: field (form pass) return
    	button "Login" [ login uidfld passfld ]
    	button "Halt" [ unview/all halt ] return
        lv: list-view 300x200 with [
                data-columns: [ name number phonetype ]
                viewed-columns: [ name number phonetype  ]
                widths: [ .4 .3 .3 ]
                data:  [ ]
    	] return
    	button "Call" [ call-phone lv/get-row ]
    	button "SMS" [ send-sms lv/get-row ]
    ]
    Was this page helpful?
    Tag page (Edit tags)
    • No tags
    You must login to post a comment.
    Powered by MindTouch Core