diff --git a/src/client/Client.js b/src/client/Client.js index d0c372d..319061a 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -1025,6 +1025,9 @@ class Client extends BaseClient { throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a 32 character string'); } break; + case 'nopecha': { + break; + } } } if (options && typeof options.DMSync !== 'boolean') { diff --git a/src/rest/CaptchaSolver.js b/src/rest/CaptchaSolver.js index 32f4616..aa65a2a 100644 --- a/src/rest/CaptchaSolver.js +++ b/src/rest/CaptchaSolver.js @@ -5,6 +5,9 @@ module.exports = class CaptchaSolver { this.solver = undefined; this._setup(service, key); } + _missingModule(name) { + return new Error(`${name} module not found, please install it with \`npm i ${name}\``); + } _setup(service, key) { switch (service) { case '2captcha': { @@ -24,7 +27,34 @@ module.exports = class CaptchaSolver { }); break; } catch (e) { - throw new Error('2captcha module not found, please install it with `npm i 2captcha`'); + throw this._missingModule('2captcha'); + } + } + case 'nopecha': { + if (!key || typeof key !== 'string') throw new Error('2captcha key is not provided'); + try { + const { Configuration, NopeCHAApi } = require('nopecha'); + const configuration = new Configuration({ + apiKey: key, + }); + this.service = 'nopecha'; + this.solver = new NopeCHAApi(configuration); + this.solve = siteKey => + new Promise((resolve, reject) => { + this.solver + .solveToken({ + type: 'hcaptcha', + sitekey: siteKey, + url: 'https://discord.com', + }) + .then(res => { + resolve(res); + }) + .catch(reject); + }); + break; + } catch (e) { + throw this._missingModule('nopecha'); } } } diff --git a/src/util/Constants.js b/src/util/Constants.js index 643249e..a403b11 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -39,9 +39,10 @@ exports.MaxBulkDeletableMessageAge = 1_209_600_000; /** * API captcha solver * * `2captcha` - 2captcha.com + * * `nopecha` - nopecha.com * @typedef {string[]} captchaServices */ -exports.captchaServices = ['2captcha']; +exports.captchaServices = ['2captcha', 'nopecha']; /** * Automatically scan and delete direct messages you receive that contain explicit media content. diff --git a/typings/index.d.ts b/typings/index.d.ts index 1386c1a..2493ce1 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3528,7 +3528,7 @@ export const Constants: { SweeperKeys: SweeperKey[]; // Add randomUA: () => string; - captchaServices: string[]; + captchaServices: captchaServices[]; DMScanLevel: EnumHolder; stickerAnimationMode: EnumHolder; NitroType: EnumHolder; @@ -4734,12 +4734,14 @@ export interface ClientOptions { password?: string; DMSync?: boolean; proxy?: string; - captchaService?: string; + captchaService?: captchaServices; captchaKey?: string; interactionTimeout?: number; usingNewAttachmentAPI?: boolean; } +export type captchaServices = '2captcha' | 'nopecha'; + // end copy export interface BaseApplicationCommandData {