diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAbstract.java b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAbstract.java new file mode 100644 index 00000000..29a10b57 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAbstract.java @@ -0,0 +1,29 @@ +package com.vk.api.sdk.captcha; + +public abstract class CaptchaHandlerAbstract { + private int maxCaptchaProcessRetries = 2; + private int maxTechnicalResolveRetries = 2; + + public int getMaxCaptchaProcessRetries() { + return maxCaptchaProcessRetries; + } + + public int getMaxTechnicalResolveRetries() { + return maxTechnicalResolveRetries; + } + + public CaptchaHandlerAbstract(int maxCaptchaProcessRetries, int maxTechnicalResolveRetries) { + this.maxCaptchaProcessRetries = maxCaptchaProcessRetries; + this.maxTechnicalResolveRetries = maxTechnicalResolveRetries; + } + + public CaptchaHandlerAbstract() { + } + + abstract public String getCaptchaCode(String sid, String img) throws CaptchaResolveException; + + public boolean checkCode(String key) { + if(key == null || !key.matches("^[0-9a-zA-Z]*?$")) return false; + return true; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAnticaptcha.java b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAnticaptcha.java new file mode 100644 index 00000000..f5ade24c --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerAnticaptcha.java @@ -0,0 +1,24 @@ +package com.vk.api.sdk.captcha; + + +import com.vk.api.sdk.captcha.anticaptcha.GetCaptchaSimple; + +public class CaptchaHandlerAnticaptcha extends CaptchaHandlerAbstract { + private final String apiKey; + private final Integer sleepSecondBetweenTaskCheck; + private final Integer maxRetries; + + public CaptchaHandlerAnticaptcha(String apiKey, Integer sleepSecondBetweenTaskCheck, Integer maxRetries) { + this.apiKey = apiKey; + this.sleepSecondBetweenTaskCheck = sleepSecondBetweenTaskCheck; + this.maxRetries = maxRetries; + } + + @Override + public String getCaptchaCode(String sid, String img) throws CaptchaResolveException { + System.out.println("Resolving captcha via anti-captcha.com..."); + return GetCaptchaSimple.getCaptchaCode(img, apiKey, sleepSecondBetweenTaskCheck, maxRetries); + } + +} + diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerConsole.java b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerConsole.java new file mode 100644 index 00000000..32b34ced --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerConsole.java @@ -0,0 +1,36 @@ +package com.vk.api.sdk.captcha; + + +import java.util.Objects; +import java.util.Scanner; + +public class CaptchaHandlerConsole extends CaptchaHandlerAbstract { + + @Override + public String getCaptchaCode(String sid, String img) throws CaptchaResolveException { + System.out.println("----------------------------------------------"); + System.out.println("NEED TO ENTER CAPTCHA"); + System.out.println("SID: "+sid); + System.out.println("Link: "+img); + System.out.println("Enter 'q' or 'quit' to decline! "); + System.out.println("---"); + Scanner consoleInputScanner = new Scanner(System.in); + String userEnteredCaptcha; + while(true) { + System.out.print("PLEASE ENTER CAPTCHA: "); + userEnteredCaptcha = consoleInputScanner.next(); + if (Objects.equals(userEnteredCaptcha, "q") || Objects.equals(userEnteredCaptcha, "quit")) + throw new CaptchaResolveException("User declined to enter the captcha"); + if(checkCode(userEnteredCaptcha)) break; + else { + System.out.println("Wrong captcha format, please re-enter captcha."); + continue; + } + } + System.out.println("Captcha entered: "+userEnteredCaptcha); + System.out.println("----------------------------------------------"); + return userEnteredCaptcha; + } + +} + diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerFactory.java b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerFactory.java new file mode 100644 index 00000000..f8a1dfa7 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaHandlerFactory.java @@ -0,0 +1,12 @@ +package com.vk.api.sdk.captcha; + + +import java.util.Objects; +import java.util.Scanner; + +public class CaptchaHandlerFactory { + public static CaptchaHandlerConsole getConsoleHandler() { + return new CaptchaHandlerConsole(); + } +} + diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaResolveException.java b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaResolveException.java new file mode 100644 index 00000000..7131672e --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/CaptchaResolveException.java @@ -0,0 +1,9 @@ +package com.vk.api.sdk.captcha; + +import com.vk.api.sdk.exceptions.ApiException; + +public class CaptchaResolveException extends ApiException { + public CaptchaResolveException(String message) { + super(message); + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/GetCaptchaSimple.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/GetCaptchaSimple.java new file mode 100644 index 00000000..0f27a1c3 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/GetCaptchaSimple.java @@ -0,0 +1,111 @@ +package com.vk.api.sdk.captcha.anticaptcha; + + +import com.vk.api.sdk.captcha.CaptchaResolveException; +import com.vk.api.sdk.captcha.anticaptcha.entities.ImageToTextTaskRequestObject; +import com.vk.api.sdk.captcha.anticaptcha.entities.requests.CreateTaskRequest; +import com.vk.api.sdk.captcha.anticaptcha.entities.requests.CreateTaskResponse; +import com.vk.api.sdk.captcha.anticaptcha.entities.requests.GetCaptchaResultRequest; +import com.vk.api.sdk.captcha.anticaptcha.entities.requests.GetCaptchaResultResponse; +import com.vk.api.sdk.captcha.anticaptcha.simpleRequest.simpleRequest; +import org.apache.commons.io.IOUtils; +import org.apache.http.message.BasicHeader; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Base64; +import java.util.Objects; + +public class GetCaptchaSimple { + + public static byte[] readFromPathOrUrl(String urlOrPath) throws IOException { + if(urlOrPath.contains("http")) { + URL url = new URL (urlOrPath); + InputStream is = null; + try { + is = url.openStream(); + return IOUtils.toByteArray(is); + } + catch (IOException e) { + System.err.printf ("Failed while reading bytes from %s: %s", url.toExternalForm(), e.getMessage()); + e.printStackTrace (); + throw e; + } + finally { + if (is != null) { is.close(); } + } + } + else return Files.readAllBytes(Path.of(urlOrPath)); + } + + + public static String getCaptchaCode(String captchaUrlOrPath, String antiCaptchaApiKey, Integer sleepSecondBetweenTaskCheck, Integer maxRetries) throws CaptchaResolveException { + if(sleepSecondBetweenTaskCheck==null) sleepSecondBetweenTaskCheck=5; + if(maxRetries==null) maxRetries=2; + + //Base64 of image + String encodedImage = null; + try { + encodedImage = Base64.getEncoder().encodeToString(readFromPathOrUrl(captchaUrlOrPath)); + } catch (IOException e) { + e.printStackTrace(); + } + if (encodedImage == null) throw new CaptchaResolveException("Cant resolve captcha, cant get base64 of img!"); + + //Set resolve task + Integer taskId = null; + try { + CreateTaskResponse createTaskResponse = new simpleRequest() + .setUrl("http://api.anti-captcha.com/createTask") + .addHeader(new BasicHeader("Accept", "application/json")) + .addHeader(new BasicHeader("Content-Type", "application/json")) + .doRequest(new CreateTaskRequest().setClientKey(antiCaptchaApiKey).setTask(new ImageToTextTaskRequestObject().setBody(encodedImage)), CreateTaskResponse.class); + taskId = createTaskResponse.getTaskId(); + } catch (IOException e) { + e.printStackTrace(); + throw new CaptchaResolveException("IO exception during create task!"); + } + if (taskId == null) throw new CaptchaResolveException("Cant resolve captcha, anticaptcha /createTask not returned taskId!"); + + //Get captcha resolve + for (int i = 0; i < maxRetries; i++) { + try { + Thread.sleep(sleepSecondBetweenTaskCheck*1000); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new CaptchaResolveException("Cant resolve captcha, wait interrupted!"); + } + + //Get captcha code + String captchaText = null; + try { + GetCaptchaResultResponse response = new simpleRequest() + .setUrl("http://api.anti-captcha.com/getTaskResult") + .addHeader(new BasicHeader("Accept", "application/json")) + .addHeader(new BasicHeader("Content-Type", "application/json")) + .doRequest(new GetCaptchaResultRequest().setClientKey(antiCaptchaApiKey).setTaskId(taskId), GetCaptchaResultResponse.class); + if (Objects.equals(response.getStatus(), "processing")) continue; + if (!Objects.equals(response.getStatus(), "ready")) + throw new CaptchaResolveException("Cant resolve captcha, anticaptcha result is not in correct status, error: " + + response.getErrorId() + + " " + response.getErrorCode() + + " " + response.getErrorDescription() + ); + captchaText = response.getSolution().getText(); + if (captchaText == null) + throw new CaptchaResolveException("Cant resolve captcha, anticaptcha result text is null!"); + return captchaText; + + } catch (IOException e) { + e.printStackTrace(); + throw new CaptchaResolveException("IO exception during getTaskResult"); + } + } + throw new CaptchaResolveException("Cant be here!"); + } + +} + diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskRequestObject.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskRequestObject.java new file mode 100644 index 00000000..03930c16 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskRequestObject.java @@ -0,0 +1,67 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities; + +import com.google.gson.annotations.SerializedName; + +public class ImageToTextTaskRequestObject { + private String type = "ImageToTextTask"; + private String body; + private Boolean phrase; + @SerializedName("case") + private Boolean tCase; + private Integer numeric; + private Boolean math; + private Integer minLength; + private Integer maxLength; + private String commend; + private String websiteURL; + + public ImageToTextTaskRequestObject setType(String type) { + this.type = type; + return this; + } + + public ImageToTextTaskRequestObject setBody(String body) { + this.body = body; + return this; + } + + public ImageToTextTaskRequestObject setPhrase(Boolean phrase) { + this.phrase = phrase; + return this; + } + + public ImageToTextTaskRequestObject setCase(Boolean tCase) { + this.tCase = tCase; + return this; + } + + public ImageToTextTaskRequestObject setNumeric(Integer numeric) { + this.numeric = numeric; + return this; + } + + public ImageToTextTaskRequestObject setMath(Boolean math) { + this.math = math; + return this; + } + + public ImageToTextTaskRequestObject setMinLength(Integer minLength) { + this.minLength = minLength; + return this; + } + + public ImageToTextTaskRequestObject setMaxLength(Integer maxLength) { + this.maxLength = maxLength; + return this; + } + + public ImageToTextTaskRequestObject setCommend(String commend) { + this.commend = commend; + return this; + } + + public ImageToTextTaskRequestObject setWebsiteURL(String websiteURL) { + this.websiteURL = websiteURL; + return this; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskResultObject.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskResultObject.java new file mode 100644 index 00000000..004e962c --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/ImageToTextTaskResultObject.java @@ -0,0 +1,14 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities; + +public class ImageToTextTaskResultObject { + private String text; + private String url; + + public String getText() { + return text; + } + + public String getUrl() { + return url; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/common/GetCaptchaResultResponseAbstract.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/common/GetCaptchaResultResponseAbstract.java new file mode 100644 index 00000000..cbeb87c9 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/common/GetCaptchaResultResponseAbstract.java @@ -0,0 +1,95 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities.common; + +abstract public class GetCaptchaResultResponseAbstract { + protected Integer errorId; + protected String errorCode; + protected String errorDescription; + protected String status; + + protected Double cost; + protected String ip; + protected Integer createTime; + protected Integer endTime; + protected Integer solveCount; + + public Integer getErrorId() { + return errorId; + } + + public String getErrorCode() { + return errorCode; + } + + public String getErrorDescription() { + return errorDescription; + } + + public String getStatus() { + return status; + } + + public Double getCost() { + return cost; + } + + public String getIp() { + return ip; + } + + public Integer getCreateTime() { + return createTime; + } + + public Integer getEndTime() { + return endTime; + } + + public Integer getSolveCount() { + return solveCount; + } + + public GetCaptchaResultResponseAbstract setErrorId(Integer errorId) { + this.errorId = errorId; + return this; + } + + public GetCaptchaResultResponseAbstract setErrorCode(String errorCode) { + this.errorCode = errorCode; + return this; + } + + public GetCaptchaResultResponseAbstract setErrorDescription(String errorDescription) { + this.errorDescription = errorDescription; + return this; + } + + public GetCaptchaResultResponseAbstract setStatus(String status) { + this.status = status; + return this; + } + + public GetCaptchaResultResponseAbstract setCost(Double cost) { + this.cost = cost; + return this; + } + + public GetCaptchaResultResponseAbstract setIp(String ip) { + this.ip = ip; + return this; + } + + public GetCaptchaResultResponseAbstract setCreateTime(Integer createTime) { + this.createTime = createTime; + return this; + } + + public GetCaptchaResultResponseAbstract setEndTime(Integer endTime) { + this.endTime = endTime; + return this; + } + + public GetCaptchaResultResponseAbstract setSolveCount(Integer solveCount) { + this.solveCount = solveCount; + return this; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskRequest.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskRequest.java new file mode 100644 index 00000000..02c20571 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskRequest.java @@ -0,0 +1,17 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities.requests; + +import com.vk.api.sdk.captcha.anticaptcha.entities.ImageToTextTaskRequestObject; + +public class CreateTaskRequest { + private String clientKey; + private ImageToTextTaskRequestObject task; + + public CreateTaskRequest setClientKey(String clientKey) { + this.clientKey = clientKey; + return this; + } + public CreateTaskRequest setTask(ImageToTextTaskRequestObject task) { + this.task = task; + return this; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskResponse.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskResponse.java new file mode 100644 index 00000000..d1b79b65 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/CreateTaskResponse.java @@ -0,0 +1,16 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities.requests; + +import com.google.gson.Gson; + +public class CreateTaskResponse { + private Integer errorId; + private Integer taskId; + + public Integer getErrorId() { + return errorId; + } + + public Integer getTaskId() { + return taskId; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultRequest.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultRequest.java new file mode 100644 index 00000000..5284f91b --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultRequest.java @@ -0,0 +1,15 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities.requests; + +public class GetCaptchaResultRequest { + private String clientKey; + private Integer taskId; + + public GetCaptchaResultRequest setClientKey(String clientKey) { + this.clientKey = clientKey; + return this; + } + public GetCaptchaResultRequest setTaskId(Integer taskId) { + this.taskId = taskId; + return this; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultResponse.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultResponse.java new file mode 100644 index 00000000..b1dd3056 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/entities/requests/GetCaptchaResultResponse.java @@ -0,0 +1,13 @@ +package com.vk.api.sdk.captcha.anticaptcha.entities.requests; + +import com.vk.api.sdk.captcha.anticaptcha.entities.ImageToTextTaskResultObject; +import com.vk.api.sdk.captcha.anticaptcha.entities.common.GetCaptchaResultResponseAbstract; + +public class GetCaptchaResultResponse extends GetCaptchaResultResponseAbstract { + + ImageToTextTaskResultObject solution; + + public ImageToTextTaskResultObject getSolution() { + return solution; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/simpleRequest/simpleRequest.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/simpleRequest/simpleRequest.java new file mode 100644 index 00000000..e42053cd --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/simpleRequest/simpleRequest.java @@ -0,0 +1,45 @@ +package com.vk.api.sdk.captcha.anticaptcha.simpleRequest; + +import com.google.gson.Gson; +import com.vk.api.sdk.client.ClientResponse; +import com.vk.api.sdk.client.TransportClient; +import com.vk.api.sdk.httpclient.HttpTransportClient; +import org.apache.http.Header; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class simpleRequest { + private String url; + private List
headers; + + public simpleRequest setUrl(String url) { + this.url = url; + return this; + } + + + public simpleRequest addHeader(Header header) { + if(headers==null) headers = new ArrayList<>(); + this.headers.add(header); + return this; + } + + public Header[] getHeaders() { + return this.headers.toArray(new Header[0]); + } + + public T doRequest(Object requestObject, Class responseObject) throws IOException { + TransportClient transportClient = new HttpTransportClient(); + ClientResponse clientResponse = null; + if(url==null) throw new IOException("URL is null!"); + try { + clientResponse = transportClient.post(url, new Gson().toJson(requestObject), getHeaders()); + return new Gson().fromJson(clientResponse.getContent(), responseObject); + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/test/resolveTestCaptcha.java b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/test/resolveTestCaptcha.java new file mode 100644 index 00000000..57e663f7 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/captcha/anticaptcha/test/resolveTestCaptcha.java @@ -0,0 +1,22 @@ +package com.vk.api.sdk.captcha.anticaptcha.test; + +import com.vk.api.sdk.captcha.CaptchaHandlerAnticaptcha; +import com.vk.api.sdk.captcha.CaptchaResolveException; + +import java.util.Objects; + +public class resolveTestCaptcha { + public static void main(String[] args) { + String filenameOrUrl = "https://api.vk.com//captcha.php?sid=723412182770"; + String apiKey = "YOUR_API_KEY_HERE"; + //String expectedResult = "ab54qc"; //cant check result if it is some dynamic link + + try { + String somesid = new CaptchaHandlerAnticaptcha(apiKey, null, null).getCaptchaCode("723412182770", filenameOrUrl); + System.out.println("Anticaptcha result: "+somesid); + //assert Objects.equals(somesid, expectedResult); //cant check result if it is some dynamic link + } catch (CaptchaResolveException e) { + e.printStackTrace(); + } + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/client/AbstractQueryBuilder.java b/sdk/src/main/java/com/vk/api/sdk/client/AbstractQueryBuilder.java index b99eba8c..edc0a769 100644 --- a/sdk/src/main/java/com/vk/api/sdk/client/AbstractQueryBuilder.java +++ b/sdk/src/main/java/com/vk/api/sdk/client/AbstractQueryBuilder.java @@ -1,5 +1,10 @@ package com.vk.api.sdk.client; +import com.vk.api.sdk.captcha.CaptchaHandlerAbstract; +import com.vk.api.sdk.captcha.CaptchaResolveException; +import com.vk.api.sdk.exceptions.ApiCaptchaExceptionCustom; +import com.vk.api.sdk.exceptions.ApiException; +import com.vk.api.sdk.exceptions.ClientException; import com.vk.api.sdk.queries.EnumParam; import java.io.UnsupportedEncodingException; @@ -332,7 +337,45 @@ public Map getParams() { return params; } - public String toString(){ + public String toString() { return this.getMethod(); } + + + private CaptchaHandlerAbstract captchaHandler; + + public T setCaptchaHandler(CaptchaHandlerAbstract captchaHandler) { + this.captchaHandler = captchaHandler; + return this.getThis(); + } + + @Override + public R execute() throws ApiException, ClientException { + for (int processRetry = 1; ; ) { + try { + return super.execute(); + } catch (ApiCaptchaExceptionCustom captchaException) { + if (captchaHandler == null + || captchaHandler.getMaxCaptchaProcessRetries() < 1 + || processRetry > captchaHandler.getMaxCaptchaProcessRetries() + ) throw captchaException; //no handler or counter > max - throw + + //technical retries + for (int technicalResolveRetry = 1; ; ) { + try { + unsafeParam("captcha_key", captchaHandler.getCaptchaCode(captchaException.getCaptcha_sid(), captchaException.getCaptcha_img())); + unsafeParam("captcha_sid", captchaException.getCaptcha_sid()); + processRetry++; + break; //resolved, retry request via execute() + } catch (CaptchaResolveException resolveException) { + //not resolved + if (technicalResolveRetry >= captchaHandler.getMaxTechnicalResolveRetries()) throw resolveException; //counter > max - throw + resolveException.printStackTrace(); + technicalResolveRetry++; + continue; //retry resolving + } + } + } + } + } } diff --git a/sdk/src/main/java/com/vk/api/sdk/client/ApiRequest.java b/sdk/src/main/java/com/vk/api/sdk/client/ApiRequest.java index 8e73d34d..f0a44984 100644 --- a/sdk/src/main/java/com/vk/api/sdk/client/ApiRequest.java +++ b/sdk/src/main/java/com/vk/api/sdk/client/ApiRequest.java @@ -2,12 +2,9 @@ import com.google.gson.*; import com.google.gson.stream.JsonReader; -import com.vk.api.sdk.exceptions.ApiException; -import com.vk.api.sdk.exceptions.ApiServerException; -import com.vk.api.sdk.exceptions.ClientException; -import com.vk.api.sdk.exceptions.ExceptionMapper; -import com.vk.api.sdk.exceptions.RequiredFieldException; +import com.vk.api.sdk.exceptions.*; import com.vk.api.sdk.objects.base.Error; +import com.vk.api.sdk.objects.base.ErrorWithCaptcha; import org.apache.http.Header; import org.slf4j.LoggerFactory; import org.slf4j.Logger; @@ -93,15 +90,15 @@ private T executeWithoutRetry() throws ClientException, ApiException { if (json.has("error")) { JsonElement errorElement = json.get("error"); - Error error; + ErrorWithCaptcha error; try { - error = gson.fromJson(errorElement, Error.class); + error = gson.fromJson(errorElement, ErrorWithCaptcha.class); } catch (JsonSyntaxException e) { LOG.error("Invalid JSON: " + textResponse, e); throw new ClientException("Can't parse json response"); } - ApiException exception = ExceptionMapper.parseException(error); + ApiException exception = ExceptionMapperCustom.parseException(error); LOG.error("API error", exception); throw exception; diff --git a/sdk/src/main/java/com/vk/api/sdk/exceptions/ApiCaptchaExceptionCustom.java b/sdk/src/main/java/com/vk/api/sdk/exceptions/ApiCaptchaExceptionCustom.java new file mode 100644 index 00000000..f99e3961 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/exceptions/ApiCaptchaExceptionCustom.java @@ -0,0 +1,20 @@ +package com.vk.api.sdk.exceptions; + +public class ApiCaptchaExceptionCustom extends ApiException { + String captcha_sid; + String captcha_img; + + public String getCaptcha_sid() { + return captcha_sid; + } + + public String getCaptcha_img() { + return captcha_img; + } + + public ApiCaptchaExceptionCustom(Integer code, String message, String captcha_sid, String captcha_img) { + super(code, "(Re)Captcha needed", message); + this.captcha_img = captcha_img; + this.captcha_sid = captcha_sid; + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/exceptions/ExceptionMapperCustom.java b/sdk/src/main/java/com/vk/api/sdk/exceptions/ExceptionMapperCustom.java new file mode 100644 index 00000000..79065cb3 --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/exceptions/ExceptionMapperCustom.java @@ -0,0 +1,16 @@ +package com.vk.api.sdk.exceptions; + +import com.vk.api.sdk.objects.base.ErrorWithCaptcha; + +public class ExceptionMapperCustom extends ExceptionMapper { + public static ApiException parseException(ErrorWithCaptcha error) { + switch(error.getErrorCode()) { + case 14: + return new ApiCaptchaExceptionCustom(14, error.getErrorMsg(), error.getCaptchaSid(), error.getCaptchaImg()); + case 3300: + return new ApiCaptchaExceptionCustom(3300, error.getErrorMsg(), error.getCaptchaSid(), error.getCaptchaImg()); + default: + return ExceptionMapper.parseException(error); + } + } +} diff --git a/sdk/src/main/java/com/vk/api/sdk/objects/base/Error.java b/sdk/src/main/java/com/vk/api/sdk/objects/base/Error.java index 3ab8de43..3429bc3e 100644 --- a/sdk/src/main/java/com/vk/api/sdk/objects/base/Error.java +++ b/sdk/src/main/java/com/vk/api/sdk/objects/base/Error.java @@ -15,28 +15,28 @@ public class Error implements Validable { * Error code */ @SerializedName("error_code") - private Integer errorCode; + protected Integer errorCode; /** * Error subcode */ @SerializedName("error_subcode") - private Integer errorSubcode; + protected Integer errorSubcode; /** * Error message */ @SerializedName("error_msg") - private String errorMsg; + protected String errorMsg; /** * Localized error message */ @SerializedName("error_text") - private String errorText; + protected String errorText; @SerializedName("request_params") - private List requestParams; + protected List requestParams; public Integer getErrorCode() { return errorCode; diff --git a/sdk/src/main/java/com/vk/api/sdk/objects/base/ErrorWithCaptcha.java b/sdk/src/main/java/com/vk/api/sdk/objects/base/ErrorWithCaptcha.java new file mode 100644 index 00000000..e60984de --- /dev/null +++ b/sdk/src/main/java/com/vk/api/sdk/objects/base/ErrorWithCaptcha.java @@ -0,0 +1,48 @@ +// Autogenerated from vk-api-schema. Please don't edit it manually. +package com.vk.api.sdk.objects.base; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.vk.api.sdk.objects.Validable; + +import java.util.List; +import java.util.Objects; + +/** + * Error object + */ +public class ErrorWithCaptcha extends Error { + @SerializedName("captcha_sid") + private String captchaSid; + + @SerializedName("captcha_img") + private String captchaImg; + + @Override + public String toString() { + final Gson gson = new Gson(); + return gson.toJson(this); + } + + public String getCaptchaSid() { + return captchaSid; + } + + public String getCaptchaImg() { + return captchaImg; + } + + + public String toPrettyString() { + final StringBuilder sb = new StringBuilder("Error{"); + sb.append("errorText='").append(errorText).append("'"); + sb.append(", errorMsg='").append(errorMsg).append("'"); + sb.append(", requestParams=").append(requestParams); + sb.append(", errorCode=").append(errorCode); + sb.append(", errorSubcode=").append(errorSubcode); + sb.append(", captcha_sid=").append(captchaSid); + sb.append(", captcha_img=").append(captchaImg); + sb.append('}'); + return sb.toString(); + } +}