com.techventus.server.voice.Voice Maven / Gradle / Ivy
Show all versions of google-voice-java Show documentation
/*
* Voice.java
*
* Created: Sat Mar 13 14:41:11 2010
*
* Copyright (C) 2010-2012 Techventus, LLC
*
* Techventus, LLC is not responsible for any use or misuse of this product.
* In using this software you agree to hold harmless Techventus, LLC and any other
* contributors to this project from any damages or liabilities which might result
* from its use.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.techventus.server.voice;
import com.techventus.server.voice.datatypes.AllSettings;
import com.techventus.server.voice.datatypes.Greeting;
import com.techventus.server.voice.datatypes.Group;
import com.techventus.server.voice.datatypes.Phone;
import com.techventus.server.voice.datatypes.records.SMSThread;
import com.techventus.server.voice.exception.AuthenticationException;
import com.techventus.server.voice.exception.ERROR_CODE;
import com.techventus.server.voice.util.ParsingUtil;
import com.techventus.server.voice.util.SMSParser;
import gvjava.org.json.JSONException;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* The Class Voice. This class is the basis of the entire API and contains all
* the components necessary to connect and authenticate with Google Voice, place
* calls and SMS, and pull in the raw data from the account.
*
* @author Techventus, LLC
*/
@SuppressWarnings("deprecation")
public class Voice {
/**
* The Constant GOOGLE.
*/
public final static String GOOGLE = "GOOGLE";
/**
* The Constant HOSTED.
*/
public final static String HOSTED = "HOSTED";
/**
* The Constant HOSTED_OR_GOOGLE.
*/
public final static String HOSTED_OR_GOOGLE = "HOSTED_OR_GOOGLE";
/**
* The Constant enc.
*/
final static String enc = "UTF-8";
/**
* The Constant USER_AGENT.
*/
final static String USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.A.B.C Safari/525.13";
/**
* Name of the Google service you're requesting authorization for. Each service using the Authorization
* service is assigned a name value; for example, the name associated with Google Calendar is 'cl'.
* This parameter is required when accessing services based on Google Data APIs. For specific service
* names, refer to the service documentation.
*/
final static String SERVICE = "grandcentral";
/**
* The Constant generalURLString.
*/
final static String generalURLString = "https://www.google.com/voice/b/0";
/**
* The Constant loginURLString.
*/
final static String loginURLString = "https://www.google.com/accounts/ClientLogin";
/**
* The Constant inboxURLString.
*/
final static String inboxURLString = "https://www.google.com/voice/b/0/inbox/recent/inbox/";
/**
* The Constant starredURLString.
*/
final static String starredURLString = "https://www.google.com/voice/b/0/inbox/recent/starred/";
/**
* The Constant recentAllURLString.
*/
final static String recentAllURLString = "https://www.google.com/voice/b/0/inbox/recent/all/";
/**
* The Constant spamURLString.
*/
final static String spamURLString = "https://www.google.com/voice/b/0/inbox/recent/spam/";
/**
* The Constant trashURLString.
*/
final static String trashURLString = "https://www.google.com/voice/b/0/inbox/recent/spam/";
/**
* The Constant voicemailURLString.
*/
final static String voicemailURLString = "https://www.google.com/voice/b/0/inbox/recent/voicemail/";
/**
* The Constant smsURLString.
*/
final static String smsURLString = "https://www.google.com/voice/b/0/inbox/recent/sms/";
/**
* The Constant recordedURLString.
*/
final static String recordedURLString = "https://www.google.com/voice/b/0/inbox/recent/recorded/";
/**
* The Constant placedURLString.
*/
final static String placedURLString = "https://www.google.com/voice/b/0/inbox/recent/placed/";
/**
* The Constant receivedURLString.
*/
final static String receivedURLString = "https://www.google.com/voice/b/0/inbox/recent/received/";
/**
* The Constant missedURLString.
*/
final static String missedURLString = "https://www.google.com/voice/b/0/inbox/recent/missed/";
/**
* The Constant phoneEnableURLString.
*/
final static String phoneEnableURLString = "https://www.google.com/voice/b/0/settings/editDefaultForwarding/";
/**
* The Constant generalSettingsURLString.
*/
final static String generalSettingsURLString = "https://www.google.com/voice/b/0/settings/editGeneralSettings/";
/**
* The Constant editForwardingSMSURLString.
*/
final static String editForwardingSMSURLString = "https://www.google.com/voice/b/0/settings/editForwardingSms/";
/**
* The Constant phonesInfoURLString.
*/
final static String phonesInfoURLString = "https://www.google.com/voice/b/0/settings/tab/phones";
/**
* The Constant groupsInfoURLString.
*/
final static String groupsInfoURLString = "https://www.google.com/voice/b/0/settings/tab/groups";
/**
* The Constant voicemailInfoURLString.
*/
final static String voicemailInfoURLString = "https://www.google.com/voice/b/0/settings/tab/voicemailsettings";
/**
* The Constant groupsSettingsURLString.
*/
final static String groupsSettingsURLString = "https://www.google.com/voice/b/0/settings/editGroup/";
/**
* The Constant voicemailDownloadURLString.
*/
final static String voicemailDownloadURLString = "https://www.google.com/voice/media/send_voicemail/";
/**
* The Constant markAsReadString.
*/
final static String markAsReadString = "https://www.google.com/voice/b/0/inbox/mark/";
/**
* The Constant unreadSMSString.
*/
final static String unreadSMSString = "https://www.google.com/voice/b/0/inbox/recent/sms/unread/";
/**
* Maximum amount of redirects before we throw an exception.
*/
private static int MAX_REDIRECTS = 5;
/**
* The PRINT to Console FLAG setting.
*/
public boolean PRINT_TO_CONSOLE;
/**
* The general.
*/
String general = null;
/**
* The phones info.
*/
String phonesInfo = null;
/**
* The rnr see.
*/
String rnrSEE = null;
/**
* Short string identifying your application, for logging purposes. This string should take the form:
* "companyName-applicationName-versionID". See: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request
*/
String source = null;
/**
* keeps the list of phones - lazy.
*/
private AllSettings settings;
/**
* The error.
*/
private ERROR_CODE error;
/**
* User's full email address. It must include the domain (i.e. [email protected]).
*/
private String user = null;
/**
* User's password.
*/
private String pass = null;
/**
* Google Voice Phone Number.
*/
private String phoneNumber = null;
/**
* Once the login information has been successfully authenticated, Google returns a token, which your
* application will reference each time it requests access to the user's account.
* This token must be included in all subsequent requests to the Google service for this account.
* Authorization tokens should be closely guarded and should not be given to any other application,
* as they represent access to the user's account. The time limit on the token varies depending on
* which service issued it.
*/
private String authToken = null;
/**
* (optional) Token representing the specific CAPTCHA challenge. Google supplies this token and the
* CAPTCHA image URL in a login failed response with the error code "CaptchaRequired".
*/
private String captchaToken = null;
/**
* Url of the image with the captcha - only filled after a captacha response to a login try.
*/
private String captchaUrl = null;
/**
* The captcha url2.
*/
private String captchaUrl2 = null;
/**
* Counts the amount of redirects we are doing in the get(String url) method to avoid infinite loop.
*/
private int redirectCounter = 0;
/**
* Type of account to request authorization for. Possible values are:
* -GOOGLE (get authorization for a Google account only)
* -HOSTED (get authorization for a hosted account only)
* -HOSTED_OR_GOOGLE (get authorization first for a hosted account; if attempt fails, get
* authorization for a Google account)
* Use HOSTED_OR_GOOGLE if you're not sure which type of account you want authorization for.
* If the user information matches both a hosted and a Google account, only the hosted account is authorized.
*/
private String account_type = GOOGLE;
//Experimental keyFlag is just there to overload method
public Voice(String authToken) throws IOException {
this.authToken = authToken;
this.pass = "UNKNOWN";
this.user = "UNKNOWN";
this.source = "GoogleVoiceJava";
this.general = getGeneral();
this.setRNRSEE();
String response = this.getRawPhonesInfo();
int phoneIndex = response.indexOf("gc-user-number-value\">");
this.phoneNumber = response.substring(phoneIndex + 22, phoneIndex + 36);
this.phoneNumber = this.phoneNumber.replaceAll("[^a-zA-Z0-9]", "");
if (this.phoneNumber.indexOf("+") == -1) {
this.phoneNumber = "+1" + this.phoneNumber;
}
}
/**
* Instantiates a new voice. This constructor is deprecated. Try
* Voice(String user, String pass) which automatically determines rnrSee and
* assigns a source.
*
* @param user the user
* @param pass the pass
* @param source the source
* @param rnrSee the rnr see
* @throws IOException Signals that an I/O exception has occurred.
*/
@Deprecated
public Voice(String user, String pass, String source, String rnrSee)
throws IOException {
this.user = user;
this.pass = pass;
this.rnrSEE = rnrSee;
this.source = source;
login();
}
/**
* A constructor which which allows a custom source.
* This Constructor enables verbose output.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the password
* @param source Short string identifying your application, for logging purposes. This string should take the form:
* "companyName-applicationName-versionID". See: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request
* @throws IOException Signals that an I/O exception has occurred.
*/
public Voice(String user, String pass, String source) throws IOException {
init(user, pass, source, true, GOOGLE, null, null);
}
/**
* Instantiates a new Voice Object. This is generally the simplest and
* preferred constructor. This Constructor enables verbose output.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the pass
* @throws IOException Signals that an I/O exception has occurred.
*/
public Voice(String user, String pass) throws IOException {
init(user, pass, null, true, GOOGLE, null, null);
}
/**
* Instantiates a new voice. Custom Source Variable allowed, and
* printDebugIntoSystemOut which allows for Verbose output.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the password
* @param source the arbitrary source identifier. Can be anything.
* @param printDebugIntoToSystemOut the print debug into to system out
* @throws IOException Signals that an I/O exception has occurred.
*/
public Voice(String user, String pass, String source,
boolean printDebugIntoToSystemOut) throws IOException {
init(user, pass, source, printDebugIntoToSystemOut, GOOGLE, null, null);
}
/**
* Instantiates a new voice. Custom Source Variable allowed, and
* printDebugIntoSystemOut which allows for Verbose output.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the password
* @param source the arbitrary source identifier. Can be anything.
* @param printDebugIntoToSystemOut the print debug into to system out
* @param accountType Type of account to request authorization for. Possible values are:
* Voice.GOOGLE (get authorization for a Google account only)
* Voice.HOSTED (get authorization for a hosted account only)
* Voice.HOSTED_OR_GOOGLE (get authorization first for a hosted account; if attempt fails, get authorization for a Google account)
* Use Voice.HOSTED_OR_GOOGLE if you're not sure which type of account you want authorization for. If the user information matches both a hosted and a Google account, only the hosted account is authorized.
* @throws IOException Signals that an I/O exception has occurred.
*/
public Voice(String user, String pass, String source,
boolean printDebugIntoToSystemOut, String accountType) throws IOException {
init(user, pass, source, printDebugIntoToSystemOut, accountType, null, null);
}
/**
* Instantiates a new voice. Custom Source Variable allowed, and
* printDebugIntoSystemOut which allows for Verbose output.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the password
* @param source the arbitrary source identifier. Can be anything.
* @param printDebugIntoToSystemOut the print debug into to system out
* @param accountType Type of account to request authorization for. Possible values are:
* Voice.GOOGLE (get authorization for a Google account only)
* Voice.HOSTED (get authorization for a hosted account only)
* Voice.HOSTED_OR_GOOGLE (get authorization first for a hosted account; if attempt fails, get authorization for a Google account)
* Use Voice.HOSTED_OR_GOOGLE if you're not sure which type of account you want authorization for. If the user information matches both a hosted and a Google account, only the hosted account is authorized.
* @param captchaResponse response to a captcha challenge, set to null if normal login
* @param captchaToken (optional) token which matches the response/url from the captcha challenge
* @throws IOException Signals that an I/O exception has occurred.
*/
public Voice(String user, String pass, String source,
boolean printDebugIntoToSystemOut, String accountType, String captchaResponse, String captchaToken) throws IOException {
init(user, pass, source, printDebugIntoToSystemOut, accountType, captchaResponse, captchaToken);
}
/**
* Place a call.
*
* @param originNumber the origin number
* @param destinationNumber the destination number
* @param phoneType the phone type, this is a number such as 1,2,7 formatted as a String
* @return the raw response string received from Google Voice.
* @throws IOException Signals that an I/O exception has occurred.
*/
public String call(String originNumber, String destinationNumber,
String phoneType) throws IOException {
String out = "";
StringBuffer calldata = new StringBuffer();
// POST /voice/call/connect/
// outgoingNumber=[number to call]
// &forwardingNumber=[forwarding number]
// &subscriberNumber=undefined
// &phoneType=[phone type from google]
// &remember=0
// &_rnr_se=[pull from page]
calldata.append("outgoingNumber=");
calldata.append(URLEncoder.encode(destinationNumber, enc));
calldata.append("&forwardingNumber=");
calldata.append(URLEncoder.encode(originNumber, enc));
calldata.append("&subscriberNumber=undefined");
calldata.append("&phoneType=");
calldata.append(URLEncoder.encode(phoneType, enc));
calldata.append("&remember=0");
calldata.append("&_rnr_se=");
calldata.append(URLEncoder.encode(rnrSEE, enc));
URL callURL = new URL("https://www.google.com/voice/b/0/call/connect/");
URLConnection callconn = callURL.openConnection();
callconn.setRequestProperty("Authorization", "GoogleLogin auth=" + authToken);
callconn.setRequestProperty("User-agent", USER_AGENT);
callconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(callconn
.getOutputStream());
callwr.write(calldata.toString());
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
callconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Cancel a call that was just placed.
*
* @param originNumber the origin number
* @param destinationNumber the destination number
* @param phoneType the phone type
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String cancelCall(String originNumber, String destinationNumber,
String phoneType) throws IOException {
String out = "";
String calldata = "";
calldata += URLEncoder.encode("outgoingNumber", enc) + "="
+ URLEncoder.encode("undefined", enc);
calldata += "&" + URLEncoder.encode("forwardingNumber", enc) + "="
+ URLEncoder.encode("undefined", enc);
calldata += "&" + URLEncoder.encode("cancelType", enc) + "="
+ URLEncoder.encode("C2C", enc);
calldata += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
// POST /voice/call/connect/ outgoingNumber=[number to
// call]&forwardingNumber=[forwarding
// number]&subscriberNumber=undefined&remember=0&_rnr_se=[pull from
// page]
URL callURL = new URL("https://www.google.com/voice/b/0/call/cancel/");
URLConnection callconn = callURL.openConnection();
callconn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
callconn
.setRequestProperty(
"User-agent",
USER_AGENT);
callconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(callconn
.getOutputStream());
callwr.write(calldata);
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
callconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Delete message.
*
* @param msgID the msg id
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String deleteMessage(String msgID) throws IOException {
String out = "";
StringBuffer calldata = new StringBuffer();
// POST /voice/inbox/deleteMessages/
// messages=[messageID]
// &trash=1
// &_rnr_se=[pull from page]
calldata.append("messages=");
calldata.append(URLEncoder.encode(msgID, enc));
calldata.append("&trash=1");
calldata.append("&_rnr_se=");
calldata.append(URLEncoder.encode(rnrSEE, enc));
URL callURL = new URL("https://www.google.com/voice/b/0/inbox/deleteMessages/");
URLConnection callconn = callURL.openConnection();
callconn.setRequestProperty("Authorization", "GoogleLogin auth=" + authToken);
callconn.setRequestProperty("User-agent", USER_AGENT);
callconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(callconn
.getOutputStream());
callwr.write(calldata.toString());
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
callconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Downloads a voicemail.
*
* @param msgID the msg id
* @return byte output stream
* @throws IOException Signals that an I/O exception has occurred.
*/
public ByteArrayOutputStream downloadVoicemail(String msgID) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
URL u = new URL(voicemailDownloadURLString + msgID);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
huc.setRequestProperty("Authorization", "GoogleLogin auth=" + authToken);
huc.setRequestProperty("User-agent", USER_AGENT);
huc.setRequestMethod("GET");
huc.connect();
InputStream is = huc.getInputStream();
if (huc.getResponseCode() == HttpURLConnection.HTTP_OK) {
byte[] buffer = new byte[4096];
int bytes = 0;
while (true) {
bytes = is.read(buffer);
if (bytes <= 0) {
break;
}
outputStream.write(buffer, 0, bytes);
}
outputStream.flush();
}
huc.disconnect();
return outputStream;
} catch (IOException e) {
System.out.println("Exception\n" + e);
}
return null;
}
/**
* HTTP GET request for a given URL String and a given page number.
*
* @param urlString the url string
* @param page number must be a natural number
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String get(String urlString, int page) throws IOException {
URL url = new URL(urlString + "?page=p" + page);
//url+="&page="+page;
URLConnection conn = url.openConnection();
conn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
conn
.setRequestProperty(
"User-agent",
USER_AGENT);
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn
.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line + "\n\r");
}
rd.close();
String result = sb.toString();
return result;
}
// public Voice(){
// authToken = "abcde";
// }
/**
* Gets the captcha token.
*
* @return the captcha token
*/
public String getCaptchaToken() {
return captchaToken;
}
/**
* Gets the captcha url.
*
* @return the captcha url
*/
public String getCaptchaUrl() {
return captchaUrl;
}
/**
* Gets the error.
*
* @return the error
*/
@Deprecated
public ERROR_CODE getError() {
return error;
}
/**
* Fetches the page Source Code for the Voice homepage. This file contains
* most of the useful information for the Google Voice Account such as
* attached PhoneOld info and Contacts.
*
* @return the general
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getGeneral() throws IOException {
return get(generalURLString);
}
/**
* The main Google Voice section is paginated. Access the raw HTML for
* specific page of the main section.
*
* @param page the page
* @return the general page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getGeneralPage(int page) throws IOException {
return get(generalURLString, page);
}
/**
* Returns the Group list - Lazy. Not yet Implemented
*
* @param forceUpdate the force update
* @return List of Greeting objects
* @throws IOException Signals that an I/O exception has occurred.
*/
public List getGroupSettingsList(boolean forceUpdate) throws IOException {
// return getSettings(forceUpdate).getGroupSettingsList();
// List lGList = new ArrayList();
// String[] lGArray = getSettings(forceUpdate).getSettings().getGroups().;
// for (int i = 0; i < lGArray.length; i++) {
// lGList.add(lGArray[i]);
// }
// return lGList;
//TODO implement getGroupSettingsList
return null;
}
/**
* Fetches and returns the raw page source code for the Inbox.
*
* @return the inbox
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getInbox() throws IOException {
return get(inboxURLString);
}
/**
* Gets the inbox page.
*
* @param page the page
* @return the inbox page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getInboxPage(int page) throws IOException {
return get(inboxURLString, page);
}
/**
* Gets the missed calls source code.
*
* @return the missed
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getMissed() throws IOException {
return get(missedURLString);
}
/**
* Gets the missed page.
*
* @param page the page
* @return the missed page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getMissedPage(int page) throws IOException {
return get(missedURLString, page);
}
/**
* Gets the phone number.
*
* @return the phone number
*/
public String getPhoneNumber() {
return this.phoneNumber;
}
/**
* Gets the raw source code for the placed calls page.
*
* @return the placed calls source code
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getPlaced() throws IOException {
return get(placedURLString);
}
/**
* Gets the placed page.
*
* @param page the page
* @return the placed page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getPlacedPage(int page) throws IOException {
return get(placedURLString, page);
}
/**
* Gets the rNRSEE.
*
* @return the rNRSEE
*/
public String getRNRSEE() {
return rnrSEE;
}
/**
* Gets the raw phones info.
*
* @return the raw phones info
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getRawPhonesInfo() throws IOException {
return get(phonesInfoURLString);
}
/**
* Gets the received calls source code.
*
* @return the received
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getReceived() throws IOException {
return get(receivedURLString);
}
/**
* Gets the received page.
*
* @param page the page
* @return the received page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getReceivedPage(int page) throws IOException {
return get(receivedURLString, page);
}
/**
* Gets the raw page source code for the recent items.
*
* @return the recent raw source code
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getRecent() throws IOException {
return get(recentAllURLString);
}
/**
* Gets the recent page.
*
* @param page the page
* @return the recent page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getRecentPage(int page) throws IOException {
return get(recentAllURLString, page);
}
/**
* Gets the page source for the recorded calls.
*
* @return the recorded
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getRecorded() throws IOException {
return get(recordedURLString);
}
/**
* Gets the recorded page.
*
* @param page the page
* @return the recorded page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getRecordedPage(int page) throws IOException {
return get(recordedURLString, page);
}
/**
* Gets the SMS page raw source code.
*
* @return the sMS
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getSMS() throws IOException {
return get(smsURLString);
}
/**
* Gets the SMS page.
*
* @param page the page
* @return the sMS page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getSMSPage(int page) throws IOException {
return get(smsURLString, page);
}
/**
* Gets a collection of SMS threads. Each SMS thread has a collection of SMS
* objects which contains contact, text and timestamp information.
*
* @return a collection of SMS threads.
* @throws IOException Signals that an I/O exception has occurred.
*/
public Collection getSMSThreads() throws IOException {
SMSParser parser = new SMSParser(get(smsURLString), phoneNumber);
return parser.getSMSThreads();
}
/**
* Gets a collection of SMS threads. Each SMS thread has a collection of SMS
* objects which contains contact, text and timestamp information.
*
* @param page Page number
* @return a collection of SMS threads.
* @throws IOException Signals that an I/O exception has occurred.
*/
public Collection getSMSThreads(int page) throws IOException {
SMSParser parser = new SMSParser(get(smsURLString, page), phoneNumber);
return parser.getSMSThreads();
}
/**
* Gets the SMS threads from a given Response Page.
*
* @param response the response
* @return the SMS threads
*/
public Collection getSMSThreads(String response) {
SMSParser parser = new SMSParser(response, phoneNumber);
return parser.getSMSThreads();
}
/**
* returns all users settings - lazy.
*
* @param forceUpdate the force update
* @return the settings
* @throws JSONException the jSON exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public AllSettings getSettings(boolean forceUpdate) throws JSONException, IOException {
if (settings == null || forceUpdate) {
if (isLoggedIn() == false || forceUpdate) {
login();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (PRINT_TO_CONSOLE) {
System.out.println("Fetching Settings.");
}
// remove html overhead
String lJson = ParsingUtil.removeUninterestingParts(get(groupsInfoURLString), " ", false);
try {
settings = new AllSettings(lJson);
} catch (JSONException e) {
throw new JSONException(e.getMessage() + lJson);
}
}
return settings;
}
/**
* Gets the page source for the spam.
*
* @return the spam
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getSpam() throws IOException {
return get(spamURLString);
}
/**
* Gets the spam page.
*
* @param page the page
* @return the spam page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getSpamPage(int page) throws IOException {
return get(spamURLString, page);
}
/**
* Gets the raw page source code for the starred items.
*
* @return the starred item page source
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getStarred() throws IOException {
return get(starredURLString);
}
/**
* Gets the starred page.
*
* @param page the page
* @return the starred page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getStarredPage(int page) throws IOException {
return get(starredURLString, page);
}
//TODO Combine with or replace setPhoneInfo
/**
* Gets the unread sms.
*
* @return the unread sms
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getUnreadSMS() throws IOException {
return get(unreadSMSString);
}
/**
* Gets the unread sms page.
*
* @param page the page
* @return the unread sms page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getUnreadSMSPage(int page) throws IOException {
return get(unreadSMSString, page);
}
/**
* Returns the username
*
* @return username for gvoice account
*/
public String getUsername() {
return this.user;
}
/**
* Gets the Voicemail page raw source code.
*
* @return the Voicemail
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getVoicemail() throws IOException {
return get(voicemailURLString);
}
/**
* Returns the Greeting list - Lazy
*
* @param forceUpdate set to true to force a List update from the server
* @return List of Greeting objects
* @throws IOException Signals that an I/O exception has occurred.
* @throws JSONException the jSON exception
*/
public List getVoicemailList(boolean forceUpdate) throws IOException, JSONException {
List lGList = new ArrayList();
Greeting[] lGArray = getSettings(forceUpdate).getSettings().getGreetings();
for (int i = 0; i < lGArray.length; i++) {
lGList.add(lGArray[i]);
}
return lGList;
}
/**
* Gets the voicemail page.
*
* @param page the page
* @return the voicemail page
* @throws IOException Signals that an I/O exception has occurred.
*/
public String getVoicemailPage(int page) throws IOException {
return get(voicemailURLString, page);
}
/**
* Fires a Get request for Recent Items. If the Response requests login
* authentication or if an exception is thrown, a false is returned,
* otherwise if arbitrary text is contained for a logged in account, a true
* is returned.
*
* TODO Examine methodology. Perhaps Could Establish greater persistence with
* an option to force an update. Currently this is an expensive
* and slow method.
*
* @return true, if is logged in
*/
public boolean isLoggedIn() {
String res;
try {
res = getRecent();
} catch (IOException e) {
return false;
}
if (res
.contains("");
this.phoneNumber = response.substring(phoneIndex + 22, phoneIndex + 36);
this.phoneNumber = this.phoneNumber.replaceAll("[^a-zA-Z0-9]", "");
if (this.phoneNumber.indexOf("+") == -1) {
this.phoneNumber = "+1" + this.phoneNumber;
}
}
/**
* Mark a Conversation with a known Message ID as read.
*
* @param msgID the msg id
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String markAsRead(String msgID) throws IOException {
String out = "";
StringBuffer calldata = new StringBuffer();
// POST /voice/inbox/mark/
// messages=[messageID]
// &read=1
// &_rnr_se=[pull from page]
calldata.append("messages=");
calldata.append(URLEncoder.encode(msgID, enc));
calldata.append("&read=1");
calldata.append("&_rnr_se=");
calldata.append(URLEncoder.encode(rnrSEE, enc));
URL callURL = new URL(markAsReadString);
URLConnection callconn = callURL.openConnection();
callconn.setRequestProperty("Authorization", "GoogleLogin auth=" + authToken);
callconn.setRequestProperty("User-agent", USER_AGENT);
callconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(callconn
.getOutputStream());
callwr.write(calldata.toString());
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
callconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Mark a Conversation with a known Message ID as unread.
*
* @param msgID the msg id
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String markUnRead(String msgID) throws IOException {
String out = "";
StringBuffer calldata = new StringBuffer();
// POST /voice/inbox/mark/
// messages=[messageID]
// &read=0
// &_rnr_se=[pull from page]
calldata.append("messages=");
calldata.append(URLEncoder.encode(msgID, enc));
calldata.append("&read=0");
calldata.append("&_rnr_se=");
calldata.append(URLEncoder.encode(rnrSEE, enc));
URL callURL = new URL("https://www.google.com/voice/b/0/inbox/mark");
URLConnection callconn = callURL.openConnection();
callconn.setRequestProperty("Authorization", "GoogleLogin auth=" + authToken);
callconn.setRequestProperty("User-agent", USER_AGENT);
callconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(callconn
.getOutputStream());
callwr.write(calldata.toString());
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
callconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Disable one of the the phones attached to the account from ringing.
* Requires the internal ID for that phone, as an integer, usually 1,2,3,
* etc.
*
* @param ID the iD
* @return the raw response of the disable action.
* @throws IOException Signals that an I/O exception has occurred.
*/
public String phoneDisable(int ID) throws IOException {
String paraString = URLEncoder.encode("enabled", enc) + "="
+ URLEncoder.encode("0", enc);
paraString += "&" + URLEncoder.encode("phoneId", enc) + "="
+ URLEncoder.encode(Integer.toString(ID), enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
return phonesEnableDisableApply(paraString);
}
/**
* Enables one of the the phones attached to the account from ringing.
* Requires the internal ID for that phone, as an integer, usually 1,2,3,
* etc.
*
* @param ID the iD
* @return the raw response of the enable action.
* @throws IOException Signals that an I/O exception has occurred.
*/
public String phoneEnable(int ID) throws IOException {
String paraString = URLEncoder.encode("enabled", enc) + "="
+ URLEncoder.encode("1", enc);
paraString += "&" + URLEncoder.encode("phoneId", enc) + "="
+ URLEncoder.encode(Integer.toString(ID), enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
return phonesEnableDisableApply(paraString);
}
/**
* Disables multiple phones in one post
*
* TODO Test this with multiple phones in an account
* Make faster - spawn threads
* Best would be to be able to construct a url which can switch multiple phones at a time.
*
* @param IDs Array of Phones to disable
* @throws IOException Signals that an I/O exception has occurred.
*/
public void phonesDisable(int[] IDs) throws IOException {
if (IDs.length < 1) {
return;
} else if (IDs.length == 1) {
//launch single (no thread overhead)
phoneDisable(IDs[0]);
} else {
for (int i = 0; i < IDs.length; i++) {
//TODO spawn threads!
int j = IDs[i];
String paraString = URLEncoder.encode("enabled", enc) + "="
+ URLEncoder.encode("0", enc);
paraString += "&" + URLEncoder.encode("phoneId", enc) + "="
+ URLEncoder.encode(Integer.toString(j), enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
phonesEnableDisableApply(paraString);
}
}
}
/**
* Enables multiple phones in one post
*
* TODO Test this with multiple phones in an account
* Best would be to be able to construct a url which can switch multiple phones at a time.
*
* @param IDs Array of Phones to enable
* @throws IOException Signals that an I/O exception has occurred.
*/
public void phonesEnable(int[] IDs) throws IOException {
if (IDs.length < 1) {
return;
} else if (IDs.length == 1) {
//launch single (no thread overhead)
phoneEnable(IDs[0]);
} else {
for (int i = 0; i < IDs.length; i++) {
//TODO spawn threads!
int j = IDs[i];
String paraString = URLEncoder.encode("enabled", enc) + "="
+ URLEncoder.encode("1", enc);
paraString += "&" + URLEncoder.encode("phoneId", enc) + "="
+ URLEncoder.encode(Integer.toString(j), enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
phonesEnableDisableApply(paraString);
}
}
}
/**
* Send an SMS.
*
* @param destinationNumber the destination number
* @param txt the Text of the message. Messages longer than the allowed
* character length will be split into multiple messages.
* @param id the Text of the message. Messages longer than the allowed
* character length will be split into multiple messages.
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String sendSMS(String destinationNumber, String txt, String id)
throws IOException {
String out = "";
String smsdata = "";
smsdata += URLEncoder.encode("id", enc) + "="
+ URLEncoder.encode(id, enc);
smsdata += "&" + URLEncoder.encode("phoneNumber", enc) + "="
+ URLEncoder.encode(destinationNumber, enc);
smsdata += "&" + URLEncoder.encode("conversationId", enc) + "="
+ URLEncoder.encode(id, enc);
smsdata += "&" + URLEncoder.encode("text", enc) + "="
+ URLEncoder.encode(txt, enc);
smsdata += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
System.out.println("smsdata: " + smsdata);
URL smsurl = new URL("https://www.google.com/voice/b/0/sms/send/");
URLConnection smsconn = smsurl.openConnection();
smsconn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
smsconn
.setRequestProperty(
"User-agent",
USER_AGENT);
smsconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(smsconn.getOutputStream());
callwr.write(smsdata);
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
smsconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Send an SMS.
*
* @param destinationNumber the destination number
* @param txt the Text of the message. Messages longer than the allowed
* character length will be split into multiple messages.
* @param thread SMS thread to attach current message to
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String sendSMS(String destinationNumber, String txt, SMSThread thread)
throws IOException {
String id = thread.getId();
return sendSMS(destinationNumber, txt, id);
}
/**
* Send an SMS.
*
* @param destinationNumber the destination number
* @param txt the Text of the message. Messages longer than the allowed
* character length will be split into multiple messages.
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String sendSMS(String destinationNumber, String txt)
throws IOException {
String out = "";
String smsdata = "";
smsdata += URLEncoder.encode("phoneNumber", enc) + "="
+ URLEncoder.encode(destinationNumber, enc);
smsdata += "&" + URLEncoder.encode("text", enc) + "="
+ URLEncoder.encode(txt, enc);
smsdata += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
URL smsurl = new URL("https://www.google.com/voice/b/0/sms/send/");
URLConnection smsconn = smsurl.openConnection();
smsconn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
smsconn
.setRequestProperty(
"User-agent",
USER_AGENT);
smsconn.setDoOutput(true);
OutputStreamWriter callwr = new OutputStreamWriter(smsconn.getOutputStream());
callwr.write(smsdata);
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
smsconn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Enables/disables the call Announcement setting (general for all phones).
*
* @param announceCaller true Announces caller's name and gives answering options
* false Directly connects calls when phones are answered
* @return the raw response of the disable action.
* @throws IOException Signals that an I/O exception has occurred.
*/
public String setCallPresentation(boolean announceCaller) throws IOException {
String out = "";
URL requestURL = new URL(generalSettingsURLString);
/** 0 for enable, 1 for disable **/
String announceCallerStr = "";
if (announceCaller) {
announceCallerStr = "0";
if (PRINT_TO_CONSOLE) {
System.out.println("Turning caller announcement on.");
}
} else {
announceCallerStr = "1";
if (PRINT_TO_CONSOLE) {
System.out.println("Turning caller announcement off.");
}
}
String paraString = "";
paraString += URLEncoder.encode("directConnect", enc) + "="
+ URLEncoder.encode(announceCallerStr, enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
URLConnection conn = requestURL.openConnection();
conn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
conn.setRequestProperty("User-agent",
USER_AGENT);
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStreamWriter callwr = new OutputStreamWriter(conn.getOutputStream());
callwr.write(paraString);
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Activated or deactivated the Do Not disturb function.
* Enable this to send to voicemail all calls made to your Google number.
*
* @param dndEnabled true to enable dnd, false to disable it
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String setDoNotDisturb(boolean dndEnabled) throws IOException {
URL requestURL = new URL(generalSettingsURLString);
String enabled;
if (dndEnabled) {
if (PRINT_TO_CONSOLE) {
System.out.println("Enabling dnd");
}
enabled = "1";
} else {
if (PRINT_TO_CONSOLE) {
System.out.println("Disabling dnd");
}
enabled = "0";
}
String paraString = "";
// URLEncoder.encode("auth", enc) + "="+ URLEncoder.encode(authToken, enc);
paraString += URLEncoder.encode("doNotDisturb", enc) + "="
+ URLEncoder.encode(enabled + "", enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
return postSettings(requestURL, paraString);
}
/**
* Applies the settings for this group.
*
* @param group the group
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String setNewGroupSettings(Group group) throws IOException {
URL requestURL = new URL(groupsSettingsURLString);
String paraString = "";
// URLEncoder.encode("auth", enc) + "="+ URLEncoder.encode(authToken, enc);;
// 1=true 0=false
int isCustomGreeting = 0;
if (group.isCustomGreeting()) {
isCustomGreeting = 1;
}
paraString += URLEncoder.encode("isCustomGreeting", enc) + "="
+ URLEncoder.encode(isCustomGreeting + "", enc);
int greetingId = group.getGreetingId();
paraString += "&" + URLEncoder.encode("greetingId", enc) + "="
+ URLEncoder.encode(greetingId + "", enc);
for (int i = 0; i < group.getDisabledForwardingIds().size(); i++) {
paraString += "&" + URLEncoder.encode("disabledPhoneIds", enc) + "="
+ URLEncoder.encode(group.getDisabledForwardingIds().get(i).getId(), enc);
}
int directConnect = 0;
if (group.isDirectConnect()) {
directConnect = 1;
}
paraString += "&" + URLEncoder.encode("directConnect", enc) + "="
+ URLEncoder.encode(directConnect + "", enc);
int isCustomDirectConnect = 0;
if (group.isCustomDirectConnect()) {
isCustomDirectConnect = 1;
}
paraString += "&" + URLEncoder.encode("isCustomDirectConnect", enc) + "="
+ URLEncoder.encode(isCustomDirectConnect + "", enc);
int isCustomForwarding = 0;
if (group.isCustomForwarding()) {
isCustomForwarding = 1;
}
paraString += "&" + URLEncoder.encode("isCustomForwarding", enc) + "="
+ URLEncoder.encode(isCustomForwarding + "", enc);
paraString += "&" + URLEncoder.encode("id", enc) + "="
+ URLEncoder.encode(group.getId(), enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
return postSettings(requestURL, paraString);
}
/**
* Activated or deactivated the SMS Forwarding for a particular phone
*
* @param smsEnable true to enable sms forwarding, false to disable it
* @param ID The id of the phone to enable/disable
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
public String setSmsEnabled(boolean smsEnable, int ID) throws IOException {
// only allow editing of type 2 phones
for (int i = 0; i < settings.getPhones().length; i++) {
Phone ph = settings.getPhones()[i];
if (ph.getId() == ID) {
if (ph.getType() != 2) {
if (PRINT_TO_CONSOLE) {
System.out.println("Cannot change sms Enabled on phone of type " + ph.getType() + " only availible on type 2");
}
return null;
}
}
}
String enabled;
if (smsEnable & !settings.isPhoneSmsEnabled(ID)) {
if (PRINT_TO_CONSOLE) {
System.out.println("Enabling sms for phone " + ID);
}
enabled = "1";
} else if (settings.isPhoneSmsEnabled(ID)) {
if (PRINT_TO_CONSOLE) {
System.out.println("Disabling sms for phone " + ID);
}
enabled = "0";
} else {
// do not make changes to phones that are already in the same state
if (PRINT_TO_CONSOLE) {
System.out.println("Phone " + ID + " is already in the requested state. " + smsEnable);
}
return null;
}
URL requestURL = new URL(editForwardingSMSURLString);
String paraString = "";
paraString += URLEncoder.encode("enabled", enc) + "="
+ URLEncoder.encode(enabled + "", enc);
paraString += "&" + URLEncoder.encode("phoneId", enc) + "="
+ URLEncoder.encode(ID + "", enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
if (PRINT_TO_CONSOLE) {
System.out.println(requestURL);
}
if (PRINT_TO_CONSOLE) {
System.out.println(paraString);
}
return postSettings(requestURL, paraString);
}
/**
* This is the general voicemail greeting callers hear.
*
* @param greetingToSet new greeint to use
* number of the greeting to choose
* @return the raw response of the disable action.
* @throws IOException Signals that an I/O exception has occurred.
*/
public String setVoicemailGreetingId(String greetingToSet) throws IOException {
URL requestURL = new URL(generalSettingsURLString);
if (PRINT_TO_CONSOLE) {
System.out.println("Activating Greeting#" + greetingToSet);
}
String paraString = "";
// URLEncoder.encode("auth", enc) + "="+ URLEncoder.encode(authToken, enc);
paraString += URLEncoder.encode("greetingId", enc) + "="
+ URLEncoder.encode(greetingToSet + "", enc);
paraString += "&" + URLEncoder.encode("_rnr_se", enc) + "="
+ URLEncoder.encode(rnrSEE, enc);
return postSettings(requestURL, paraString);
}
/**
* HTTP GET request for a given URL String.
*
* @param urlString the url string
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
String get(String urlString) throws IOException {
URL url = new URL(urlString);
//+ "?auth=" + URLEncoder.encode(authToken, enc));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
conn.setRequestProperty(
"User-agent",
USER_AGENT);
conn.setInstanceFollowRedirects(false); // will follow redirects of same protocol http to http, but does not follow from http to https for example if set to true
// Get the response
conn.connect();
int responseCode = conn.getResponseCode();
if (PRINT_TO_CONSOLE) {
System.out.println(urlString + " - " + conn.getResponseMessage());
}
InputStream is;
if (responseCode == 200) {
is = conn.getInputStream();
} else if (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_SEE_OTHER || responseCode == 307) {
redirectCounter++;
if (redirectCounter > MAX_REDIRECTS) {
redirectCounter = 0;
throw new IOException(urlString + " : " + conn.getResponseMessage() + "(" + responseCode + ") : Too manny redirects. exiting.");
}
String location = conn.getHeaderField("Location");
if (location != null && !location.equals("")) {
System.out.println(urlString + " - " + responseCode + " - new URL: " + location);
return get(location);
} else {
throw new IOException(urlString + " : " + conn.getResponseMessage() + "(" + responseCode + ") : Received moved answer but no Location. exiting.");
}
} else {
is = conn.getErrorStream();
}
redirectCounter = 0;
if (is == null) {
throw new IOException(urlString + " : " + conn.getResponseMessage() + "(" + responseCode + ") : InputStream was null : exiting.");
}
String result = "";
try {
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line + "\n\r");
}
rd.close();
result = sb.toString();
} catch (Exception e) {
throw new IOException(urlString + " - " + conn.getResponseMessage() + "(" + responseCode + ") - " + e.getLocalizedMessage());
}
return result;
}
/**
* Gets the error enum by code.
*
* @param pErrorCodeString the error code string
* @return the error enum by code
*/
@Deprecated
private ERROR_CODE getErrorEnumByCode(String pErrorCodeString) {
if (pErrorCodeString.equals(ERROR_CODE.AccountDeleted.name())) {
return ERROR_CODE.AccountDeleted;
} else if (pErrorCodeString.equals(ERROR_CODE.AccountDisabled.name())) {
return ERROR_CODE.AccountDisabled;
} else if (pErrorCodeString.equals(ERROR_CODE.BadAuthentication.name())) {
return ERROR_CODE.BadAuthentication;
} else if (pErrorCodeString.equals(ERROR_CODE.CaptchaRequired.name())) {
return ERROR_CODE.CaptchaRequired;
} else if (pErrorCodeString.equals(ERROR_CODE.NotVerified.name())) {
return ERROR_CODE.NotVerified;
} else if (pErrorCodeString.equals(ERROR_CODE.ServiceDisabled.name())) {
return ERROR_CODE.ServiceDisabled;
} else if (pErrorCodeString.equals(ERROR_CODE.TermsNotAgreed.name())) {
return ERROR_CODE.TermsNotAgreed;
} else {
return ERROR_CODE.Unknown;
}
}
/**
* Internal function used by all constructors to fully initiate the Voice
* Object without chaptcha Response.
*
* @param user the username in the format of [email protected] or [email protected]
* @param pass the password for the google account
* @param source the source
* @param printDebugIntoToSystemOut the print debug into to system out
* @param accountType Type of account to request authorization for. Possible values are:
* Voice.GOOGLE (get authorization for a Google account only)
* Voice.HOSTED (get authorization for a hosted account only)
* Voice.HOSTED_OR_GOOGLE (get authorization first for a hosted account; if attempt fails, get authorization for a Google account)
* Use Voice.HOSTED_OR_GOOGLE if you're not sure which type of account you want authorization for. If the user information matches both a hosted and a Google account, only the hosted account is authorized.
* @param captchaResponse response to a captcha challenge, set to null if normal login
* @param captchaToken token which matches the response/url from the captcha challenge
* @throws IOException Signals that an I/O exception has occurred.
*/
private void init(String user, String pass, String source,
boolean printDebugIntoToSystemOut, String accountType, String captchaResponse, String captchaToken) throws IOException {
if (accountType == GOOGLE || accountType == HOSTED || accountType == HOSTED_OR_GOOGLE) {
this.account_type = accountType;
this.PRINT_TO_CONSOLE = printDebugIntoToSystemOut;
this.user = user;
this.pass = pass;
// this.rnrSEE = rnrSee;
if (source != null) {
this.source = source;
} else {
this.source = "GoogleVoiceJava";
}
login(captchaResponse, captchaToken);
this.general = getGeneral();
setRNRSEE();
} else {
throw new IOException("AccountType not valid");
}
}
/**
* Executes the enable/disable action with the provided url params.
*
* @param paraString the URL Parameters (encoded), ie ?auth=3248sdf7234&enable=0&phoneId=1&enable=1&phoneId=2&_rnr_se=734682ghdsf
* @return the raw response of the disable action.
* @throws IOException Signals that an I/O exception has occurred.
*/
private String phonesEnableDisableApply(String paraString) throws IOException {
String out = "";
// POST /voice/call/connect/ outgoingNumber=[number to
// call]&forwardingNumber=[forwarding
// number]&subscriberNumber=undefined&remember=0&_rnr_se=[pull from
// page]
//
if (PRINT_TO_CONSOLE) {
System.out.println(phoneEnableURLString);
}
if (PRINT_TO_CONSOLE) {
System.out.println(paraString);
}
URL requestURL = new URL(phoneEnableURLString);
URLConnection conn = requestURL.openConnection();
conn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
conn
.setRequestProperty(
"User-agent",
USER_AGENT);
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStreamWriter callwr = new OutputStreamWriter(conn
.getOutputStream());
callwr.write(paraString);
callwr.flush();
BufferedReader callrd = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
return out;
}
/**
* Posts a settings change.
*
* @param requestURL the request url
* @param paraString the para string
* @return the string
* @throws IOException Signals that an I/O exception has occurred.
*/
private String postSettings(URL requestURL, String paraString)
throws IOException {
String out = "";
HttpURLConnection conn = (HttpURLConnection) requestURL.openConnection();
conn.setRequestProperty("Authorization",
"GoogleLogin auth=" + authToken);
conn.setRequestProperty("User-agent",
USER_AGENT);
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStreamWriter callwr = new OutputStreamWriter(conn.getOutputStream());
callwr.write(paraString);
callwr.flush();
// Get the response
conn.connect();
int responseCode = conn.getResponseCode();
if (PRINT_TO_CONSOLE) {
System.out.println(requestURL + " - " + conn.getResponseMessage());
}
InputStream is;
if (responseCode == 200) {
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
InputStreamReader isr = new InputStreamReader(is);
BufferedReader callrd = new BufferedReader(isr);
String line;
while ((line = callrd.readLine()) != null) {
out += line + "\n\r";
}
callwr.close();
callrd.close();
if (out.equals("")) {
throw new IOException("No Response Data Received.");
}
if (PRINT_TO_CONSOLE) {
System.out.println(out);
}
return out;
}
/**
* Internal method which parses the Homepage source code to determine the
* rnrsee variable, this variable is passed into most fuctions for placing
* calls and sms.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
private void setRNRSEE() throws IOException {
if (general != null) {
if (general.contains("'_rnr_se': '")) {
String p1 = general.split("'_rnr_se': '", 2)[1];
rnrSEE = p1.split("',", 2)[0];
if (PRINT_TO_CONSOLE) {
System.out.println("Successfully Received rnr_se.");
}
p1 = null;
} else if (general.contains("
")) {
String gcNotice = ParsingUtil.removeUninterestingParts(general, "", "", false);
System.out.println(gcNotice + "(Answer did not contain rnr_se)");
throw new IOException(gcNotice + "(Answer did not contain rnr_se)");
} else {
System.out.println("Answer did not contain rnr_se! " + general);
throw new IOException("Answer did not contain rnr_se! " + general);
}
} else {
System.out.println("setRNRSEE(): Answer was null!");
throw new IOException("setRNRSEE(): Answer was null!");
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy