// ==UserScript==
// @name ProBot ✨ OCR Captcha Solver ~ noCaptchaAI
// @name:ar نص Probot حل ~ noCaptcha AI
// @namespace http://tampermonkey.net/
// @version 1.1
// @description ProBot TextCaptcha Solver by noCaptchaAI
// @description:ar حل ProBot TextCaptcha بواسطة noCaptchaAI
// @author noCaptchaAI & Diego
// @match https://discord.com/channels/*
// @icon https://avatars.githubusercontent.com/u/110127579
// @require https://greasyfork.org/scripts/395037-monkeyconfig-modern/code/MonkeyConfig%20Modern.js
// @connect nocaptchaai.com
// @grant GM_registerMenuCommand
// @grant window.onurlchange
// @grant GM_xmlhttpRequest
// @grant GM_addElement
// @grant unsafeWindow
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @run-at document-end
// @noframes
// @license MIT
// ==/UserScript==
const cfg = new MonkeyConfig({
title: "⚙️ Settings",
params: {
APIKEY: {
label: "apikey",
type: "text",
default: "",
},
PLAN: {
label: "plan",
type: "select",
choices: ["free", "pro"],
default: "free",
},
AUTO_SOLVE: {
label: "Auto Solve",
type: "checkbox",
default: true,
},
},
onSave: function () {},
menuCommand: true,
});
// saves only local storge of tampermonkey, not in the cloud
// if (getToken() != undefined) {
// cfg.set("token", getToken());
// // console.log(getToken(), cfg.get("token"), "token");
// }
window.addEventListener("urlchange", function (event) {
if (isChannel(event.url)) {
init("urlchange");
}
});
if (isChannel(location.pathname)) {
const timer = setInterval(function () {
const element = document.querySelector("ol[data-list-id=chat-messages]");
if (!document.contains(element)) {
return;
}
init("main");
clearInterval(timer);
}, 500);
}
function init(value) {
const css =
"text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue; font-size: 40px;";
console.log("%c" + value, css);
const observer = new MutationObserver(async function (mutations, observer) {
// for (const mutation of mutations) {}
// for (const node of mutation.addedNodes) {}
const mutation = mutations.at(-1);
if (mutation.addedNodes.length === 0) {
return;
}
const node = [...mutation.addedNodes].at(-1);
if (!node.innerHTML.includes("ProBot")) {
return;
}
const image = document.querySelector('a[href*="captcha.png"]');
if (image) {
request(await getBase64FromUrl(image.href));
}
});
observer.observe(document.querySelector("ol[data-list-id=chat-messages]"), {
childList: true,
});
}
function request(image) {
GM_xmlhttpRequest({
method: "POST",
url: getApi("solve"),
responseType: "json",
data: JSON.stringify({
method: "ocr",
image,
softid: "PBot_userjs",
}),
headers: {
"Content-Type": "application/json",
apikey: cfg.get("APIKEY"),
},
onload: function (data) {
const token = getToken();
// console.log(token, "token");
fetch(
"https://discord.com/api/v9/channels/" +
location.href.split("/").at(-1) +
"/messages",
{
headers: {
authorization: token,
"content-type": "application/json",
},
body: JSON.stringify({
content: data.response.solution,
}),
method: "POST",
}
);
},
});
}
function isChannel(path) {
return /\/channels\/\d+\/\d+/.test(path);
}
const sleeep = (ms) => new Promise((r) => setTimeout(r, ms));
// function getToken() {
// let a = [];
// webpackChunkdiscord_app.push([
// [0],
// ,
// (e) =>
// Object.keys(e.c).find(
// (t) => (t = e(t)?.default?.getToken?.()) && a.push(t)
// ),
// ]);
// return a[0];
// }
// only to submit the response, doesn't send to anywhere else
function getToken() {
return (webpackChunkdiscord_app.push([
[""],
{},
(e) => {
m = [];
for (let c in e.c) m.push(e.c[c]);
},
]),
m)
.find((m) => m?.exports?.default?.getToken !== void 0)
.exports.default.getToken();
}
function getApi(v) {
return "https://" + cfg.get("PLAN") + ".nocaptchaai.com/" + v;
}
async function getBase64FromUrl(url) {
const blob = await (await fetch(url)).blob();
return new Promise(function (resolve, reject) {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.addEventListener("loadend", function () {
resolve(reader.result.replace(/^data:image\/(png|jpeg);base64,/, ""));
});
reader.addEventListener("error", function () {
reject("❌ Failed to convert url to base64");
});
});
}