google calendar data | test parse bookmarks | sync chrome history | Search

This code synchronizes your Chrome browsing history with a Google Calendar, creating time-based events for each bookmark folder. It groups bookmarks by half-hour intervals and generates calendar events with summaries and descriptions based on the bookmark data.

Run example

npm run import -- "sync chrome bookmarks"

sync chrome bookmarks

var importer = require('../Core');
var _ = require('lodash');

var offset = (new Date()).getTimezoneOffset() * 60 * 1000;
var {
    ISODateString, updateEvent, correctCalendarId, getBookmarksFromTakeout
} = importer.import("import google calendar api",
"lookup calendar name",
"convert date iso",
"update create merge event",
"parse bookmarks file");
var options = {
    calendarId: 'Bookmarks'
};

function getAllBookmarks(folders) {
    if(!folders) return []
    return folders.map(f => f['links']
        .map(l => Object.assign(l, {folder: f.folder}))
        .concat(getAllBookmarks(f.children)))
        .flat(2)
}

async function syncChromeBookmarks() {
    await correctCalendarId(options)
    // TODO: copy to chrome history
    var links = getAllBookmarks(getBookmarksFromTakeout())
    // group by half hour
    links.sort((a, b) => parseInt(b.date) - parseInt(a.date))
    var groups = _.groupBy(links, l => Math.floor(l.date / (60 * 30 * 1000)))
    var results = Object.keys(groups).reduce((acc, t) => {
        var folders = _.groupBy(groups[t], l => l.folder)
        return acc.concat(Object.keys(folders).map(f => ({
            start: {
                dateTime: ISODateString(new Date(parseInt(t) * 30 * 60 * 1000 - offset))
            },
            end: {
                dateTime: ISODateString(new Date(parseInt(t) * 30 * 60 * 1000 + 60 * 30 * 1000 - offset))
            },
            summary: f,
            description: JSON.stringify(folders[f], null, 4)
        })))
    }, [])
    return await importer.runAllPromises(results
        .map(event => resolve => updateEvent(event, options)
        .then(r => resolve(r))
        .catch(e => {
            console.log(e);
            resolve()
        })))
}

module.exports = syncChromeBookmarks;

What the code could have been:

const { 
  google,
  googleAuth,
  fetchGoogleCalendarId,
  parseBookmarksFile,
  updateEventGoogleCalendar,
  getEventDateISOString 
} = require('../Core');

const { groupBy } = require('lodash');
const { googleCalendarId } = require('../constants');

function getAllBookmarks(folders) {
  if (!folders || folders.length === 0) return [];
  return folders.reduce((acc, folder) => {
    const links = folder.links.map(link => ({...link, folder: folder.folder }));
    return acc.concat(links.concat(getAllBookmarks(folder.children)).flat(2));
  }, []);
}

async function getBookmarksFromTakeout() {
  try {
    const parsedBookmarks = parseBookmarksFile();
    return getAllBookmarks(parsedBookmarks);
  } catch (error) {
    console.error('Error parsing bookmarks file:', error);
    throw error;
  }
}

async function groupBookmarksByTime(links) {
  links.sort((a, b) => parseInt(b.date) - parseInt(a.date));
  return groupBy(links, l => Math.floor(l.date / (60 * 30 * 1000)));
}

async function createEvents(groups) {
  return Object.keys(groups).reduce((acc, time) => {
    const folders = groupBy(groups[time], l => l.folder);
    return acc.concat(Object.keys(folders).map(f => ({
      start: {
        dateTime: getEventDateISOString(new Date(parseInt(time) * 30 * 60 * 1000 - offset))
      },
      end: {
        dateTime: getEventDateISOString(new Date(parseInt(time) * 30 * 60 * 1000 + 60 * 30 * 1000 - offset))
      },
      summary: f,
      description: JSON.stringify(folders[f], null, 4)
    })));
  }, []);
}

async function syncChromeBookmarks() {
  try {
    const calendarId = await fetchGoogleCalendarId(googleCalendarId);
    await correctCalendarId(calendarId);
    const links = await getBookmarksFromTakeout();
    const groups = await groupBookmarksByTime(links);
    const events = await createEvents(groups);
    return await runAllPromises(events.map(event => updateEventGoogleCalendar(event, calendarId)));
  } catch (error) {
    console.error('Error syncing bookmarks:', error);
    throw error;
  }
}

async function runAllPromises(promises) {
  const results = [];
  for (const promise of promises) {
    const result = await promise();
    results.push(result);
  }
  return results;
}

module.exports = syncChromeBookmarks;

This code synchronizes your Chrome bookmarks with a Google Calendar.

Here's a breakdown:

  1. Imports: It imports necessary modules for interacting with Google Calendar, parsing bookmarks, and working with dates.

  2. Initialization:

  3. Bookmark Processing:

  4. Synchronization Logic:

  5. Export: The syncChromeBookmarks function is exported as a module, allowing it to be used in other parts of the application.

In essence, this code takes your Chrome bookmarks, organizes them by time, and creates corresponding events in a Google Calendar, effectively streaming your browsing history as a visual timeline.