-
-
Save hmmhmmhm/289c46b333d38aa8b3c5352fa4f2a4ff to your computer and use it in GitHub Desktop.
Login to Google Account via Puppeteer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import puppeteer from 'puppeteer-extra'; | |
import pluginStealth from 'puppeteer-extra-plugin-stealth'; // Use v2.4.5 instead of latest | |
import * as readline from 'readline'; | |
puppeteer.use(pluginStealth()); | |
// Use '-h' arg for headful login. | |
const headless = !process.argv.includes('-h'); | |
// Prompt user for email and password. | |
const prompt = (query: string, hidden = false): Promise<string> => | |
new Promise((resolve, reject) => { | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
try { | |
if (hidden) { | |
const stdin = process.openStdin(); | |
process.stdin.on('data', (char: string) => { | |
char = char + ''; | |
switch (char) { | |
case '\n': | |
case '\r': | |
case '\u0004': | |
stdin.pause(); | |
break; | |
default: | |
process.stdout.clearLine(0); | |
readline.cursorTo(process.stdout, 0); | |
process.stdout.write(query + Array(rl.line.length + 1).join('*')); | |
break; | |
} | |
}); | |
} | |
rl.question(query, (value) => { | |
resolve(value); | |
rl.close(); | |
}); | |
} catch (err) { | |
reject(err); | |
} | |
}); | |
// Launch puppeteer browser. | |
puppeteer.launch({ headless: headless }).then(async (browser: any) => { | |
console.log('Opening chromium browser...'); | |
const page = await browser.newPage(); | |
const pages = await browser.pages(); | |
// Close the new tab that chromium always opens first. | |
pages[0].close(); | |
await page.goto('https://accounts.google.com/signin/v2/identifier', { waitUntil: 'networkidle2' }); | |
if (headless) { | |
// Only needed if sign in requires you to click 'sign in with google' button. | |
// await page.waitForSelector('button[data-test="google-button-login"]'); | |
// await page.waitFor(1000); | |
// await page.click('button[data-test="google-button-login"]'); | |
// Wait for email input. | |
await page.waitForSelector('#identifierId'); | |
let badInput = true; | |
// Keep trying email until user inputs email correctly. | |
// This will error due to captcha if too many incorrect inputs. | |
while (badInput) { | |
const email = await prompt('Email or phone: '); | |
await page.type('#identifierId', email); | |
await page.waitFor(1000); | |
await page.keyboard.press('Enter'); | |
await page.waitFor(1000); | |
badInput = await page.evaluate(() => document.querySelector('#identifierId[aria-invalid="true"]') !== null); | |
if (badInput) { | |
console.log('Incorrect email or phone. Please try again.'); | |
await page.click('#identifierId', { clickCount: 3 }); | |
} | |
} | |
const password = await prompt('Enter your password: ', true); | |
console.log('Finishing up...'); | |
// Wait for password input | |
await page.type('input[type="password"]', password); | |
await page.waitFor(1000); | |
await page.keyboard.press('Enter'); | |
// For headless mode, 2FA needs to be handled here. | |
// Login via gmail app works autmatically. | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"displayName": "Puppeteer Google Login", | |
"name": "puppeteer-google-login", | |
"version": "1.0.0", | |
"description": "Login to your google account using puppeteer", | |
"main": "dist/login.js", | |
"scripts": { | |
"clean": "rimraf ./dist ./coverage", | |
"build": "rimraf ./dist ./coverage && tsc" | |
}, | |
"engines": { | |
"node": ">=10" | |
}, | |
"files": [ | |
"dist/**/*" | |
], | |
"dependencies": { | |
}, | |
"devDependencies": { | |
"@types/node": "14.0.11", | |
"@types/puppeteer": "^3.0.0", | |
"puppeteer": "^3.3.0", | |
"puppeteer-extra": "^3.1.9", | |
"puppeteer-extra-plugin-stealth": "^2.4.5", | |
"rimraf": "^3.0.2", | |
"typescript": "^3.8.3" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"compilerOptions": { | |
"target": "ES2018", | |
"module": "commonjs", | |
"lib": [ | |
"ES2015", | |
"ES2016", | |
"ES2017", | |
"ES2018", | |
"dom" | |
], | |
"sourceMap": true, | |
"rootDir": "src", | |
"outDir": "dist", | |
"allowJs": true, | |
"strict": true, | |
"esModuleInterop": true, | |
"forceConsistentCasingInFileNames": true | |
}, | |
"include": [ | |
"src" | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment