Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: New Recaptcha Provider (CapSolver) #57

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Net.Http;
using System.Threading.Tasks;

namespace PuppeteerExtraSharp.Plugins.Recaptcha.Provider.CapSolver;

public class CapSolver : IRecaptchaProvider
{
private readonly ProviderOptions _options;
private readonly CapSolverApi _api;

public CapSolver(string key, ProviderOptions options = null)
{
_options = options ?? ProviderOptions.CreateDefaultOptions();
_api = new CapSolverApi(key, _options);
}
public async Task<string> GetSolution(string key, string pageUrl, string proxyStr = null)
{
var task = await _api.CreateTaskAsync(pageUrl, key);
await System.Threading.Tasks.Task.Delay(_options.StartTimeoutSeconds * 1000);
var result = await _api.PendingForResult(task.taskId);

if (result.status != "ready" || result.solution is null || result.errorId != 0)
throw new HttpRequestException($"CapSolver request ends with error - {result.errorId}");

return result.solution.gRecaptchaResponse;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Threading;
using System.Threading.Tasks;
using PuppeteerExtraSharp.Plugins.Recaptcha.Provider.CapSolver.Models;
using PuppeteerExtraSharp.Plugins.Recaptcha.RestClient;
using RestSharp;

namespace PuppeteerExtraSharp.Plugins.Recaptcha.Provider.CapSolver;

public class CapSolverApi
{
private readonly string _userKey;
private readonly ProviderOptions _options;
private readonly RestClient.RestClient _client = new RestClient.RestClient("https://api.capsolver.com");
public CapSolverApi(string userKey, ProviderOptions options)
{
_userKey = userKey;
_options = options;
}

public Task<CapSolverTaskResponse> CreateTaskAsync(string pageUrl, string key, CancellationToken token = default)
{
var request = new CapSolverRequest()
{
clientKey = _userKey,
task = new CapSolverTaskRequest()
{
type = "ReCaptchaV2TaskProxyless",
websiteURL = pageUrl,
websiteKey = key
}
};

var result = _client.PostWithJsonAsync<CapSolverTaskResponse>("createTask", request, token);
return result;
}

public async Task<CapSolverTaskResponse> PendingForResult(string taskId, CancellationToken token = default)
{
var content = new CapSolverRequest()
{
clientKey = _userKey,
taskId = taskId
};

var request = new RestRequest("getTaskResult");
request.AddJsonBody(content);
request.Method = Method.Post;

var result = await _client.CreatePollingBuilder<CapSolverTaskResponse>(request).TriesLimit(_options.PendingCount)
.WithTimeoutSeconds(5).ActivatePollingAsync(
response =>
{
if (response.Data.status == "ready" || response.Data.errorId != 0)
return PollingAction.Break;

return PollingAction.ContinuePolling;
});
return result.Data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace PuppeteerExtraSharp.Plugins.Recaptcha.Provider.CapSolver.Models;

public class CapSolverRequest
{
public string clientKey { get; set; }
public string taskId { get; set; }
public CapSolverTaskRequest task { get; set; }

}

public class CapSolverTaskRequest
{
public string type { get; set; }
public string websiteURL { get; set; }
public string websiteKey { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace PuppeteerExtraSharp.Plugins.Recaptcha.Provider.CapSolver.Models;

public class CapSolverTaskResponse
{
public int errorId { get; set; }
public string errorCode { get; set; }
public string errorDescription { get; set; }
public string taskId { get; set; }
public string status { get; set; }
public CapSolverTaskSolutionResponse solution { get; set; }
}

public class CapSolverTaskSolutionResponse
{
public string userAgent { get; set; }
public long expireTime { get; set; }
public string gRecaptchaResponse { get; set; }
}
2 changes: 2 additions & 0 deletions PuppeteerExtraSharp/Plugins/Recaptcha/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ await recaptchaPlugin.SolveCaptchaAsync(page);

👾 [2captcha](https://2captcha.com/ru)

👽 [CapSolver](https://www.capsolver.com/)

You can use your own provider implements IRecaptcha provider interface who should return g-recaptcha-responce.