• Need to find way to find xpath or selector efficiently. Problem: npm Nodejs environment variables
npm install dotenv
// create .env file in your directory
// add variable
VARIABLE_NAME=value
 
require('dotenv').config();
const databaseUrl = process.env.DATABASE_URL;
 
// .env to gitignore
  • Google keep login didn’t work inchrome but it is working infirefox
const { chromium } = require('playwright');
 
const MarkdownIt = require('markdown-it');
 
const fs = require('fs');
 
const dotenv = require('dotenv').config();
 
const { firefox } = require('playwright');
 
const SELECTORS = require('./selectors.js');
 
  
 
const email = dotenv.parsed.USERNAME;
 
const password = dotenv.parsed.PASSWORD;
 
  
 
(async () => {
 
  const browser = await firefox.launch({ headless: false }); // await chromium.launch({ headless: false });
 
  const context = await browser.newContext();
 
  const page = await context.newPage();
 
  
 
  // Login to Google account
 
  await page.goto('https://keep.google.com/');
 
  await page.fill('#identifierId', email);
 
  await page.click('#identifierNext');
 
  await page.waitForSelector('input[type="password"]', { state: 'visible' });
 
  await page.fill('input[type="password"]', password);
 
  await page.click('#passwordNext');
 
  await page.waitForNavigation();
 
  
 
  // Wait for notes to load
 
  await page.waitForSelector(SELECTORS.NOTES, { state: 'visible' });
 
  
 
  // Get all notes
 
  const notes = await page.$$(SELECTORS.NOTES);
 
  
 
  // Convert notes to markdown
 
  const md = new MarkdownIt();
 
  let unamedPrefix = 'No Title-';
 
  let unnamedCount = 0;
 
  let index = 0;
 
  for (const note of notes) {
 
    if (index === 0) {
 
      index++;
 
      continue; // find note is empty, it is block to create new note
 
    }
 
  
 
    let title = await note.$eval(SELECTORS.NOTE_TITLE, el => el.textContent);
 
    const content = await note.$eval(SELECTORS.NOTE_TITLE, el => el.textContent);
 
    let markdown = `# ${title}\n\n${md.render(content)}\n\n`;
 
    markdown = stripHtml(markdown);
 
    if (!title) {
 
      title = unamedPrefix + unnamedCount;
 
      unnamedCount++;
 
    }
 
    fs.writeFileSync(`notes/${title}.md`, markdown);
 
    // await deleteNote(note, page);
 
  }
 
  
 
  await browser.close();
 
})();
 
  
 
/** This is taking too much time, google has some way to not make it clickable, element gets highlighted but not clicked */
 
async function deleteNote(note, page) {
 
  // click on note
 
  // click on the more button
 
  // click delete
 
  await note.click();
 
  let mores = await page.$$(SELECTORS.MORE_BUTTON);
 
  let lastMore = mores.slice(-1)[0];
 
  await lastMore.click();
 
  await page.waitForSelector(SELECTORS.DELETE_BUTTON, { state: 'visible' });
 
  await page.$(SELECTORS.DELETE_BUTTON).click();
 
}
 
  
 
function stripHtml(content) {
 
  let val = content.replace("<p>Take a note…</p>", "");
 
  val = val.replaceAll("<p>", "");
 
  val = val.replace("</p>", "");
 
  val = val.replace(/<[^>]*>?/gm, '');
 
  return val;
 
}

Python script that didn’t work

  • What the issue? There was issue with one of the auth library about reading some variable, didn’t seem related to my code.
  • Exact issue?
import google.auth
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
 
# Get Google Keep API credentials
creds, project = google.auth.default(
    scopes=["https://www.googleapis.com/auth/keep"]
)
 
# Build Google Keep API client
service = build("keep", "v1", credentials=creds)
 
# Get all Google Keep notes
notes = service.notes().list().execute().get("notes", [])
 
# Print title and text of each note
for note in notes:
    print(note["title"])
    print(note["textContent"])
    print()