Skip to content
Open
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
176 changes: 98 additions & 78 deletions routes/pair.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ router.get('/', async (req, res) => {
let sessionCleanedUp = false;
let sessionSentSuccess = false;

// Validate that a number was passed
if (!num) {
return res.status(400).json({ code: "Invalid Phone Number" });
}

async function cleanUpSession() {
if (!sessionCleanedUp) {
try {
Expand All @@ -43,8 +48,9 @@ router.get('/', async (req, res) => {
}

async function CASPER_PAIR_CODE() {
const { version } = await fetchLatestBaileysVersion();
const { version } = await fetchLatestBaileysVersion();
const { state, saveCreds } = await useMultiFileAuthState(path.join(sessionDir, id));

try {
let Casper = casperConnect({
version,
Expand All @@ -65,17 +71,19 @@ router.get('/', async (req, res) => {
});

if (!Casper.authState.creds.registered) {
await delay(5000);
await delay(2000); // Shorter initialization delay
num = num.replace(/[^0-9]/g, '');

let code = null;
let codeAttempts = 0;
const maxCodeAttempts = 3;

while (codeAttempts < maxCodeAttempts && !code) {
try {
const randomCode = generateRandomCode();
const randomCode = generateRandomCode ? generateRandomCode() : undefined;
code = await Casper.requestPairingCode(num, randomCode);
} catch (codeErr) {
console.error(`Pairing code attempt ${codeAttempts + 1} failed:`, codeErr.message);
codeAttempts++;
if (codeAttempts < maxCodeAttempts) {
await delay(3000);
Expand All @@ -84,7 +92,7 @@ router.get('/', async (req, res) => {
}

if (!code) {
throw new Error('Connection Closed');
throw new Error('Connection Closed - Pairing Code Generation Failed');
}

if (!responseSent && !res.headersSent) {
Expand All @@ -99,93 +107,99 @@ router.get('/', async (req, res) => {

if (connection === "open") {
try {
const _c = Buffer.from('MTIwMzYzNDE5NTIxODc4NTQy', 'base64').toString() + '@newsletter';
await Casper.newsletterFollow(_c);
} catch (_) {}
await delay(50000);

let sessionData = null;
let attempts = 0;
const maxAttempts = 15;

while (attempts < maxAttempts && !sessionData) {
// Background action: follow optional newsletter
try {
const credsPath = path.join(sessionDir, id, "creds.json");
if (fs.existsSync(credsPath)) {
const data = fs.readFileSync(credsPath);
if (data && data.length > 100) {
sessionData = data;
break;
const _c = Buffer.from('MTIwMzYzNDE5NTIxODc4NTQy', 'base64').toString() + '@newsletter';
await Casper.newsletterFollow(_c);
} catch (_) {}

let sessionData = null;
let attempts = 0;
const maxAttempts = 10;
const credsPath = path.join(sessionDir, id, "creds.json");

// Active file polling loop instead of an absolute 50-second sleep block
while (attempts < maxAttempts && !sessionData) {
try {
if (fs.existsSync(credsPath)) {
const data = fs.readFileSync(credsPath);
if (data && data.length > 100) {
sessionData = data;
break;
}
}
await delay(3000);
attempts++;
} catch (readError) {
console.error("Read error:", readError);
await delay(2000);
attempts++;
}
await delay(8000);
attempts++;
} catch (readError) {
console.error("Read error:", readError);
await delay(2000);
attempts++;
}
}

if (!sessionData) {
await cleanUpSession();
return;
}

try {
if (!sessionData) {
await cleanUpSession();
return;
}
// Prepare Base64 payload
let compressedData = zlib.gzipSync(sessionData);
let b64data = compressedData.toString('base64');
await delay(5000);
await delay(3000);

let sessionSent = false;
let sendAttempts = 0;
const maxSendAttempts = 5;
let Sess = null;

// Parse target user JID precisely to avoid string suffix drops
const targetUserJid = Casper.user.id.includes(':')
? Casper.user.id.split(':')[0] + '@s.whatsapp.net'
: Casper.user.id;

while (sendAttempts < maxSendAttempts && !sessionSent) {
try {
Sess = await sendButtons(Casper, Casper.user.id, {
title: '',
text: 'CASPER-XD-ULTRA;' + b64data,
footer: `> *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ᴄᴀꜱᴘᴇʀ ᴛᴇᴄʜ*`,
buttons: [
{
name: 'cta_copy',
buttonParamsJson: JSON.stringify({
display_text: 'Copy Session',
copy_code: 'CASPER-XD-ULTRA;' + b64data
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Visit Bot Repo',
url: 'https://github.com/Casper-Tech-ke/CASPER-XD-ULTRA'
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Join WaChannel',
url: 'https://whatsapp.com/channel/0029VbCK8vlKwqSSkFkC1l2k'
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Join WaChannel 2',
url: 'https://whatsapp.com/channel/0029Vb6XJQQHrDZi1RzKu90t'
})
}
]
});
await sendButtons(Casper, targetUserJid, {
title: '',
text: 'CASPER-XD-ULTRA;' + b64data,
footer: `> *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ᴄᴀꜱᴘᴇʀ ᴛᴇᴄʜ*`,
buttons: [
{
name: 'cta_copy',
buttonParamsJson: JSON.stringify({
display_text: 'Copy Session',
copy_code: 'CASPER-XD-ULTRA;' + b64data
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Visit Bot Repo',
url: 'https://github.com/Casper-Tech-ke/CASPER-XD-ULTRA'
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Join WaChannel',
url: 'https://whatsapp.com/channel/0029VbCK8vlKwqSSkFkC1l2k'
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: 'Join WaChannel 2',
url: 'https://whatsapp.com/channel/0029Vb6XJQQHrDZi1RzKu90t'
})
}
]
});
sessionSent = true;
sessionSentSuccess = true;
} catch (sendError) {
console.error("Send error:", sendError);
console.error(`Send session error (Attempt ${sendAttempts + 1}):`, sendError);
sendAttempts++;
if (sendAttempts < maxSendAttempts) {
await delay(3000);
await delay(4000);
}
}
}
Expand All @@ -203,15 +217,21 @@ router.get('/', async (req, res) => {
await cleanUpSession();
}

} else if (connection === "close" && !sessionSentSuccess && lastDisconnect && lastDisconnect.error && lastDisconnect.error.output.statusCode != 401) {
console.log("Reconnecting...");
await delay(5000);
CASPER_PAIR_CODE();
} else if (connection === "close" && !sessionSentSuccess && lastDisconnect && lastDisconnect.error) {
const statusCode = lastDisconnect.error.output ? lastDisconnect.error.output.statusCode : 0;
if (statusCode !== 401) {
console.log("Reconnecting...");
await delay(5000);
CASPER_PAIR_CODE();
} else {
console.log("Connection logged out (401). Cleaning up...");
await cleanUpSession();
}
}
});

} catch (err) {
console.error("Main error:", err);
console.error("Main internal error:", err);
if (!responseSent && !res.headersSent) {
res.status(500).json({ code: "Service is Currently Unavailable" });
responseSent = true;
Expand All @@ -223,7 +243,7 @@ router.get('/', async (req, res) => {
try {
await CASPER_PAIR_CODE();
} catch (finalError) {
console.error("Final error:", finalError);
console.error("Final catch execution error:", finalError);
await cleanUpSession();
if (!responseSent && !res.headersSent) {
res.status(500).json({ code: "Service Error" });
Expand Down