Skip to content
Merged
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function run() {
websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd',
});

console.log(await cmcClient.Solve(recaptchaV2ProxylessRequest));
console.log(await cmcClient.Solve(recaptchaV2Request));
}

run()
Expand Down Expand Up @@ -87,9 +87,11 @@ DEBUG=cmc-* node app.js
- [ProsopoRequest](https://zenno.link/doc-prosopo-en)
- [RecaptchaComplexImageTaskRequest](https://zenno.link/doc-complextask-rc-en)
- [RecaptchaV2EnterpriseRequest](https://zenno.link/doc-recaptcha2e-proxy-en)
- [RecaptchaV3EnterpriseRequest](https://zenno.link/doc-recaptcha3e-proxy-en)
- [RecaptchaV2Request](https://zenno.link/doc-recaptcha2-proxy-en)
- [RecaptchaV3ProxylessRequest](https://zenno.link/doc-recaptcha3-en)
- [Temu](https://zenno.link/doc-temu-en)
- [TenDIRequest](https://zenno.link/doc-tendi-en)
- [TurnstileRequest](https://zenno.link/doc-turnstile-proxy-en)
- [Yidun](https://zenno.link/doc-yidun-en)
- [Altcha](https://zenno.link/doc-altcha-en)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zennolab_com/capmonstercloud-client",
"version": "2.4.0",
"version": "2.5.0",
"description": "Official JS client library for https://capmonster.cloud/ captcha recognition service",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
22 changes: 22 additions & 0 deletions src/CapMonsterCloudClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ import { YidunRequest } from './Requests/YidunRequest';
import { YidunResponse } from './Responses/YidunResponse';
import { MTCaptchaRequest } from './Requests/MTCaptchaRequest';
import { MTCaptchaResponse } from './Responses/MTCaptchaResponse';
import { AltchaRequest } from './Requests/AltchaRequest';
import { AltchaResponse } from './Responses/AltchaResponse';
import { RecaptchaV3EnterpriseRequest } from './Requests/RecaptchaV3EnterpriseRequest';
import { RecaptchaV3EnterpriseResponse } from './Responses/RecaptchaV3EnterpriseResponse';

type CustomTaskUnion = TemuRequest | BasiliskRequest | ImpervaRequest;

Expand Down Expand Up @@ -214,6 +218,15 @@ export class CapMonsterCloudClient {
resultTimeouts?: GetResultTimeouts,
cancellationController?: AbortController,
): Promise<CaptchaResult<RecaptchaV2EnterpriseResponse>>;
/**
* Solve RecaptchaV3EnterpriseTask task
* You will get response within 10 - 180 secs period depending on service workload.
*/
public async Solve(
task: RecaptchaV3EnterpriseRequest,
resultTimeouts?: GetResultTimeouts,
cancellationController?: AbortController,
): Promise<CaptchaResult<RecaptchaV3EnterpriseResponse>>;
/**
* Solve NoCaptchaTask task
* You will get response within 10 - 180 secs period depending on service workload.
Expand Down Expand Up @@ -241,6 +254,15 @@ export class CapMonsterCloudClient {
resultTimeouts?: GetResultTimeouts,
cancellationController?: AbortController,
): Promise<CaptchaResult<DataDomeResponse>>;
/**
* Solve AltchaRequest task
* You will get response within 10 - 180 secs period depending on service workload.
*/
public async Solve(
task: AltchaRequest,
resultTimeouts?: GetResultTimeouts,
cancellationController?: AbortController,
): Promise<CaptchaResult<AltchaResponse>>;
/**
* Solve TenDI task
* You will get response within 10 - 180 secs period depending on service workload.
Expand Down
37 changes: 0 additions & 37 deletions src/CapMonsterCloudClientFactory.i.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -731,44 +731,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => {

expect(await srv.destroy()).toBeUndefined();
});
it('should solve Imperva Task', async () => {
expect.assertions(5);

const srv = await createServerMock({
responses: [
{ responseBody: '{"errorId":0,"taskId":1234567}' },
{
responseBody:
'{"errorId":0,"status":"ready","solution":{"domains": { "site.com" : { "cookies": { "___utmvc": "NMB", "reese84": "reese84"}} } }}',
},
],
});

const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: '<your capmonster.cloud API key>', serviceUrl: `http://localhost:${srv.address.port}` }),
);

const impervaRequest = new ImpervaRequest({
websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle',
metadata: {
incapsulaScriptBase64: 'dmFyIF8weGQ2ZmU9Wydce..eDUzXHg2YV',
incapsulaSessionCookie: 'l/LsGnrvyB9lNhXI8borDKa2IGc',
},
});

const task = await cmcClient.Solve(impervaRequest);

expect(srv.caughtRequests[0]).toHaveProperty(
'body',
'{"clientKey":"<your capmonster.cloud API key>","task":{"type":"CustomTask","websiteURL":"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle","metadata":{"incapsulaScriptBase64":"dmFyIF8weGQ2ZmU9Wydce..eDUzXHg2YV","incapsulaSessionCookie":"l/LsGnrvyB9lNhXI8borDKa2IGc"},"class":"Imperva"},"softId":54}',
);
expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"<your capmonster.cloud API key>","taskId":1234567}');
expect(task).toHaveProperty('solution');

expect(task).toHaveProperty('solution.domains', { 'site.com': { cookies: { ___utmvc: 'NMB', reese84: 'reese84' } } });

expect(await srv.destroy()).toBeUndefined();
});
it('should solve Imperva Task with Proxy', async () => {
expect.assertions(5);

Expand Down
4 changes: 3 additions & 1 deletion src/GetTaskResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { BasiliskResponse } from './Responses/BasiliskResponse';
import { ImpervaResponse } from './Responses/ImpervaResponse';
import { BinanceResponse } from './Responses/BinanceResponse';
import { ComplexImageRecognitionResponse } from './Responses/ComplexImageRecognitionResponse';
import { AltchaResponse } from './Responses/AltchaResponse';

export enum TaskResultType {
Failed = 'Failed',
Expand Down Expand Up @@ -45,7 +46,8 @@ export type TaskCompletedSolution =
| BasiliskResponse
| ImpervaResponse
| BinanceResponse
| ComplexImageRecognitionResponse;
| ComplexImageRecognitionResponse
| AltchaResponse;

export type TaskCompleted<S extends TaskCompletedSolution> = {
type: TaskResultType.Completed;
Expand Down
20 changes: 20 additions & 0 deletions src/Requests/AltchaRequest/AltchaRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TaskType } from '../../TaskType';
import { AltchaRequestBase, AltchaRequestBaseIn } from './AltchaRequestBase';
import { ProxyInfo, ProxyInfoIn } from '../ProxyInfo';

export type AltchaRequestIn = Pick<AltchaRequestBaseIn, Exclude<keyof AltchaRequestBaseIn, 'type' | '_class'>> & {
proxy?: ProxyInfoIn;
};
/**
* Altcha recognition request.
* {@link https://zenno.link/doc-altcha}
*/
export class AltchaRequest extends AltchaRequestBase {
constructor({ proxy, ...argsObj }: AltchaRequestIn) {
super({ type: TaskType.CustomTask, _class: 'altcha', ...argsObj });

if (proxy) {
Object.assign(this, new ProxyInfo(proxy));
}
}
}
53 changes: 53 additions & 0 deletions src/Requests/AltchaRequest/AltchaRequestBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase';

export type AltchaRequestBaseIn = {
websiteURL: string;
userAgent?: string;
_class: string;
metadata: Metadata;
} & CaptchaRequestBaseIn;

export type Metadata = {
challenge: string;
iterations: string;
salt: string;
signature: string;
};

/**
* Base Altcha recognition request
*/
export abstract class AltchaRequestBase extends CaptchaRequestBase {
/**
* Address of a webpage with DataDome.
*/
public websiteURL!: string;

/**
* Altcha website key.
*/
public websiteKey!: string;

/**
* The object that contains additional data about the captcha - challenge, iterations, salt, signature
*/
public metadata!: Metadata;

/**
* Browser User-Agent. Pass only the actual UA from Windows OS
*/
public userAgent?: string;

/**
* Class of captcha object
*/
public class: string;

constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: AltchaRequestBaseIn) {
super({ type, nocache });
this.websiteURL = websiteURL;
this.metadata = metadata;
this.userAgent = userAgent;
this.class = _class;
}
}
1 change: 1 addition & 0 deletions src/Requests/AltchaRequest/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AltchaRequest';
8 changes: 5 additions & 3 deletions src/Requests/DataDomeRequest/DataDomeRequestBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ export type DataDomeRequestBaseIn = {
} & CaptchaRequestBaseIn;

export type MetadataWithHtml = {
[key: string]: string;
[key: string]: string | undefined;
htmlPageBase64: string;
datadomeCookie: string;
datadomeVersion?: string;
};

export type MetadataCaptchaUrl = {
[key: string]: string;
[key: string]: string | undefined;
captchaUrl: string;
datadomeCookie: string;
datadomeVersion?: string;
};

/**
Expand All @@ -38,7 +40,7 @@ export abstract class DataDomeRequestBase extends CaptchaRequestBase {
* You can take the link from the page with the captcha.
* Often it looks like https://geo.captcha-delivery.com/captcha/?initialCid=...
*/
public metadata!: Record<string, string>;
public metadata!: Record<string, string | undefined>;

/**
* Browser User-Agent. Pass only the actual UA from Windows OS
Expand Down
7 changes: 2 additions & 5 deletions src/Requests/ImpervaRequest/ImpervaRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ import { TaskType } from '../../TaskType';
import { ImpervaRequestBase, ImpervaRequestBaseIn } from './ImpervaRequestBase';
import { ProxyInfo, ProxyInfoIn } from '../ProxyInfo';

export type ImpervaRequestIn = Pick<ImpervaRequestBaseIn, Exclude<keyof ImpervaRequestBaseIn, 'type' | '_class'>> & { proxy?: ProxyInfoIn };
export type ImpervaRequestIn = Pick<ImpervaRequestBaseIn, Exclude<keyof ImpervaRequestBaseIn, 'type' | '_class'>> & { proxy: ProxyInfoIn };
/**
* Imperva recognition request.
* {@link https://zenno.link/doc-imperva-en}
*/
export class ImpervaRequest extends ImpervaRequestBase {
constructor({ proxy, ...argsObj }: ImpervaRequestIn) {
super({ type: TaskType.CustomTask, _class: 'Imperva', ...argsObj });

if (proxy) {
Object.assign(this, new ProxyInfo(proxy));
}
Object.assign(this, new ProxyInfo(proxy));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type RecaptchaV2EnterpriseRequestBaseIn = {
enterprisePayload?: Record<string, unknown>;
recaptchaDataSValue?: string;
userAgent?: string;
pageAction?: string;
} & CaptchaRequestBaseIn;

/**
Expand Down Expand Up @@ -55,6 +56,9 @@ export abstract class RecaptchaV2EnterpriseRequestBase extends CaptchaRequestBas
*/
public userAgent?: string;

// The action name passed to grecaptcha.execute().
public pageAction?: string;

constructor({
type,
nocache,
Expand All @@ -63,12 +67,14 @@ export abstract class RecaptchaV2EnterpriseRequestBase extends CaptchaRequestBas
enterprisePayload,
recaptchaDataSValue,
userAgent,
pageAction,
}: RecaptchaV2EnterpriseRequestBaseIn) {
super({ type, nocache });
this.websiteURL = websiteURL;
this.websiteKey = websiteKey;
this.enterprisePayload = enterprisePayload;
this.recaptchaDataSValue = recaptchaDataSValue;
this.userAgent = userAgent;
this.pageAction = pageAction;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { TaskType } from '../../TaskType';
import { RecaptchaV3EnterpriseRequestBase, RecaptchaV3EnterpriseRequestBaseIn } from './RecaptchaV3EnterpriseRequestBase';

export type RecaptchaV3EnterpriseRequestIn = Pick<
RecaptchaV3EnterpriseRequestBaseIn,
Exclude<keyof RecaptchaV3EnterpriseRequestBaseIn, 'type'>
>;

/**
* Recaptcha V3 Enterprise recognition request.
* {@link https://zenno.link/doc-recaptcha3e-proxy-en}
*/

export class RecaptchaV3EnterpriseRequest extends RecaptchaV3EnterpriseRequestBase {
constructor({ ...restArgsObj }: RecaptchaV3EnterpriseRequestIn) {
super({ type: TaskType.RecaptchaV3EnterpriseTask, ...restArgsObj });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase';

export type RecaptchaV3EnterpriseRequestBaseIn = {
websiteURL: string;
websiteKey: string;
userAgent?: string;
minScore?: number;
pageAction?: string;
} & CaptchaRequestBaseIn;

/**
* Base Recaptcha V3 Enterprise recognition request
*/
export abstract class RecaptchaV3EnterpriseRequestBase extends CaptchaRequestBase {
/**
* Address of a webpage with Google ReCaptcha
*/
public websiteURL!: string;

/**
* The ReCaptcha v3 site key on the target page.
* https://www.google.com/recaptcha/enterprise.js?render=THIS_ONE
*/
public websiteKey!: string;

/**
* Browser's User-Agent which is used in emulation.
* It is required that you use a signature of a modern browser,
* otherwise Google will ask you to "update your browser".
*/
public userAgent?: string;

// The action name passed to grecaptcha.execute().
public pageAction?: string;

// Can have a value from 0.1 to 0.9
public minScore?: number;

constructor({ type, nocache, websiteURL, websiteKey, userAgent, pageAction, minScore }: RecaptchaV3EnterpriseRequestBaseIn) {
super({ type, nocache });
this.websiteURL = websiteURL;
this.websiteKey = websiteKey;
this.userAgent = userAgent;
this.pageAction = pageAction;
this.minScore = minScore;
}
}
1 change: 1 addition & 0 deletions src/Requests/RecaptchaV3EnterpriseRequest/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './RecaptchaV3EnterpriseRequest';
Loading