google calendar data | sync chrome bookmarks | sync chrome data | Search

This code synchronizes your Chrome browsing history from Takeout files into a Google Calendar, creating a visual timeline of your online activity grouped by half-hour intervals.

Run example

npm run import -- "sync chrome history"

sync chrome history

var importer = require('../Core');
var url = require('url');
var glob = require('glob');
var path = require('path');
var fs = require('fs');

var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var PROJECT_PATH = PROFILE_PATH + '/Downloads';

function loadChromeHistory(file) {
    var chromeHistory = {};
    var wholeFile = JSON.parse(fs.readFileSync(file).toString('utf-8'))
    wholeFile['Browser History'].forEach((match) => {
        var timeGroup = Math.round(match.time_usec / 60 / 30 / 1000000) * 60 * 30 * 1000;
        if (typeof chromeHistory[timeGroup] === 'undefined') {
            chromeHistory[timeGroup] = [];
        }
        match.host = url.parse(match.url).hostname;
        var hostAlreadyListed = chromeHistory[timeGroup]
            .filter(h => h.host === match.host)
        if (hostAlreadyListed.length === 0) {
            chromeHistory[timeGroup].push(match);
        } else {
            if (typeof hostAlreadyListed[0].urls === 'undefined') {
                hostAlreadyListed[0].urls = {};
            }
            hostAlreadyListed[0].urls[match.time_usec] = match.url;
        }
    })
    return Promise.resolve(chromeHistory);
}

var {
    ISODateString, updateEvent, correctCalendarId
} = importer.import("import google calendar api",
"lookup calendar name",
"convert date iso",
"update create merge event");

var options = {
    calendarId: 'Bookmarks'
};

function syncChromeHistory() {
    var files = glob.sync('Takeout*/Chrome/BrowserHistory.json', {cwd: PROJECT_PATH})
        .map(f => path.join(PROJECT_PATH, f));
    files.sort((a, b) => fs.statSync(a).ctime - fs.statSync(b).ctime);
    return correctCalendarId(options)
        .then(() => loadChromeHistory(files.pop()))
        .then(links => {
            const groups = Object.keys(links).sort((a, b) => parseInt(b) - parseInt(a));
            console.log(groups.slice(0, 10));
            console.log(new Date(parseInt(Object.keys(links)[0])));
            return Object.keys(links).map(t => ({
                start: {
                    dateTime: ISODateString(new Date(parseInt(t)))
                },
                end: {
                    dateTime: ISODateString(new Date(parseInt(t) + 60 * 30 * 1000))
                },
                summary: 'Chrome activity',
                description: JSON.stringify(links[t], null, 4)
            }))
        })
        .then(results => {
            return importer.runAllPromises(results
                .map(event => resolve => {
                    return updateEvent(event, options)
                        .then(r => resolve(r))
                        .catch(e => {
                            console.log(e);
                            resolve()
                        })
                }))
        })
        .catch(e => console.log(e))
}

module.exports = syncChromeHistory;

What the code could have been:

const { importCore, importFunctions } = require('../Core');
const url = require('url');
const glob = require('glob');
const path = require('path');
const fs = require('fs');
const { console } = require('console');

// Define constants and environment variables
const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const PROJECT_PATH = path.join(PROFILE_PATH, 'Downloads');
const CHROME_HISTORY_GLOB = 'Takeout*/Chrome/BrowserHistory.json';

// Function to load Chrome history from a file
function loadChromeHistory(filePath) {
    // Read the file and parse its contents
    const wholeFile = JSON.parse(fs.readFileSync(filePath, 'utf-8'));

    // Initialize an object to store the Chrome history
    const chromeHistory = {};

    // Iterate over the browser history entries
    wholeFile['Browser History'].forEach((match) => {
        // Group the entries by date
        const timeGroup = Math.round(match.time_usec / 60 / 30 / 1000000) * 60 * 30 * 1000;
        if (!chromeHistory[timeGroup]) {
            chromeHistory[timeGroup] = [];
        }

        // Parse the URL and extract the hostname
        const host = url.parse(match.url).hostname;
        const existingHosts = chromeHistory[timeGroup].filter((h) => h.host === host);

        // Add the entry to the history if it's not already there
        if (existingHosts.length === 0) {
            chromeHistory[timeGroup].push({ host,...match });
        } else {
            // Merge the URL with the existing entry
            const existingHost = existingHosts[0];
            if (!existingHost.urls) {
                existingHost.urls = {};
            }
            existingHost.urls[match.time_usec] = match.url;
        }
    });

    return chromeHistory;
}

// Import functions from the core module
const { ISODateString, updateEvent, correctCalendarId } = importFunctions([
    'import google calendar api',
    'lookup calendar name',
    'convert date iso',
    'update create merge event',
]);

// Options for the calendar ID
const calendarOptions = {
    calendarId: 'Bookmarks',
};

// Function to sync Chrome history with the calendar
function syncChromeHistory() {
    // Find the Chrome history files in the project directory
    const files = glob.sync(CHROME_HISTORY_GLOB, { cwd: PROJECT_PATH })
       .map((f) => path.join(PROJECT_PATH, f));

    // Sort the files by creation time
    files.sort((a, b) => fs.statSync(a).ctime - fs.statSync(b).ctime);

    // Load the Chrome history from the most recent file
    return correctCalendarId(calendarOptions)
       .then(() => loadChromeHistory(files.pop()))
       .then((chromeHistory) => {
            // Group the history by date
            const groups = Object.keys(chromeHistory).sort((a, b) => parseInt(b) - parseInt(a));

            // Log the first 10 groups
            console.log(groups.slice(0, 10));

            // Get the start date of the history
            const startDate = new Date(parseInt(Object.keys(chromeHistory)[0]));

            // Create events for each group
            return Object.keys(chromeHistory).map((t) => ({
                start: {
                    dateTime: ISODateString(new Date(parseInt(t))),
                },
                end: {
                    dateTime: ISODateString(new Date(parseInt(t) + 60 * 30 * 1000)),
                },
                summary: 'Chrome activity',
                description: JSON.stringify(chromeHistory[t], null, 4),
            }));
        })
       .then((events) => {
            // Update each event on the calendar
            return importCore.runAllPromises(
                events.map((event) =>
                    resolve =>
                        updateEvent(event, calendarOptions)
                           .then((r) => resolve(r))
                           .catch((e) => {
                                console.log(e);
                                resolve();
                            }),
                ),
            );
        })
       .catch((error) => console.log(error));
}

module.exports = syncChromeHistory;

This code synchronizes your Chrome browsing history from Takeout files with a Google Calendar.

Here's a breakdown:

  1. Setup:

  2. History Loading:

  3. Calendar Integration:

  4. Synchronization Logic:

In essence, this code fetches your Chrome browsing history from Takeout files, organizes it by time, and pushes it into a Google Calendar as a visual timeline of your online activity.