All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.techventus.server.voice.Voice Maven / Gradle / Ivy

The newest version!
/*
 * 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