feat: custom solve captcha function

This commit is contained in:
March 7th 2023-01-03 13:56:24 +07:00
parent 84e2e23468
commit c9d2d1bd18
7 changed files with 30 additions and 5 deletions

View File

@ -16,6 +16,9 @@ class BaseClient extends EventEmitter {
if (options.intents) { if (options.intents) {
process.emitWarning('Intents is not available.', 'DeprecationWarning'); process.emitWarning('Intents is not available.', 'DeprecationWarning');
} }
if (typeof options.captchaSolver === 'function') {
options.captchaService = 'custom';
}
/** /**
* The options the client was instantiated with * The options the client was instantiated with
* @type {ClientOptions} * @type {ClientOptions}

View File

@ -984,7 +984,7 @@ class Client extends BaseClient {
throw new TypeError('CLIENT_INVALID_OPTION', 'captchaService', captchaServices.join(', ')); throw new TypeError('CLIENT_INVALID_OPTION', 'captchaService', captchaServices.join(', '));
} }
// Parse captcha key // Parse captcha key
if (options && captchaServices.includes(options.captchaService)) { if (options && captchaServices.includes(options.captchaService) && options.captchaService !== 'custom') {
if (typeof options.captchaKey !== 'string') { if (typeof options.captchaKey !== 'string') {
throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a string'); throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a string');
} }
@ -996,6 +996,9 @@ class Client extends BaseClient {
break; break;
} }
} }
if (options && typeof options.captchaSolver !== 'function') {
throw new TypeError('CLIENT_INVALID_OPTION', 'captchaSolver', 'a function');
}
if (options && typeof options.DMSync !== 'boolean') { if (options && typeof options.DMSync !== 'boolean') {
throw new TypeError('CLIENT_INVALID_OPTION', 'DMSync', 'a boolean'); throw new TypeError('CLIENT_INVALID_OPTION', 'DMSync', 'a boolean');
} }

View File

@ -1,8 +1,9 @@
'use strict'; 'use strict';
module.exports = class CaptchaSolver { module.exports = class CaptchaSolver {
constructor(service, key) { constructor(service, key, defaultCaptchaSolver) {
this.service = ''; this.service = 'custom';
this.solver = undefined; this.solver = undefined;
this.defaultCaptchaSolver = defaultCaptchaSolver;
this._setup(service, key); this._setup(service, key);
} }
_missingModule(name) { _missingModule(name) {
@ -37,6 +38,9 @@ module.exports = class CaptchaSolver {
throw this._missingModule('2captcha'); throw this._missingModule('2captcha');
} }
} }
default: {
this.solve = this.defaultCaptchaSolver;
}
} }
} }
solve() {} solve() {}

View File

@ -28,7 +28,11 @@ class RESTManager {
} }
setup() { setup() {
this.captchaService = new CaptchaSolver(this.client.options.captchaService, this.client.options.captchaKey); this.captchaService = new CaptchaSolver(
this.client.options.captchaService,
this.client.options.captchaKey,
this.client.options.captchaSolver,
);
} }
get api() { get api() {

View File

@ -23,7 +23,7 @@ exports.MaxBulkDeletableMessageAge = 1_209_600_000;
* * `2captcha` - 2captcha.com * * `2captcha` - 2captcha.com
* @typedef {string[]} captchaServices * @typedef {string[]} captchaServices
*/ */
exports.captchaServices = ['2captcha']; exports.captchaServices = ['2captcha', 'custom'];
/** /**
* Automatically scan and delete direct messages you receive that contain explicit media content. * Automatically scan and delete direct messages you receive that contain explicit media content.

View File

@ -92,6 +92,15 @@ const { randomUA } = require('../util/Constants');
* @property {SweeperOptions} [sweepers={}] Options for cache sweeping * @property {SweeperOptions} [sweepers={}] Options for cache sweeping
* @property {WebsocketOptions} [ws] Options for the WebSocket * @property {WebsocketOptions} [ws] Options for the WebSocket
* @property {HTTPOptions} [http] HTTP options * @property {HTTPOptions} [http] HTTP options
* @property {CustomCaptchaSolver} [captchaSolver] Function to solve a captcha (custom)
*/
/**
* Function to solve a captcha
* @typedef {function} CustomCaptchaSolver
* @param {Captcha} captcha The captcha to solve
* @param {string} userAgent The user agent to use for the request
* @returns {Promise<string>} hcaptcha token
*/ */
/** /**
@ -148,6 +157,7 @@ class Options extends null {
static createDefault() { static createDefault() {
return { return {
jsonTransformer: object => JSONBig.stringify(object), jsonTransformer: object => JSONBig.stringify(object),
captchaSolver: captcha => Promise.reject(new Error('CAPTCHA_SOLVER_NOT_IMPLEMENTED', captcha)),
closeTimeout: 5_000, closeTimeout: 5_000,
checkUpdate: true, checkUpdate: true,
readyStatus: true, readyStatus: true,

1
typings/index.d.ts vendored
View File

@ -4773,6 +4773,7 @@ export interface ClientOptions {
proxy?: string; proxy?: string;
captchaService?: captchaServices; captchaService?: captchaServices;
captchaKey?: string; captchaKey?: string;
captchaSolver?: (data: Captcha, userAgent: string) => Promise<string>;
interactionTimeout?: number; interactionTimeout?: number;
usingNewAttachmentAPI?: boolean; usingNewAttachmentAPI?: boolean;
} }