Rebol > GoogleVoice

GoogleVoice

Table of contents
No headers
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://97.107.135.89/www.hmkdesign.dk/data/projects/list-view/downloads/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 ]
]
Tag page

Files 1

FileSizeDateAttached by 
gvoice2.r
0.0.6 - can add users ( to list only )
6.08 kB21:58, 29 Aug 2010AdminActions
You must login to post a comment.
wik.is