Posted By

reboltutorial on 12/11/10


Tagged


Versions (?)

sms


 / Published in: R
 

URL: http://rebol.wik.is/GoogleVoice

  1. Rebol [
  2. title: "GoogleVoice"
  3. author: "SynapseDirect"
  4. date: 29-Aug-2010
  5. file: %googlevoice.r
  6. version: 0.0.5
  7. rights: 'LGPL
  8. ]
  9.  
  10. ; user settings
  11. pass: "********" ; <<<<<< your gmail password
  12. gmail: [email protected] ;<<<<<<< your gmail id
  13. forwarding-number: "+1000000000" ;<<<<< your googlevoice forwarding number
  14.  
  15. ; API endpoints
  16. login-url: https://www.google.com/accounts/ClientLogin
  17. voice-api: https://www.google.com/voice
  18.  
  19. ; globals
  20. token: none
  21. rnr_se: none
  22.  
  23. if not value? 'load-json [
  24. do http://www.ross-gill.com/r/altjson.r
  25. ]
  26.  
  27. if not value? 'to-webform [
  28. do http://www.ross-gill.com/r/altwebform.r
  29. ]
  30.  
  31. if not value? 'ctx-list-view [
  32. do http://97.107.135.89/www.hmkdesign.dk/data/projects/list-view/downloads/list-view.r
  33. ]
  34.  
  35. url-encode: func [
  36. "URL-encode a string"
  37. data "String to encode"
  38. /local new-data
  39. ] [
  40. new-data: make string! ""
  41. normal-char: charset [
  42. #"A" - #"Z" #"a" - #"z"
  43. #"@" #"." #"*" #"-" #"_"
  44. #"0" - #"9"
  45. ]
  46. if not string? data [return new-data]
  47. forall data [
  48. append new-data either find normal-char first data [
  49. first data
  50. ] [
  51. rejoin ["%" to-string skip tail (to-hex to-integer first data) -2]
  52. ]
  53. ]
  54. new-data
  55. ]
  56.  
  57. login: func [ uidfld [object!] passfld [object!]
  58. /local payload uid pass phone tmp
  59. ][
  60. uid: get-face uidfld
  61. pass: get-face passfld
  62.  
  63. ; get the token
  64. if none? token [
  65. payload: rejoin [ "accountType=GOOGLE&Email=" uid "&Passwd=" pass "&service=grandcentral&source=REBOL" ]
  66. if error? set/any 'err try [
  67. result: read/custom login-url reduce [ 'POST payload ]
  68. either parse result [ thru "Auth=" copy token to end ][
  69. trim/head/tail token
  70. ][
  71. alert "Unable to get login token!"
  72. return
  73. ]
  74. ][
  75. probe mold disarm err
  76. probe payload
  77. return
  78. ]
  79. ]
  80. ; now get the _rnr_se value
  81. if error? set/any 'err try [
  82. result: read/custom join voice-api "#history" compose/deep [ header [ Authorization: (join "GoogleLogin auth=" token) ]]
  83. ; probe result
  84. either find result "Sign in with your" [
  85. alert "History view failed"
  86. write %result.html result
  87. browse %result.html
  88. return
  89. ][
  90. either tmp: find result "_rnr_se" [
  91. parse tmp [ thru {value="} copy rnr_se to {"/} to end ]
  92. ][
  93. alert "Can not find _rnr_se!"
  94. return
  95. ]
  96. ]
  97. ][
  98. probe mold disarm err
  99. alert "Unable to login to history page"
  100. return
  101. ]
  102. ; has _rnr_se, so load all our contacts
  103. either parse result [ thru {var _gcData =} copy json to ";" to end ][
  104. ;?? json
  105. if error? set/any 'err try [
  106. gcontacts: load-json replace/all json {'} {"}
  107. contact-data: copy []
  108. ; get the contactPhones object
  109. contacts: get in gcontacts 'contacts
  110. foreach id next first contacts [
  111. if contact: get in contacts id [
  112. repend/only contact-data [ contact/name contact/phoneNumber contact/phoneTypeName ]
  113. ]
  114. ]
  115. either empty? contact-data [
  116. alert "no contacts!"
  117. ][
  118. set-face lv contact-data
  119. ]
  120. ][
  121. probe mold disarm err
  122. alert "JSON error"
  123. return
  124. ]
  125. ][
  126. alert "failed to load contacts"
  127. ]
  128.  
  129. ]
  130.  
  131. ; /voice/sms/send/ id=&phoneNumber=[number to text]&text=[URL Encoded message]&_rnr_se=[pull from page]
  132.  
  133. send-sms: func [ data
  134. /local err payload txt
  135. ][
  136. if any [
  137. none? rnr_se
  138. none? token
  139. ][
  140. alert "You need to login first!"
  141. return
  142. ]
  143. if data/3 <> "mobile" [
  144. alert "Not a mobile number!"
  145. return
  146. ]
  147.  
  148. if not txt: request-text [
  149. alert "cancelled1"
  150. return
  151. ]
  152.  
  153. payload: to-webform context [
  154. phoneNumber: next next data/2
  155. text: txt
  156. _rnr_se: rnr_se
  157. id: ""
  158. ]
  159.  
  160. payload: rejoin [
  161. "_rnr_se=" url-encode rnr_se
  162. "&phoneNumber=" url-encode next data/2
  163. "&text=" url-encode txt
  164. "&id=" ""
  165. ]
  166.  
  167. probe payload
  168. if error? set/any 'err try [
  169. result: read/custom join voice-api "/sms/send/" compose/deep [ POST (payload) header [ Authorization: (join "GoogleLogin auth=" token) ]]
  170. probe result
  171. ][
  172. probe mold disarm err
  173. ]
  174. ]
  175.  
  176. ; POST /voice/call/connect/ outgoingNumber=[number to call]&forwardingNumber=[forwarding number]&subscriberNumber=undefined&phoneType=[phone type]&remember=0&_rnr_se=[pull from page]
  177.  
  178. call-phone: func [ data
  179. /local err payload pt
  180. ][
  181. if any [
  182. none? rnr_se
  183. none? token
  184. ][
  185. alert "You need to login first!"
  186. return
  187. ]
  188.  
  189. PT: switch/default data/3 [
  190. "home" [ 1 ]
  191. "mobile" [ 2 ]
  192. "work" [ 3 ]
  193. "gizmo" [ 7 ]
  194. ][ 1 ]
  195.  
  196. payload: to-webform context [
  197. outgoingNumber: data/2
  198. forwardingNumber: forwarding-number
  199. subscriberNumber: "undefined"
  200. phoneType: PT
  201. remember: 0
  202. _rnr_se: rnr_se
  203. ]
  204.  
  205. probe payload
  206. if error? set/any 'err try [
  207. result: read/custom join voice-api "/call/connect/" compose/deep [ POST (payload) header [ Authorization: (join "GoogleLogin auth=" token) ]]
  208. probe result
  209. ][
  210. probe mold disarm err
  211. ]
  212. ]
  213.  
  214. view center-face layout compose/deep [
  215. across
  216. label "UID: " uidfld: field (form gmail) return
  217. label "PASS: " passfld: field (form pass) return
  218. button "Login" [ login uidfld passfld ]
  219. button "Halt" [ unview/all halt ] return
  220. lv: list-view 300x200 with [
  221. data-columns: [ name number phonetype ]
  222. viewed-columns: [ name number phonetype ]
  223. widths: [ .4 .3 .3 ]
  224. data: [ ]
  225. ] return
  226. button "Call" [ call-phone lv/get-row ]
  227. button "SMS" [ send-sms lv/get-row ]
  228. ]

Report this snippet  

You need to login to post a comment.