Socket
Socket
Sign inDemoInstall

google-shopping-list

Package Overview
Dependencies
69
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.1 to 1.0.2

lib/logger.js

178

index.js

@@ -1,54 +0,142 @@

const puppeteer = require('puppeteer');
const puppeteer = require('puppeteer'),
fs = require('fs-extra'),
logger = require('./lib/logger');
to = require('./lib/to');
const ERROR_CHECK = 'body > div > div.main.content.clearfix > div',
USERNAME_SELECTOR = '#Email',
EMAIL_NEXT_BUTTON = '#next',
PASSWORD_SELECTOR = '#Passwd',
PASSWORD_NEXT_BUTTON = '#signIn',
SHOPPINGLIST_ITEMS = '.listItemTitle';
let exp = module.exports;
exp.getList = function(creds) {
return new Promise((resolve,reject) => {
exp.getList = async (creds, options = { cookies: false }) => {
let err, list, browser, page;
if(!creds) {
reject(new Error('Credentials not supplied'));
} else if(!('email' in creds)) {
reject(new Error('Email not supplied'));
} else if (!('password' in creds)) {
reject(new Error('Password not supplied'));
} else {
get();
if(!creds) {
return Error('Credentials not supplied');
} else if(!('email' in creds)) {
return Error('Email not supplied');
} else if (!('password' in creds)) {
return Error('Password not supplied');
}
// Turn headless to false to debug
[err, browser] = await to( puppeteer.launch({ headless: true }) );
if(err) return Error("Unable to launch the browser");
[err, page] = await to( browser.newPage() );
if(err) return Error("Unable to create a new page");
// Have to set this because some pages display differently for Headless Chrome
[err] = await to( page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/65.0.3312.0 Safari/537.36'));
if(err) return Error("Unable to set the user agent");
// If cookies option is enabled
if(options.cookies) {
let loadedCookies;
[err, loadedCookies] = await to( loadCookies() );
if(err) logger.verbose("No cookie file.")
if(loadedCookies) {
if(creds.email in loadedCookies) { // Check cookies file contains cookies for the specified email if true, set cookies
[err] = await to( page.setCookie(...loadedCookies[creds.email]) );
if(err) logger.Error("Unable to set cookies in browser");
}
}
}
function get() {
const ERROR_CHECK = 'body > div > div.main.content.clearfix > div'
const USERNAME_SELECTOR = '#Email';
const EMAIL_NEXT_BUTTON = '#next';
const PASSWORD_SELECTOR = '#Passwd';
const PASSWORD_NEXT_BUTTON = '#signIn';
const SHOPPINGLIST_ITEMS = '.listItemTitle';
[err] = await to( page.goto('https://shoppinglist.google.com', {waitUntil: 'domcontentloaded'}) );
if(err) return Error("Unable to go to url https://shoppinglist.google.com");
(async () => {
const browser = await puppeteer.launch({
headless: true // Turn this to false to debug
});
const page = await browser.newPage();
await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/65.0.3312.0 Safari/537.36') // Have to set this because some pages display differently for Headless Chrome
await page.goto('https://shoppinglist.google.com', {waitUntil: 'networkidle0'});
await page.click(USERNAME_SELECTOR);
await page.keyboard.type(creds.email);
await page.click(EMAIL_NEXT_BUTTON);
await page.waitForNavigation();
await page.keyboard.type(creds.password);
await page.click(PASSWORD_NEXT_BUTTON);
await page.waitForNavigation({waitUntil: 'networkidle0'});
logger.verbose("Go to https://shoppinglist.google.com")
let list = await page.evaluate(selector => {
let items = [];
let allItems = document.querySelectorAll(selector);
allItems.forEach(res => items.push(res.innerHTML)); // Must use a forEach as it is a nodeList not an array, convert to array
items.pop(); // Removes last element from array as it is not a list item
return items;
}, SHOPPINGLIST_ITEMS)
// If you are not logged in google redirects you to a different url
if(page.url() !== 'https://shoppinglist.google.com/') {
logger.verbose("Not logged in")
await logIn(page, creds);
}
await browser.close();
logger.verbose("Logged in")
resolve(list);
})();
}
})
}
[err] = await to( page.waitFor(SHOPPINGLIST_ITEMS) );
if(err) return Error("Unable to see the shopping list");
logger.verbose("Found the shopping list");
if(options.cookies) { // If cookies option is enabled
const cookies = await page.cookies();
await saveCookies(creds.email, cookies);
}
[err, list] = await to( page.evaluate(selector => {
let items = [];
let allItems = document.querySelectorAll(selector);
allItems.forEach(res => items.push(res.innerHTML.trim())); // Must use a forEach as it is a nodeList not an array, convert to array
items.pop(); // Removes last element from array as it is not a list item
return items;
}, SHOPPINGLIST_ITEMS) );
if(err) return Error("Unable to get the shopping list items");
await browser.close();
return list;
}
async function logIn(page, creds) {
[err] = await to( page.click(USERNAME_SELECTOR) );
if(err) return Error("Unable to find the username field");
logger.verbose('Clicked username');
[err] = await to( page.keyboard.type(creds.email) );
if(err) return Error("Unable to enter email");
logger.verbose('Entered email');
[err] = await to( page.click(EMAIL_NEXT_BUTTON) );
if(err) return Error(err, "Unable to click the next button");
logger.verbose('Click next button');
[err] = await to( page.waitFor(PASSWORD_NEXT_BUTTON) );
if(err) return Error(err, "Unable to see the password page");
logger.verbose("Sign in button seen");
[err] = await to( page.keyboard.type(creds.password) );
if(err) return Error(err, "Unable to enter the password");
logger.verbose("Entered password");
[err] = await to( page.click(PASSWORD_NEXT_BUTTON) );
if(err) return Error(err, "Unable to click the signin button");
logger.verbose("Clicked sign in");
}
async function saveCookies(email, cookies) {
cookies = {[email]: cookies}
const [err] = await to ( fs.writeJson('./cookies.json', cookies) )
if(err) {
logger.error(Error(err));
return Error(err);
}
logger.verbose('Cookies written to file');
return true;
}
async function loadCookies() {
const [err, cookies] = await to ( fs.readJson('./cookies.json') )
if(err) {
logger.error(Error(err));
return Error(err);
}
logger.verbose('Cookies read from file');
return cookies;
}
{
"name": "google-shopping-list",
"version": "1.0.1",
"version": "1.0.2",
"description": "Scrapes the shopping list from shoppinglist.google.com as Google does not seem to have an API for this.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"start": "node index.js",
"test": "node test.js"
},

@@ -20,4 +21,6 @@ "repository": {

"dependencies": {
"puppeteer": "^1.0.0"
"fs-extra": "^5.0.0",
"puppeteer": "^1.17.0",
"winston": "^3.2.1"
}
}
# Google Shopping List
Scrapes the shopping list from shoppinglist.google.com as Google does not seem to have an API for this.

@@ -25,9 +24,10 @@

**googleShoppingList.getList(credentials)**
**googleshoppinglist.getList(credentials[, options])**
* credentials <[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>
* email: <[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)> A Google email
* password: <[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)> The password for your google email
* `credentials` <[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>
* `email` <[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)> A Google email
* `password` <[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)> The password for your google email
* `options` <[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>
* `cookies` <[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)> Will store the cookies from the first session in a json file and use them in consequent connections until they expire. This speeds up the return. Defaults to `false`
* returns: <[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)>> Promise which resolves an array containing the list items

@@ -37,2 +37,2 @@

[puppeteer](https://www.npmjs.com/package/puppeteer)
[puppeteer](https://www.npmjs.com/package/puppeteer)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc