title: GitHub MFA Automation | Scrapeless Scraping Browser
description: Scrapeless Browser + Signal CDP के साथ TOTP और Email OTP सपोर्ट का उपयोग करके GitHub टू-फैक्टर ऑथेंटिकेशन को स्वचालित करें।
keywords: GitHub MFA, GitHub 2FA, TOTP ऑटोमेशन, Email OTP, Signal CDP, Scraping Browser
GitHub MFA Automation
परिचय
GitHub लॉगिन को स्वचालित करने में सबसे बड़ी चुनौती है टू-फैक्टर ऑथेंटिकेशन (2FA)। चाहे वह ऑथेंटिकेटर ऐप (TOTP) हो या Email OTP, पारंपरिक ऑटोमेशन प्रक्रियाएँ आमतौर पर इस चरण पर फंस जाती हैं क्योंकि:
- सत्यापन कोड को स्वचालित रूप से प्राप्त करने में असमर्थता
- कोड को वास्तविक समय में सिंक्रोनाइज़ करने में असमर्थता
- ऑटोमेशन के माध्यम से कोड को स्वचालित रूप से इनपुट करने में असमर्थता
- ब्राउज़र वातावरण पर्याप्त यथार्थवादी नहीं होते, जिससे GitHub की सुरक्षा जाँच सक्रिय हो जाती है
यह लेख दिखाता है कि Scrapeless Browser + Signal CDP का उपयोग करके GitHub 2FA वर्कफ़्लो को पूरी तरह से स्वचालित कैसे बनाया जाए, जिसमें शामिल हैं:
- केस 1: GitHub 2FA (Authenticator / TOTP ऑटो-जनरेशन)
- केस 2: GitHub 2FA (Email OTP ऑटो-लिसनिंग)
हम प्रत्येक केस के लिए पूर्ण वर्कफ़्लो समझाएंगे और दिखाएंगे कि एक स्वचालित सिस्टम में लॉगिन स्क्रिप्ट को सत्यापन कोड लिसनर के साथ कैसे समन्वयित किया जाए।
केस 1: GitHub 2FA (Authenticator OTP मोड)
GitHub का TOTP (Time-based One-Time Password) मेकनिज्म ऑटोमेशन परिदृश्यों के लिए आदर्श है। Scrapeless Browser + Signal CDP के उपयोग से, ब्राउज़र स्वतः निम्न कार्य कर सकता है:
- जब यह 2FA पेज तक पहुँचता है तो एक इवेंट ट्रिगर करे
- OTP कोड जेनरेट करे
- कोड को स्वचालित रूप से भर दे
- लॉगिन पूरा करे
पारंपरिक Email/SMS OTP की तुलना में, TOTP प्रदान करता है:
- बाहरी निर्भरताओं के बिना स्थानीय रूप से जनरेट कोड
- तेज़ और स्थिर कोड जेनरेशन
- अतिरिक्त API की आवश्यकता नहीं
- बिना मानव हस्तक्षेप के पूरी तरह ऑटोमेटेबल
लागू परिदृश्य:
- Google Authenticator / Authy / 1Password का उपयोग करने वाले GitHub अकाउंट्स
- 2FA पेज पाथ:
/sessions/two-factor/appया/sessions/two-factor/webauthn
वीडियो

चरण 1: Scrapeless Browser से कनेक्ट करें
इस चरण में, हम Scrapeless Browser के साथ पूर्ण-डुप्लेक्स WebSocket कनेक्शन स्थापित करते हैं:
import puppeteer from 'puppeteer-core';
const query = new URLSearchParams({
token: "",
proxyCountry: "ANY",
sessionRecording: true,
sessionTTL: 900,
sessionName: "Data Scraping",
});
const connectionURL = `wss://browser.scrapeless.com/api/v2/browser?${query.toString()}`;
const browserWSEndpoint = connectionURL;
const browser = await puppeteer.connect({ browserWSEndpoint });
console.log("✅ Scrapeless Browser से कनेक्टेड");फायदे:
- क्लाउड में असली क्रोम ब्राउज़र जिसमें मजबूत एंटी-डिटेक्शन है
- स्थानीय संसाधनों का उपभोग नहीं करता
- ऑटोमैटिक प्रॉक्सी, पर्सिस्टेंस, और सेशन रिकॉर्डिंग
- बड़े पैमाने पर ऑटोमेटेड लॉगिन वर्कफ़्लो का विश्वसनीय क्रियान्वयन
चरण 2: MFA मैनेजर + TOTP प्रोवाइडर इनिशियलाइज़ करें
MFA Signal CDP द्विदिश संचार के माध्यम से नियंत्रण में होता है, जो:
- 2FA पेज डिटेक्ट होने पर स्वतः
mfa_code_requestभेजता है - TOTP कोड जनरेट करता है
mfa_code_responseके माध्यम से कोड लौटाता है- लॉगिन रिजल्ट इवेंट भेजता है
import { authenticator } from 'otplib';
const TOTP_SECRETS = {
'github': 'secret-code',
'default': 'secret-code'
};
authenticator.options = {
digits: 6,
step: 30,
window: 1
};चरण 3: MFA मैनेजर बनाएं
यहाँ हम Signal CDP के साथ संवाद को संभालने के लिए एक केंद्रीकृत MFA मैनेजर बनाते हैं:
mfa_code_requestट्रिगर करें- प्रतीक्षा करें और सत्यापन कोड प्राप्त करें (
mfa_code_response) - कोड को GitHub लॉगिन प्रक्रिया को वापस करें
- अंतिम लॉगिन परिणाम इवेंट भेजें
class MFAManager {
constructor() {
this.client = null;
}
setClient(client) {
this.client = client;
}
async sendMFARequest(username, provider = 'github') {
const requestData = {
type: 'mfa_required',
provider,
username,
timestamp: new Date().toISOString(),
service: 'github_2fa'
};
return await this.client.send('Signal.send', {
event: 'mfa_code_request',
data: JSON.stringify(requestData)
});
}
async waitForMFACode(timeout = 120000) {
const result = await this.client.send('Signal.wait', {
event: 'mfa_code_response',
timeout
});
if (result.status === 200 && result.data) {
return JSON.parse(result.data).code;
} else if (result.status === 408) {
throw new Error('MFA कोड की प्रतीक्षा का समय समाप्त हुआ');
} else {
throw new Error(`Signal wait विफल, स्थिति: ${result.status}`);
}
}
async sendMFAResponse(code, username) {
const responseData =
console.log("🚀 गिटहब लॉगिन प्रक्रिया शुरू हो रही है...");
const githubCredentials = {
username: "****@gmail.com",
password: "******",
twoFactorCode: null
};
const pages = await browser.pages();
page = pages.length > 0 ? pages[0] : await browser.newPage();
page.setDefaultTimeout(30000);
page.setDefaultNavigationTimeout(30000);
console.log('📱 गिटहब लॉगिन पेज पर जा रहे हैं...');
await page.goto('https://github.com/login', {waitUntil: 'networkidle2'});
// लॉगिन फॉर्म लोड होने का इंतजार करें
await page.waitForSelector('#login_field', {timeout: 10000});
console.log('🔑 उपयोगकर्ता नाम और पासवर्ड टाइप कर रहे हैं...');
await page.type('#login_field', githubCredentials.username);
await page.type('#password', githubCredentials.password);
// साइन इन बटन क्लिक करें
console.log('🖱️ साइन इन बटन क्लिक कर रहे हैं...');
await page.click('input[type="submit"][value="Sign in"]');
// waitForTimeout के बजाय setTimeout का उपयोग करें
console.log('⏳ पेज प्रतिक्रिया का इंतजार कर रहे हैं...');
await new Promise(resolve => setTimeout(resolve, 3000));
// जांचें कि क्या ईमेल सत्यापन (2FA) आवश्यक है
const currentUrl = page.url();
console.log(`🔍 वर्तमान URL: ${currentUrl}`);
if (currentUrl.includes('/sessions/verified-device')) {
console.log('🔐 ईमेल सत्यापन आवश्यक मिला, सत्यापन कोड का इंतजार कर रहे हैं...');
const client = await page.target().createCDPSession();
// ईमेल सत्यापन कोड आवश्यकता का संकेत भेजें
await client.send('Signal.send', {
event: 'github_2fa_required',
data: JSON.stringify({
status: '2fa_required',
timestamp: new Date().toISOString()
})
});
// ईमेल सत्यापन कोड प्राप्त करने के लिए प्रतीक्षा करें
console.log('⏳ ईमेल सत्यापन कोड का इंतजार कर रहे हैं...');
const twoFactorResult = await client.send('Signal.wait', {
event: 'github_2fa_code',
timeout: 120000
});
if (twoFactorResult.status === 200 && twoFactorResult.data) {
const twoFactorData = JSON.parse(twoFactorResult.data);
githubCredentials.twoFactorCode = twoFactorData.code;
console.log(`✅ ईमेल सत्यापन कोड प्राप्त हुआ: ${githubCredentials.twoFactorCode}, कोड दर्ज कर रहे हैं...`);
// सुनिश्चित करें कि हम अभी भी सत्यापन पेज पर हैं
if (!page.url().includes('/sessions/verified-device')) {
console.log('⚠️ पेज ने नेविगेट किया है, सत्यापन अब आवश्यक नहीं हो सकता');
return;
}
// सत्यापन कोड दर्ज करें
console.log('⌨️ सत्यापन कोड दर्ज कर रहे हैं...');
await page.$eval('#otp', (input, code) => {
input.value = '';
}, githubCredentials.twoFactorCode);
await page.type('#otp', githubCredentials.twoFactorCode);
console.log(`✅ सत्यापन कोड ${githubCredentials.twoFactorCode} दर्ज किया गया है`);
// सत्यापित करें बटन क्लिक करें
console.log('🖱️ सत्यापित करें बटन क्लिक कर रहे हैं...');
try {
await page.evaluate(() => {
const button = document.querySelector('button[type="submit"]');
if (button) button.click();
});
console.log('✅ सत्यापित करें बटन क्लिक किया गया, पेज प्रतिक्रिया का इंतजार कर रहे हैं...');
await new Promise(resolve => setTimeout(resolve, 5000));
} catch (clickError) {
console.log('⚠️ बटन क्लिक करने में समस्या:', clickError.message);
}
// लॉगिन परिणाम जांचें
await new Promise(resolve => setTimeout(resolve, 3000));
const finalUrl = page.url();
console.log(`🔍 अंतिम URL: ${finalUrl}`);
const isLoggedIn = !finalUrl.includes('/sessions/verified-device') &&
!finalUrl.includes('/login') &&
(finalUrl.includes('github.com') || finalUrl === 'https://github.com/');
// लॉगिन परिणाम संकेत भेजें
if (client) {
await client.send('Signal.send', {
event: 'github_login_result',
data: JSON.stringify({
success: isLoggedIn,
username: githubCredentials.username,
url: finalUrl,
twoFactorCode: githubCredentials.twoFactorCode,
timestamp: new Date().toISOString()
})
});
}
if (isLoggedIn) {
console.log('🎉 गिटहब लॉगिन सफल!');
try {
await page.goto('https://github.com/', {
waitUntil: 'networkidle2',
timeout: 10000
});
console.log('✅ गिटहब होमपेज सफलतापूर्वक एक्सेस किया गया');
} catch (profileError) {
console.log('⚠️ होमपेज एक्सेस करने में समस्या:', profileError.message);
}
} else {
console.log('❌ ईमेल सत्यापन विफल, लॉगिन असफल');
console.log('🔍 वर्तमान पेज शीर्षक:', await page.title());
}
} else {
console.log('❌ ईमेल सत्यापन कोड के लिए प्रतीक्षा समय समाप्त हो गया');
}
} else if (currentUrl.includes('github.com') && !currentUrl.includes('/login')) {
// कोई ईमेल सत्यापन आवश्यक नहीं
console.log('✅ लॉगिन सफल (कोई ईमेल सत्यापन आवश्यक नहीं)');
const client = await page.target().createCDPSession();
await client.send('Signal.send', {
event: 'github_login_result',
data: JSON.stringify({
success: true,
username: githubCredentials.username,
url: currentUrl,
timestamp: new Date().toISOString()
})
});
} else {
console.log('❌ लॉगिन विफल, अभी भी लॉगिन पेज पर हैं');
console.log('🔍 वर्तमान पेज शीर्षक:', await page.title());
}
// सत्र को कुछ समय के लिए बनाए रखें
console.log('⏳ कनेक्शन 5 सेकंड के लिए बनाए रखा जा रहा है...');
await new Promise(resolve => setTimeout(resolve, 5000));
} catch (error) {
console.error('❌ गिटहब लॉगिन प्रक्रिया विफल:', error);
try {
const pages = await browser.pages();
const currentPage = pages.length > 0 ? pages[0] : page;
if (currentPage) {
const errorClient = await currentPage.target().createCDPSession();
await errorClient.send('Signal.send', {
event: 'github_login_error',
data: JSON.stringify({
error: error.message,
timestamp: new Date().toISOString()
})
});
}
} catch (signalError) {
console.error('❌ त्रुटि संकेत भेजने में विफल:', signalError);
}
} finally {
if (browser) await browser.close();
console.log('🔚 गिटहब लॉगिन स्क्रिप्ट समाप्त हुई');
}
}
// स्क्रिप्ट चलाएं
githubLoginWith2FA().catch(console.error);
- जब ऊपर दी गई स्क्रिप्ट सत्यापन कोड के लिए पेज पर पहुंचती है, तो तुरंत यह ईमेल लिस्नर स्क्रिप्ट चलाएं, जो नवीनतम कोड को मुख्य स्क्रिप्ट को भेजेगी ताकि सत्यापन पूरा हो सके।
import Imap from 'imap';
import {simpleParser} from 'mailparser';
const CONFIG = {
imap: {
user: "****@gmail.com",
password: "****",
host: "mail.privateemail.com",
port: 993,
tls: true,
tlsOptions: {rejectUnauthorized: false}
},
signal: {
baseUrl: "https://browser.scrapeless.com",
apiKey: "api-key"
},
checkInterval: 5000,
maxWaitTime: 120000
};
class EmailListener {
constructor() {
this.imap = null;
this.isListening = false;
this.sessionId = null;
}
async start(sessionId) {
console.log('ईमेल लिस्नर शुरू हो रहा है...');
this.sessionId = sessionId;
try {
await this.connectIMAP();
const code = await this.listenForCode();
if (code) {
console.log(`कोड मिला: ${code}`);
await this.sendSignal('github_2fa_code', {code});
console.log('कोड ब्राउज़र को भेज दिया गया');
} else {
console.log('कोई कोड नहीं मिला (समय समाप्त)');
await this.sendSignal('email_listener_timeout', {status: 'timeout'});
}
} catch (error) {
console.error('लिस्नर त्रुटि:', error.message || error);
} finally {
await this.cleanup();
}
}
connectIMAP() {
return new Promise((resolve, reject) => {
this.imap = new Imap(CONFIG.imap);
this.imap.once('ready', () => {
console.log('IMAP कनेक्ट हो गया');
resolve();
});
this.imap.once('error', reject);
this.imap.connect();
});
}
async listenForCode() {
console.log('गिटहब सत्यापन कोड के लिए सुन रहे हैं...');
this.isListening = true;
const startTime = Date.now();
while (this.isListening && (Date.now() - startTime) < CONFIG.maxWaitTime) {
try {
const code = await this.checkEmails();
if (code) return code;
await new Promise(resolve => setTimeout(resolve, CONFIG.checkInterval));
} catch (error) {
console.error('checkEmails विफल:', error.message || error);
await new Promise(resolve => setTimeout(resolve, 10000));
}
}
return null;
}
checkEmails() {
return new Promise((resolve, reject) => {
this.imap.openBox('INBOX', false, (err, box) => {
if (err) return reject(err);
const criteria = ['UNSEEN', ['FROM', '****@github.com']];
this.imap.search(criteria, (err, results) => {
if (err) return reject(err);
if (!results || results.length === 0) return resolve(null);
this.processEmails(results, resolve, reject);
});
});
});
}
processEmails(results, resolve, reject) {
const fetcher = this.imap.fetch(results, {
bodies: ['TEXT'],
markSeen: true
});
let processed = 0;
let foundCode = null;
fetcher.on('message', (msg) => {
let buffer = '';
msg.on('body', (stream) => {
stream.on('data', (chunk) => buffer += chunk.toString('utf8'));
});
msg.once('end', async () => {
try {
const mail = await simpleParser(buffer);
const code = this.extractCode(mail.text || '');
if (code) foundCode = code;
} catch (error) {
console.error('मेल पार्स करने में विफल:', error);
}
processed++;
if (processed === results.length) resolve(foundCode);
});
});
fetcher.once('error', reject);
}
extractCode(text) {
const patterns = [
/verification code:?\s*(\d{6})/i,
/verification code:?\s*(\d{6})/i,
/code:?\s*(\d{6})/i,
/GitHub verification code:?\s*(\d{6})/i
];
for (const pattern of patterns) {
const match = text.match(pattern);
if (match) return match[1];
}
const digitMatch = text.match(/\b\d{6}\b/);
return digitMatch ? digitMatch[0] : null;
}
// HTTP के माध्यम से सिग्नल भेजें, sessionId पैरामीटर के रूप में
async sendSignal(event, data, sessionId = this.sessionId) {
if (!sessionId) throw new Error('सेशन ID उपलब्ध नहीं है');
try {
const url = `${CONFIG.signal.baseUrl}/browser/${sessionId}/signal/send`;
const response = await fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
'token': CONFIG.signal.apiKey
},
body: JSON.stringify({event, data})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
console.log('सिग्नल सफलतापूर्वक भेजा गया:', result);
return result;
} catch (err) {
console.error('HTTP के माध्यम से सिग्नल भेजने में विफल:', err);
throw err;
}
}
async cleanup() {
this.isListening = false;
if (this.imap) {
try {
this.imap.end();
console.log('IMAP कनेक्शन बंद किया गया');
} catch (e) {
console.error('IMAP बंद करते समय त्रुटि:', e);
}
}
this.sessionId = null;
}
}
const listener = new EmailListener();
listener.start({taskId}).then(); // पहले चरण से taskId के साथ बदलें
ऊपर दिए गए दो गिटहब लॉगिन उदाहरणों के माध्यम से, हम दिखाते हैं कि कैसे उद्यम वातावरण में कुशल और स्थिर स्वचालित लॉगिन प्राप्त किया जा सकता है, जो दो सामान्य 2FA मोड्स को कवर करता है: TOTP और ईमेल सत्यापन कोड। Scrapeless Browser + Signal CDP का उपयोग करके, आप असली ब्राउज़र संचालन कर सकते हैं, उपयोगकर्ता व्यवहार को सटीक रूप से अनुकरण कर सकते हैं, और MFA सिस्टम तथा ईमेल लिस्नर्स के साथ रियल टाइम में इंटरैक्ट कर सकते हैं ताकि सत्यापन कोड स्वतः प्राप्त और सबमिट किया जा सके। चाहे स्वचालित लॉगिन वर्कफ़्लोज़ विकसित करना हो, CI/CD सिस्टम के साथ एकीकृत करना हो, या आंतरिक उद्यम खातों का प्रबंधन करना हो, यह समाधान लॉगिन सफलता दर को काफी बढ़ा सकता है, मैनुअल हस्तक्षेप को कम कर सकता है, और पूर्ण परिचालन लेखा परीक्षा और निगरानी प्रदान कर सकता है।