Crear eventos de Google Calendar desde la hoja de cálculo pero evitar duplicados

Intento escribir un script que tome datos de una hoja de cálculo de Google y cree eventos en mi calendario de Google.

Logré eso bien pero produjo duplicados cada vez que lo ejecuté. Así que ahora estoy tratando de evitar eso creando una columna 17 en la hoja de cálculo con un ID de evento único producido automáticamente para cada fila y luego cada vez que se ejecuta el script se verá el ID del evento para cada fila y se eliminará el evento correspondiente en el calendario antes de volver a crearlo con los datos originales o los datos actualizados si he cambiado la fila.

Soy nuevo en el scripting de cualquier tipo y lo improvisé todo, pero estoy chocando contra una pared ahora. ¿Alguien puede ayudar a resolver esto?

function CalInsert() { var cal = CalendarApp.getDefaultCalendar(); var id = SpreadsheetApp.getActiveSheet().getRange(2,17).getValue(); if (id != 0) { var event = cal.getEventSeriesById(id); event.deleteEventSeries(); } var sheet = SpreadsheetApp.getActiveSheet(); var startRow = 2; // First row of data to process var numRows = sheet.getLastRow(); // Number of rows to process var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn()); var data = dataRange.getValues(); for (i in data) { var row = data[i]; var title = row[0]; // First column var desc = row[13]; // Second column var tstart = row[14]; var tstop = row[15]; var event = cal.createEvent(title, tstart, tstop, {description:desc}); var eventid = event.getId(); SpreadsheetApp.getActiveSheet().getRange(2,17).setValue(eventid); } } 

Esto es muy similar a una pregunta hecha hace solo dos días, que consistía en sincronizar una hoja de cálculo de eventos con un calendario. Parece que desea considerar que la hoja de cálculo es el maestro de los eventos que origina, lo que simplificaría considerablemente el problema. Los fundamentos de lo que debe hacer están cubiertos en esta respuesta . Si prefieres modificar el código existente, tengo una implementación a continuación.

Tengo una versión modificada del código de este blog , que modificará las entradas de calendario preexistentes para que coincidan con la información en la hoja de cálculo. He organizado mi hoja de cálculo de manera diferente, y esto se refleja en el código.

Fecha | Título | Hora de inicio | Hora de finalización | Ubicación | Descripción | EventID

El script completa la columna de ID de evento cuando se crean nuevos eventos, y luego se utiliza en invocaciones posteriores para recuperar eventos del calendario, evitando así la duplicación.

Guión

 /** * Adds a custom menu to the active spreadsheet, containing a single menu item * for invoking the exportEvents() function. * The onOpen() function, when defined, is automatically invoked whenever the * spreadsheet is opened. * For more information on using the Spreadsheet API, see * https://developers.google.com/apps-script/service_spreadsheet */ function onOpen() { var sheet = SpreadsheetApp.getActiveSpreadsheet(); var entries = [{ name : "Export Events", functionName : "exportEvents" }]; sheet.addMenu("Calendar Actions", entries); }; /** * Export events from spreadsheet to calendar */ function exportEvents() { var sheet = SpreadsheetApp.getActiveSheet(); var headerRows = 1; // Number of rows of header info (to skip) var range = sheet.getDataRange(); var data = range.getValues(); var calId = "YOUR_CALENDAR_ID"; var cal = CalendarApp.getCalendarById(calId); for (i=0; i 

Eliminar / Recrear

En esta alternativa, eventID se utiliza para buscar y eliminar el evento previamente existente. Después de eso, se crea un nuevo evento con los datos en la hoja de cálculo. Esto tiene el beneficio de que todos los valores del evento se pueden actualizar, incluidas las horas de inicio y finalización (vea Notas a continuación). Por otro lado, cualquier cambio que se haya realizado en el evento original se perderá, por ejemplo, si se hubiera invitado a otras personas al evento o se hubieran agregado recordatorios personalizados.

Para usar esta alternativa, simplemente reemplace el código coincidente con esto:

 // Check if event already exists, delete it if it does try { var event = cal.getEventSeriesById(id); event.deleteEventSeries(); row[6] = ''; // Remove event ID } catch (e) { // do nothing - we just want to avoid the exception when event doesn't exist } //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc}); var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId(); row[6] = newEvent; // Update the data array with event ID debugger; 

Notas

  • La documentación de getEventSeriesById declara erróneamente que devuelve null cuando no se encuentra un evento coincidente, cuando en su lugar arroja una excepción. (desagradable!) Así que lo he incluido en un bloque de prueba / captura solo para seguir nadando.
  • Desafortunadamente, mientras getEventSeriesById funciona para recuperar un evento, returns un objeto EventSeries , que no admite el método setTime() . Si no espera cambiar la hora de los eventos, esto está bien. De lo contrario, puede cambiar el Event en una EventSeries de EventSeries estableciendo las reglas y horas de recurrencia , o eliminar el evento anterior y crear uno nuevo, como se muestra en Eliminar / Recrear . Número 1154 .
  • La hoja de cálculo siempre gana. Cualquier cambio de evento (en campos relevantes) registrado a través del Calendario de Google será sobrescrito por el script.

Me gustaría publicar esto para cualquier persona que quiera usarlo, he modificado la secuencia de comandos para trabajar dentro de una hoja que ya estaba usando. El formato de fecha y la duplicación de eventos fueron un par de problemas que debieron solucionarse, pero después de algunas pruebas estoy bastante contento con cómo funciona esto. Lo uso para reservar trabajos y compartirlos con mis empleados que son móviles y trabajo de tipo de construcción en todo el ciudad. El siguiente paso es llevar los eventos del calendario a la hoja de cálculo para que funcione en ambos sentidos y puedo usar la aplicación de calendario en mi teléfono para reservar trabajos sobre la marcha, así que si alguien tiene algún consejo en todos los oídos, también necesito un script para insertar Forme datos de respuesta en la misma hoja y agregue filas completas donde los números de trabajo coincidan manteniendo intactos los datos existentes.

 `function onOpen() { var sheet = SpreadsheetApp.getActiveSpreadsheet(); var entries = [{ name : "Export Events", functionName : "exportEvents" }]; sheet.addMenu("Calendar Actions", entries); }; function parseDate(s) { var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5, jul:6,aug:7,sep:8,oct:9,nov:10,dec:11}; var p = s.replace(".", "").split('-'); return new Date(p[2], months[p[1].toLowerCase()], p[0]); } /** * Export events from spreadsheet to calendar */ function exportEvents() { var sheet = SpreadsheetApp.getActiveSheet(); var headerRows = 6; // Number of rows of header info (to skip) var range = sheet.getDataRange(); var data = range.getDisplayValues(); //var calId = "Your calendar Id"; // PRODUCTION var calId = "Your_calendar Id to test"; // TEST var cal = CalendarApp.getCalendarById(calId); //Logger.log(cal); //Logger.log(data.length); for (i=0; i 0) { try { event = cal.getEventSeriesById(id); } catch (e) { // do nothing - we just want to avoid the exception when event doesn't exist } } if (!event) { //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc}); var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId(); var r = i + 1; var cell = sheet.getRange("G" + r); cell.setValue(newEvent); } else { Logger.log(event); event.setTitle(title); event.setDescription(desc); event.setLocation(loc); // event.setTime(tstart, tstop); // cannot setTime on eventSeries. // ... but we CAN set recurrence! var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1); event.setRecurrence(recurrence, tstart, tstop); } debugger; } } 

`