From a309bb72c57e41bf5ab274001c8e8cdaab40522d Mon Sep 17 00:00:00 2001 From: MLTN Date: Sun, 12 Jul 2026 18:22:28 +0300 Subject: [PATCH] Enhance phone number validation and session handling Added validation for phone number input and improved error messages. Adjusted delays and refactored session handling logic for better performance. --- routes/pair.js | 176 +++++++++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 78 deletions(-) diff --git a/routes/pair.js b/routes/pair.js index dc9ac18..9886565 100644 --- a/routes/pair.js +++ b/routes/pair.js @@ -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 { @@ -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, @@ -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); @@ -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) { @@ -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); } } } @@ -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; @@ -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" });