├── LICENSE
├── example.php
├── README.md
└── GoogleVoice.php
/LICENSE:
--------------------------------------------------------------------------------
1 | http://creativecommons.org/licenses/BSD/
2 |
3 | Copyright (c) 2009, Aaron Parecki
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | * Neither the name of Aaron Parecki nor the
14 | names of its contributors may be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY AARON PARECKI ''AS IS'' AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL AARON PARECKI BE LIABLE FOR ANY
21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 |
--------------------------------------------------------------------------------
/example.php:
--------------------------------------------------------------------------------
1 | callNumber('9995551212', '5558675309', 'mobile');
10 |
11 | // Cancel in-progress call placed using callNumber.
12 | $gv->cancelCall('9995551212', '5558675309', 'mobile');
13 |
14 | // Send an SMS to a phone number.
15 | $gv->sendSMS('9995551212', 'Sending a message!');
16 |
17 | // Get all unread SMSs from your Google Voice Inbox.
18 | $sms = $gv->getUnreadSMS();
19 | $msgIDs = array();
20 | foreach($sms as $s) {
21 | echo 'Message from: '.$s->phoneNumber.' on '.$s->displayStartDateTime.': '.$s->messageText."
\n";
22 | if(!in_array($s->id, $msgIDs)) {
23 | // Mark the message as read in your Google Voice Inbox.
24 | $gv->markMessageRead($s->id);
25 | $msgIDs[] = $s->id;
26 | }
27 | }
28 |
29 | // Get all unread messages from your Google Voice Voicemail.
30 | $voice_mails = $gv->getUnreadVoicemail();
31 | $msgIDs = array();
32 | foreach($voice_mails as $v) {
33 | echo 'Message from: '.$v->phoneNumber.' on '.$v->displayStartDateTime.': '.$v->messageText."
\n";
34 | if(!in_array($v->id, $msgIDs)) {
35 | // Mark the message as read in your Google Voice Voicemail.
36 | $gv->markMessageRead($v->id);
37 | $msgIDs[] = $v->id;
38 | }
39 | }
40 |
41 | // Download all unread Google Voice voicemails as indididual MP3 files.
42 | $voice_mails = $gv->getUnreadVoicemail();
43 | $msgIDs = array();
44 | foreach($voice_mails as $v) {
45 | // Uncomment next line if you want message texts displayed as in previous example.
46 | // echo 'Message from: '.$v->phoneNumber.' on '.$v->displayStartDateTime.': '.$v->messageText."
\n";
47 | // Download individual voicemail.
48 | $mp3 = $gv->getVoicemailMP3($v->id);
49 | // construct mp3 filename using message id as filename.
50 | $mp3file = $v->id.".mp3";
51 | // write mp3 file to disk.
52 | $fh = fopen($mp3file, 'w') or die("can't open file");
53 | fwrite($fh, $mp3);
54 | fclose($fh);
55 | if(!in_array($v->id, $msgIDs)) {
56 | // Mark the message as read in your Google Voice Voicemail.
57 | $gv->markMessageRead($v->id);
58 | $msgIDs[] = $v->id;
59 | }
60 | }
61 |
62 | ?>
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://unmaintained.tech/)
2 |
3 | Google Voice PHP API
4 | ====================
5 |
6 | An API to interact with Google Voice using PHP.
7 |
8 | Currently the API can place calls, cancel previously placed calls, send and
9 | receive SMS messages, add a note to or remove a note from a message or voicemail,
10 | mark a message or voicemail as read or unread, and download transcriptions and/or
11 | MP3 files of voicemail. Feel free to implement new functionality and send me your
12 | changes so I can incorporate them into this library!
13 |
14 | getUnreadSMS, getReadSMS, getUnreadVoicemail, and getReadVoicemail all return
15 | an array of JSON objects. Each object has the following attributes, example
16 | values included:
17 |
18 | $msg->id = c3716aa447a19c7e2e7347f443dd29091401ae13
19 | $msg->phoneNumber = +15555555555
20 | $msg->displayNumber = (555) 555-5555
21 | $msg->startTime = 1359918736555
22 | $msg->displayStartDateTime = 2/3/13 5:55 PM
23 | $msg->displayStartTime = 5:55 PM
24 | $msg->relativeStartTime = 5 hours ago
25 | $msg->note =
26 | $msg->isRead = true
27 | $msg->isSpam = false
28 | $msg->isTrash = false
29 | $msg->star: = alse
30 | $msg->messageText = Hello, cellphone.
31 | $msg->labels = [sms,all]
32 | $msg->type = 11
33 | $msg->children =
34 |
35 | Note: Receiving SMSs and voicemails is mostly unnecessary via this API since
36 | Google now allows SMSs to be forwarded to an email address. It is a better
37 | idea to parse those incoming emails with a script.
38 |
39 | SMS and Voice Integration
40 | =========================
41 |
42 | For better SMS and voice integration with your web app, check out Tropo
43 | at [tropo.com](http://tropo.com). Tropo is free for development, and you will
44 | get better results than using unsupported Google Voice API calls.
45 |
46 | Check out some [sample apps built with Tropo](https://www.tropo.com/docs/scripting/tutorials.htm)
47 |
48 | Disclaimer
49 | ==========
50 |
51 | This code is provided for educational purposes only. This code may stop
52 | working at any time if Google changes their login mechanism or their web
53 | pages. You agree that by downloading this code you agree to use it solely
54 | at your own risk.
55 |
56 | License
57 | =======
58 |
59 | Copyright 2009 by Aaron Parecki
60 | [http://aaronparecki.com](http://aaronparecki.com)
61 |
62 | See LICENSE
63 |
64 |
--------------------------------------------------------------------------------
/GoogleVoice.php:
--------------------------------------------------------------------------------
1 | _login = $login;
24 | $this->_pass = $pass;
25 | $this->_cookieFile = '/tmp/gvCookies.txt';
26 |
27 | $this->_ch = curl_init();
28 | curl_setopt($this->_ch, CURLOPT_COOKIEJAR, $this->_cookieFile);
29 | curl_setopt($this->_ch, CURLOPT_FOLLOWLOCATION, TRUE);
30 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
31 | curl_setopt($this->_ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); //was "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
32 | }
33 |
34 |
35 |
36 | private function _logIn() {
37 | global $conf;
38 |
39 | if($this->_loggedIn)
40 | return TRUE;
41 |
42 | // Fetch the Google Voice login page input fields
43 | $URL='https://accounts.google.com/ServiceLogin?service=grandcentral&passive=1209600&continue=https://www.google.com/voice/b/0/redirection/voice&followup=https://www.google.com/voice/b/0/redirection/voice#inbox'; //adding login to GET prefills with username "&Email=$this->_login"
44 | curl_setopt($this->_ch, CURLOPT_URL, $URL);
45 | $html = curl_exec($this->_ch);
46 |
47 | // Send HTTP POST service login request using captured input information.
48 | $URL='https://accounts.google.com/signin/challenge/sl/password'; // This is the second page of the two page signin
49 | curl_setopt($this->_ch, CURLOPT_URL, $URL);
50 | $postarray = $this->dom_get_input_tags($html); // Using DOM keeps the order of the name/value from breaking the code.
51 |
52 | // Parse the returned webpage for the "GALX" token, needed for POST requests.
53 | if((!isset($postarray['GALX']) || $postarray['GALX']=='') && (!isset($postarray['gxf']) || $postarray['gxf']=='')){
54 | $pi1 = var_export($postarray, TRUE);
55 | error_log("Could not parse for GALX or gxf token. Inputs from page:\n" . $pi1 . "\n\nHTML from page:" . $html);
56 | throw new Exception("Could not parse for GALX or gxf token. Inputs from page:\n" . $pi1);
57 | }
58 |
59 | $postarray['Email'] = $this->_login; //Add login to POST array
60 | $postarray['Passwd'] = $this->_pass; //Add password to POST array
61 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
62 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $postarray);
63 | $html = curl_exec($this->_ch);
64 |
65 | // Test if the service login was successful.
66 | $postarray = $this->dom_get_input_tags($html); // Using DOM keeps the order of the name/value from breaking the code.
67 | if(isset($postarray['_rnr_se']) && $postarray['_rnr_se']!='') {
68 | $this->_rnr_se = $postarray['_rnr_se'];
69 | $this->_loggedIn = TRUE;
70 | } else {
71 | $pi2 = var_export($postarray, TRUE);
72 | error_log("Could not log in to Google Voice with username: " . $this->_login .
73 | "\n\nMay need to change scraping. Here are the inputs from the page:\n". $pi2
74 | ); //add POST action information from DOM. May help hunt down single or dual sign on page changes.
75 | throw new Exception("Could not log in to Google Voice with username: " . $this->_login . "\nLook at error log for detailed input information.\n");
76 | }
77 | }
78 |
79 |
80 |
81 | /**
82 | * Place a call to $number connecting first to $fromNumber.
83 | * @param $number The 10-digit phone number to call (formatted with parens and hyphens or none).
84 | * @param $fromNumber The 10-digit number on your account to connect the call (no hyphens or spaces).
85 | * @param $phoneType (mobile, work, home) The type of phone the $fromNumber is. The call will not be connected without this value.
86 | */
87 | public function callNumber($number, $from_number, $phone_type = 'mobile') {
88 | $types = array(
89 | 'mobile' => 2,
90 | 'work' => 3,
91 | 'home' => 1
92 | );
93 |
94 | // Make sure phone type is set properly.
95 | if(!array_key_exists($phone_type, $types))
96 | throw new Exception('Phone type must be mobile, work, or home');
97 |
98 | // Login to the service if not already done.
99 | $this->_logIn();
100 |
101 | // Send HTTP POST request.
102 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/call/connect/');
103 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
104 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
105 | '_rnr_se' => $this->_rnr_se,
106 | 'forwardingNumber' => '+1'.$from_number,
107 | 'outgoingNumber' => $number,
108 | 'phoneType' => $types[$phone_type],
109 | 'remember' => 0,
110 | 'subscriberNumber' => 'undefined'
111 | ));
112 | curl_exec($this->_ch);
113 | }
114 |
115 |
116 |
117 | /**
118 | * Cancel a call to $number connecting first to $fromNumber.
119 | * @param $number The 10-digit phone number to call (formatted with parens and hyphens or none).
120 | * @param $fromNumber The 10-digit number on your account to connect the call (no hyphens or spaces).
121 | * @param $phoneType (mobile, work, home) The type of phone the $fromNumber is. The call will not be connected without this value.
122 | */
123 | public function cancelCall($number, $from_number, $phone_type = 'mobile') {
124 | $types = array(
125 | 'mobile' => 2,
126 | 'work' => 3,
127 | 'home' => 1
128 | );
129 |
130 | // Make sure phone type is set properly.
131 | if(!array_key_exists($phone_type, $types))
132 | throw new Exception('Phone type must be mobile, work, or home');
133 |
134 | // Login to the service if not already done.
135 | $this->_logIn();
136 |
137 | // Send HTTP POST request.
138 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/call/cancel/');
139 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
140 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
141 | '_rnr_se' => $this->_rnr_se,
142 | 'forwardingNumber' => '+1'.$from_number,
143 | 'outgoingNumber' => $number,
144 | 'phoneType' => $types[$phone_type],
145 | 'remember' => 0,
146 | 'subscriberNumber' => 'undefined'
147 | ));
148 | curl_exec($this->_ch);
149 | }
150 |
151 |
152 |
153 | /**
154 | * Send an SMS to $number containing $message.
155 | * @param $number The 10-digit phone number to send the message to (formatted with parens and hyphens or none).
156 | * @param $message The message to send within the SMS.
157 | */
158 | public function sendSMS($number, $message) {
159 | // Login to the service if not already done.
160 | $this->_logIn();
161 |
162 | // Send HTTP POST request.
163 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/sms/send/');
164 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
165 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
166 | '_rnr_se' => $this->_rnr_se,
167 | 'phoneNumber' => '+1'.$number,
168 | 'text' => $message
169 | ));
170 | curl_exec($this->_ch);
171 | }
172 |
173 |
174 |
175 | public function getNewSMS()
176 | {
177 | $this->_logIn();
178 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/recent/sms/');
179 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
180 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
181 | $xml = curl_exec($this->_ch);
182 |
183 | $dom = new DOMDocument();
184 |
185 | // load the "wrapper" xml (contains two elements, json and html)
186 | $dom->loadXML($xml);
187 | $json = $dom->documentElement->getElementsByTagName("json")->item(0)->nodeValue;
188 | $json = json_decode($json);
189 |
190 | // now make a dom parser which can parse the contents of the HTML tag
191 | $html = $dom->documentElement->getElementsByTagName("html")->item(0)->nodeValue;
192 | // replace all "&" with "&" so it can be parsed
193 | $html = str_replace("&", "&", $html);
194 | $dom->loadHTML($html);
195 | $xpath = new DOMXPath($dom);
196 |
197 | $results = array();
198 |
199 | foreach( $json->messages as $mid=>$convo )
200 | {
201 | $elements = $xpath->query("//div[@id='$mid']//div[@class='gc-message-sms-row']");
202 | if(!is_null($elements))
203 | {
204 | if( in_array('unread', $convo->labels) )
205 | {
206 | foreach($elements as $i=>$element)
207 | {
208 | $XMsgFrom = $xpath->query("span[@class='gc-message-sms-from']", $element);
209 | $msgFrom = '';
210 | foreach($XMsgFrom as $m)
211 | $msgFrom = trim($m->nodeValue);
212 |
213 | if( $msgFrom != "Me:" )
214 | {
215 | $XMsgText = $xpath->query("span[@class='gc-message-sms-text']", $element);
216 | $msgText = '';
217 | foreach($XMsgText as $m)
218 | $msgText = trim($m->nodeValue);
219 |
220 | $XMsgTime = $xpath->query("span[@class='gc-message-sms-time']", $element);
221 | $msgTime = '';
222 | foreach($XMsgTime as $m)
223 | $msgTime = trim($m->nodeValue);
224 |
225 | $results[] = array('msgID'=>$mid, 'phoneNumber'=>$convo->phoneNumber, 'message'=>$msgText, 'date'=>date('Y-m-d H:i:s', strtotime(date('m/d/Y ',intval($convo->startTime/1000)).$msgTime)));
226 | }
227 | }
228 | }
229 | else
230 | {
231 | //echo "This message is not unread\n";
232 | }
233 | }
234 | else
235 | {
236 | //echo "gc-message-sms-row query failed\n";
237 | }
238 | }
239 |
240 | return $results;
241 | }
242 |
243 |
244 |
245 | public function markSMSRead($msgID)
246 | {
247 | $this->_logIn();
248 |
249 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/mark/');
250 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
251 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
252 | '_rnr_se'=>$this->_rnr_se,
253 | 'messages'=>$msgID,
254 | 'read'=>1
255 | ));
256 | curl_exec($this->_ch);
257 | }
258 |
259 |
260 |
261 | public function markSMSDeleted($msgID)
262 | {
263 | $this->_logIn();
264 |
265 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/deleteMessages/');
266 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
267 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
268 | '_rnr_se'=>$this->_rnr_se,
269 | 'messages'=>$msgID,
270 | 'trash'=>1
271 | ));
272 | curl_exec($this->_ch);
273 | }
274 |
275 |
276 |
277 | /**
278 | * Add a note to a message in a Google Voice Inbox or Voicemail.
279 | * @param $message_id The id of the message to update.
280 | * @param $note The message to send within the SMS.
281 | */
282 | public function addNote($message_id, $note) {
283 | // Login to the service if not already done.
284 | $this->_logIn();
285 |
286 | // Send HTTP POST request.
287 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/savenote/');
288 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
289 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
290 | '_rnr_se' => $this->_rnr_se,
291 | 'id' => $message_id,
292 | 'note' => $note
293 | ));
294 | curl_exec($this->_ch);
295 | }
296 |
297 |
298 |
299 | /**
300 | * Removes a note from a message in a Google Voice Inbox or Voicemail.
301 | * @param $message_id The id of the message to update.
302 | */
303 | public function removeNote($message_id, $note) {
304 | // Login to the service if not already done.
305 | $this->_logIn();
306 |
307 | // Send HTTP POST request.
308 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/deletenote/');
309 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
310 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
311 | '_rnr_se' => $this->_rnr_se,
312 | 'id' => $message_id,
313 | ));
314 | curl_exec($this->_ch);
315 | }
316 |
317 |
318 |
319 | /**
320 | * Get all of the unread SMS messages in a Google Voice inbox.
321 | */
322 | public function getUnreadSMS() {
323 | // Login to the service if not already done.
324 | $this->_logIn();
325 |
326 | // Send HTTP POST request.
327 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/recent/sms/');
328 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
329 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
330 | $xml = curl_exec($this->_ch);
331 |
332 | // Load the "wrapper" xml (contains two elements, json and html).
333 | $dom = new DOMDocument();
334 | $dom->loadXML($xml);
335 | $json = $dom->documentElement->getElementsByTagName("json")->item(0)->nodeValue;
336 | $json = json_decode($json);
337 |
338 | // Loop through all of the messages.
339 | $results = array();
340 | foreach($json->messages as $mid=>$convo) {
341 | if($convo->isRead == FALSE) {
342 | $results[] = $convo;
343 | }
344 | }
345 | return $results;
346 | }
347 |
348 |
349 |
350 | /**
351 | * Get all of the read SMS messages in a Google Voice inbox.
352 | */
353 | public function getReadSMS() {
354 | // Login to the service if not already done.
355 | $this->_logIn();
356 |
357 | // Send HTTP POST request.
358 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/recent/sms/');
359 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
360 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
361 | $xml = curl_exec($this->_ch);
362 |
363 | // Load the "wrapper" xml (contains two elements, json and html).
364 | $dom = new DOMDocument();
365 | $dom->loadXML($xml);
366 | $json = $dom->documentElement->getElementsByTagName("json")->item(0)->nodeValue;
367 | $json = json_decode($json);
368 |
369 | // Loop through all of the messages.
370 | $results = array();
371 | foreach($json->messages as $mid=>$convo) {
372 | if($convo->isRead == TRUE) {
373 | $results[] = $convo;
374 | }
375 | }
376 | return $results;
377 | }
378 |
379 |
380 |
381 | /**
382 | * Get all of the unread SMS messages from a Google Voice Voicemail.
383 | */
384 | public function getUnreadVoicemail() {
385 | // Login to the service if not already done.
386 | $this->_logIn();
387 |
388 | // Send HTTP POST request.
389 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/recent/voicemail/');
390 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
391 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
392 | $xml = curl_exec($this->_ch);
393 |
394 | // Load the "wrapper" xml (contains two elements, json and html)
395 | $dom = new DOMDocument();
396 | $dom->loadXML($xml);
397 | $json = $dom->documentElement->getElementsByTagName("json")->item(0)->nodeValue;
398 | $json = json_decode($json);
399 |
400 | // Loop through all of the messages.
401 | $results = array();
402 | foreach($json->messages as $mid=>$convo) {
403 | if($convo->isRead == FALSE) {
404 | $results[] = $convo;
405 | }
406 | }
407 | return $results;
408 | }
409 |
410 |
411 |
412 | /**
413 | * Get all of the unread SMS messages from a Google Voice Voicemail.
414 | */
415 | public function getReadVoicemail() {
416 | // Login to the service if not already done.
417 | $this->_logIn();
418 |
419 | // Send HTTP POST request.
420 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/recent/voicemail/');
421 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
422 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
423 | $xml = curl_exec($this->_ch);
424 |
425 | // load the "wrapper" xml (contains two elements, json and html)
426 | $dom = new DOMDocument();
427 | $dom->loadXML($xml);
428 | $json = $dom->documentElement->getElementsByTagName("json")->item(0)->nodeValue;
429 | $json = json_decode($json);
430 |
431 | // Loop through all of the messages.
432 | $results = array();
433 | foreach( $json->messages as $mid=>$convo ) {
434 | if( $convo->isRead == TRUE ) {
435 | $results[] = $convo;
436 | }
437 | }
438 | return $results;
439 | }
440 |
441 |
442 |
443 | /**
444 | * Get MP3 of a Google Voice Voicemail.
445 | */
446 | public function getVoicemailMP3($message_id) {
447 | // Login to the service if not already done.
448 | $this->_logIn();
449 |
450 | // Send HTTP POST request.
451 | curl_setopt($this->_ch, CURLOPT_URL, "https://www.google.com/voice/media/send_voicemail/$message_id/");
452 | curl_setopt($this->_ch, CURLOPT_POST, FALSE);
453 | curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
454 | $results = curl_exec($this->_ch);
455 |
456 | return $results;
457 | }
458 |
459 |
460 |
461 | /**
462 | * Mark a message in a Google Voice Inbox or Voicemail as read.
463 | * @param $message_id The id of the message to update.
464 | * @param $note The message to send within the SMS.
465 | */
466 | public function markMessageRead($message_id) {
467 | // Login to the service if not already done.
468 | $this->_logIn();
469 |
470 | // Send HTTP POST request.
471 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/mark/');
472 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
473 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
474 | '_rnr_se' => $this->_rnr_se,
475 | 'messages' => $message_id,
476 | 'read' => '1'
477 | ));
478 | curl_exec($this->_ch);
479 | }
480 |
481 |
482 |
483 | /**
484 | * Mark a message in a Google Voice Inbox or Voicemail as unread.
485 | * @param $message_id The id of the message to update.
486 | * @param $note The message to send within the SMS.
487 | */
488 | public function markMessageUnread($message_id) {
489 | // Login to the service if not already done.
490 | $this->_logIn();
491 |
492 | // Send HTTP POST request.
493 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/mark/');
494 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
495 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
496 | '_rnr_se' => $this->_rnr_se,
497 | 'messages' => $message_id,
498 | 'read' => '0'
499 | ));
500 | curl_exec($this->_ch);
501 | }
502 |
503 |
504 |
505 | /**
506 | * Delete a message or conversation.
507 | * @param $message_id The ID of the conversation to delete.
508 | */
509 | public function deleteMessage($message_id) {
510 | $this->_logIn();
511 |
512 | curl_setopt($this->_ch, CURLOPT_URL, 'https://www.google.com/voice/inbox/deleteMessages/');
513 | curl_setopt($this->_ch, CURLOPT_POST, TRUE);
514 | curl_setopt($this->_ch, CURLOPT_POSTFIELDS, array(
515 | '_rnr_se' => $this->_rnr_se,
516 | 'messages' => $message_id,
517 | 'trash' => 1
518 | ));
519 |
520 | curl_exec($this->_ch);
521 | }
522 |
523 |
524 |
525 | public function dom_dump($obj) {
526 | if ($classname = get_class($obj)) {
527 | $retval = "Instance of $classname, node list: \n";
528 | switch (TRUE) {
529 | case ($obj instanceof DOMDocument):
530 | $retval .= "XPath: {$obj->getNodePath()}\n".$obj->saveXML($obj);
531 | break;
532 | case ($obj instanceof DOMElement):
533 | $retval .= "XPath: {$obj->getNodePath()}\n".$obj->ownerDocument->saveXML($obj);
534 | break;
535 | case ($obj instanceof DOMAttr):
536 | $retval .= "XPath: {$obj->getNodePath()}\n".$obj->ownerDocument->saveXML($obj);
537 | break;
538 | case ($obj instanceof DOMNodeList):
539 | for ($i = 0; $i < $obj->length; $i++) {
540 | $retval .= "Item #$i, XPath: {$obj->item($i)->getNodePath()}\n"."{$obj->item($i)->ownerDocument->saveXML($obj->item($i))}\n";
541 | }
542 | break;
543 | default:
544 | return "Instance of unknown class";
545 | }
546 | }
547 | else {
548 | return 'no elements...';
549 | }
550 | return htmlspecialchars($retval);
551 | }
552 |
553 | /**
554 | * Source from http://www.binarytides.com/php-get-name-and-value-of-all-input-tags-on-a-page-with-domdocument/
555 | * Generic function to fetch all input tags (name and value) on a page
556 | * Useful when writing automatic login bots/scrapers
557 | */
558 | private function dom_get_input_tags($html)
559 | {
560 | $post_data = array();
561 |
562 | // a new dom object
563 | $dom = new DomDocument;
564 |
565 | //load the html into the object
566 | @$dom->loadHTML($html); //@suppresses warnings
567 | //discard white space
568 | $dom->preserveWhiteSpace = FALSE;
569 |
570 | //all input tags as a list
571 | $input_tags = $dom->getElementsByTagName('input');
572 |
573 | //get all rows from the table
574 | for ($i = 0; $i < $input_tags->length; $i++)
575 | {
576 | if( is_object($input_tags->item($i)) )
577 | {
578 | $name = $value = '';
579 | $name_o = $input_tags->item($i)->attributes->getNamedItem('name');
580 | if(is_object($name_o))
581 | {
582 | $name = $name_o->value;
583 |
584 | $value_o = $input_tags->item($i)->attributes->getNamedItem('value');
585 | if(is_object($value_o))
586 | {
587 | $value = $input_tags->item($i)->attributes->getNamedItem('value')->value;
588 | }
589 |
590 | $post_data[$name] = $value;
591 | }
592 | }
593 | }
594 |
595 | return $post_data;
596 | }
597 |
598 | }
599 |
600 | ?>
601 |
--------------------------------------------------------------------------------