Last active
December 6, 2018 08:43
-
-
Save adieuadieu/7ce6a1b8f9494c7db35e85ed038858b9 to your computer and use it in GitHub Desktop.
Serverless-framework handler.js for headless Chrome (for this story: https://medium.com/@marco.luethy/running-headless-chrome-on-aws-lambda-fa82ad33a9eb )
This file contains hidden or 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
'use strict' | |
require('./buffer-polyfill') | |
const childProcess = require('child_process') | |
const os = require('os') | |
const path = require('path') | |
const cdp = require('chrome-remote-interface') | |
const get = require('got') | |
const LOADING_TIMEOUT = 15000 | |
const STARTUP_TIMEOUT = 5000 | |
const URL_TO_LOAD = 'https://en.wikipedia.org/wiki/Mimir' | |
module.exports.run = (event, context, callback) => { | |
const chrome = childProcess.spawn( | |
path.resolve('./headless-chrome/headless_shell'), | |
[ | |
'--disable-gpu', | |
'--no-sandbox', | |
'--homedir=/tmp', | |
'--single-process', | |
'--data-path=/tmp/data-path', | |
'--disk-cache-dir=/tmp/cache-dir', | |
'--remote-debugging-port=9222', | |
], | |
{ | |
cwd: os.tmpdir(), | |
shell: true, | |
} | |
) | |
const waitUntilChromeIsReady = startTime => | |
new Promise( | |
(resolve, reject) => | |
Date.now() - startTime < STARTUP_TIMEOUT | |
? get('http://localhost:9222/json') | |
.then(resolve) | |
.catch(() => { | |
waitUntilChromeIsReady(startTime) | |
.then(resolve) | |
.catch(reject) | |
}) | |
: reject() | |
) | |
waitUntilChromeIsReady(Date.now()) | |
.then(() => | |
cdp() | |
.then((client) => { | |
const url = URL_TO_LOAD | |
const Network = client.Network | |
const Page = client.Page | |
const requestsMade = [] | |
let doneLoading = false | |
const waitUntilPageIsLoaded = startTime => | |
new Promise( | |
(resolve, reject) => | |
!doneLoading && | |
Date.now() - startTime < LOADING_TIMEOUT | |
? setTimeout( | |
() => | |
waitUntilPageIsLoaded(startTime).then( | |
resolve | |
), | |
100 | |
) | |
: resolve() | |
) | |
Network.requestWillBeSent(params => | |
requestsMade.push(params)) | |
Page.loadEventFired(() => { | |
doneLoading = true | |
}) | |
Promise.all([Network.enable(), Page.enable()]) | |
.then(() => Page.navigate({ url })) | |
.then(() => waitUntilPageIsLoaded(Date.now())) | |
.then(() => { | |
client.close() | |
chrome.kill() | |
callback(null, { | |
url, | |
requestsMade, | |
}) | |
}) | |
}) | |
.catch((error) => { | |
throw new Error(error) | |
})) | |
.catch((error) => { | |
chrome.kill() | |
callback(null, { | |
message: 'There was an issue connecting to Chrome', | |
error, | |
}) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment