google calendar | days events | create new calendar event | Search

This code manages Google Calendar events, likely by updating existing events, merging information, and identifying duplicates.

Run example

npm run import -- "Update create merge delete event"

Update create merge delete event

var {google} = require('googleapis');
var util = require('util');
var importer = require('../Core');
var chrono = require('chrono-node');
var {JSDOM} = require('jsdom');
var getDaysEvents = importer.import("days events");

var {
    authorizeCalendar, ISODateString, correctCalendarId
} = importer.import("authorize google calendar",
"convert date iso",
"lookup calendar name")

function updateEvent(event, options) {
    var calendar;
    
    return authorizeCalendar()
        .then(c => calendar = c)
        .then(() => correctCalendarId(options))
        .then(() => getDaysEvents(event.start.dateTime, options))
        .then(m => {
            const actionsArray = [];
            const matches = m.filter(match => !match.event.deleted
                && match.event.summary.toLowerCase().trim() === event.summary.toLowerCase().trim()
                && Math.abs(Math.round(new Date(match.event.start.dateTime).getTime() / 1000 / 60)
                    - Math.round(new Date(event.start.dateTime).getTime() / 1000 / 60)) < 32);
            console.log('Matching ' + matches.length);
        
            // TODO: check for existing event if the ID is already set?
            if (matches.length > 0) {
                var unique = [];
                try {
                    let descriptions = JSON.parse(event.description) || [];
                    descriptions = descriptions.concat(
                        ...matches.map(match => {
                            try {
                                return JSON.parse(match.event.description)
                            } catch (e) {
                                return [];
                            }
                        }));
                    const urls = descriptions.map(d => (d || {}).url);
                    unique = descriptions.filter((d, i) => urls.indexOf((d || {}).url) === i);
                } catch (e) {
                    unique = [event.description];
                }
                // TODO: make sure there are no duplicates
                // TODO: move this in to some parsing utility?
                // TODO: deep compare instead of just comparing "url" property?
                // support for objects if there's only one
                unique = unique.length === 1 ? unique[0] : unique;
                // patch the first match
                var newDescription = typeof unique === 'string' ? unique : JSON.stringify(unique, null, 4);
                
                if(matches[0].event.description !== newDescription) {
                    actionsArray.push(util.promisify(
                        calendar.events.patch.bind(calendar.events, {
                            eventId: matches[0].event.id,
                            calendarId: options.calendarId,
                            auth: options.auth,
                            resource: {
                                description: newDescription,
                                colorId: event.colorId
                            }
                        }))());
                }

                // TODO: delete the rest
                for (const match of matches.slice(1)) {
                    match.event.deleted = true;
                    actionsArray.push(util.promisify(
                        calendar.events.delete.bind(calendar.events, {
                            eventId: match.event.id,
                            calendarId: options.calendarId,
                            auth: options.auth
                        }))());
                }
            } else {
                console.log('adding event ' + event.summary)
                actionsArray.push(util.promisify(
                    calendar.events.insert.bind(calendar.events, {
                        calendarId: options.calendarId,
                        auth: options.auth,
                        resource: event
                    }))());
            }
            return importer.runAllPromises(actionsArray);
        })
        .catch(e => console.log(e))
};
module.exports = updateEvent;

What the code could have been:

const { google } = require('googleapis');
const { JSDOM } = require('jsdom');
const { chrono } = require('chrono-node');
const importer = require('../Core');

const {
    authorizeCalendar,
    ISODateString,
    correctCalendarId
} = importer.import([
    'authorize google calendar',
    'convert date iso',
    'lookup calendar name'
]);

const getDaysEvents = importer.import('days events');

/**
 * Updates an existing event or creates a new one if it does not exist.
 * 
 * @param {Object} event - The event to be updated or created.
 * @param {Object} options - Options for the update process.
 * @param {string} options.calendarId - The ID of the calendar to update.
 * @param {Object} options.auth - Authentication object for Google Calendar.
 * @returns {Promise} A promise that resolves when the update process is complete.
 */
async function updateEvent(event, options) {
    const calendar = await authorizeCalendar();
    const correctedCalendarId = await correctCalendarId(options);
    const events = await getDaysEvents(event.start.dateTime, options);
    const matches = events.filter(match =>!match.event.deleted
        && match.event.summary.toLowerCase().trim() === event.summary.toLowerCase().trim()
        && Math.abs(Math.round(new Date(match.event.start.dateTime).getTime() / 1000 / 60)
            - Math.round(new Date(event.start.dateTime).getTime() / 1000 / 60)) < 32);

    if (matches.length > 0) {
        const descriptions = mergeDescriptions(event.description, matches.map(match => parseDescription(match.event.description)));
        const newDescription = JSON.stringify(descriptions, null, 4);

        if (matches[0].event.description!== newDescription) {
            await calendar.events.patch({
                eventId: matches[0].event.id,
                calendarId: correctedCalendarId,
                auth: options.auth,
                resource: {
                    description: newDescription,
                    colorId: event.colorId
                }
            });
        }

        await deleteExtraEvents(calendar, correctedCalendarId, options.auth, matches.slice(1));
    } else {
        console.log(`Adding event ${event.summary}`);
        await calendar.events.insert({
            calendarId: correctedCalendarId,
            auth: options.auth,
            resource: event
        });
    }
}

async function mergeDescriptions(existingDescription, newDescriptions) {
    if (existingDescription) {
        try {
            const existingDescriptions = JSON.parse(existingDescription);
            newDescriptions.forEach(description => existingDescriptions.push(description));
            return existingDescriptions;
        } catch (e) {
            const descriptions = existingDescription || [];
            newDescriptions.forEach(description => descriptions.push(description));
            return descriptions;
        }
    } else {
        return newDescriptions;
    }
}

async function parseDescription(description) {
    try {
        return JSON.parse(description);
    } catch (e) {
        return {};
    }
}

async function deleteExtraEvents(calendar, calendarId, auth, events) {
    events.forEach(event => {
        event.event.deleted = true;
        calendar.events.delete({
            eventId: event.event.id,
            calendarId,
            auth
        });
    });
}

module.exports = updateEvent;

This code snippet processes Google Calendar events, likely for updating or managing them.

Here's a breakdown:

  1. Dependencies:

  2. Imports:

  3. updateEvent Function:

Purpose:

This code snippet appears to be part of a system for managing Google Calendar events. It likely handles tasks such as updating existing events, merging information from multiple events, or identifying potential duplicates.