Skip to content

Instantly share code, notes, and snippets.

@paucoma
Forked from tomjaimz/ICS Import.gs
Last active October 7, 2023 22:33
Show Gist options
  • Save paucoma/a529c3b982e991a9137143bda052e24c to your computer and use it in GitHub Desktop.
Save paucoma/a529c3b982e991a9137143bda052e24c to your computer and use it in GitHub Desktop.
Google App Script code to import events from a Calendar (.ics) file into Google Sheets.
function onOpen() {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem('Upload', 'upload')
.addToUi();
}
function upload() {
const hs = HtmlService.createHtmlOutput(
'<form><input type="file" name="file" onchange="var reader = new FileReader(); reader.onloadend = (e) => google.script.run.withSuccessHandler(google.script.host.close).importICS(e.target.result); reader.readAsText(this.parentNode.file.files[0]);"></form>'
);
SpreadsheetApp.getUi().showModalDialog(hs, 'Select .ics file');
}
function importICS(form) {
var inputFields = ['DTSTART', 'SUMMARY', 'DESCRIPTION',"RRULE"], // add to this to add more FIELDs
data = [['Inicio', 'Resumen', 'Descripcion','Repeats']], // should correspond to inputFields
lines = form.split(/\r\n|\n|\r/);
for (i in lines) {
var lineData = lines[i].split(':'), col = inputFields.indexOf(lineData[0].split(';',1)[0])
if(lines[i] === "BEGIN:VEVENT") { //Adds a new row and initialize it to avoid issues when not found
data[data.length] = ["","","",""]; //If a FIELD is not present on the file, it makes an error: Better to initialize!
// Its length should correspond to inputFields. Eg: for 7 read fiels --> = ["","","","","","",""];
}
else if (lines[i].substr(0, 1) === ' ') {
//If row starts with just SPACE instead of a FIELD, it must be added to previous line as it belows to a multiple line FIELD
// https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.11
data[data.length - 1][previous_col] = data[data.length - 1][previous_col] + lines[i]
}
else if(col !== -1 && data.length > 1) { // exists in inputFields, and BEGIN:VEVENT found
//Browser.msgBox("Dealing with: /////////0:" + lineData[0] + " //////////////1: " + lineData[1] )
// Date (YYYY,MM,DD) Thus: lineData[1].substr(0, 4) is YYYY, lineData[1].substr(4, 2)-1 is MM (from 0-11) and the other is DD. And last, lineData[1] is the text DATA to import when it is not a Date (DTStart or DTend)
data[data.length - 1][col] = (lineData[0].substr(0, 2) === 'DT') ? new Date(lineData[1].substr(0, 4),lineData[1].substr(4, 2)-1,lineData[1].substr(6, 2) ) : lineData[1]
for (var j=2; j<lineData.length ; j=j+1) { //It might happen that someone added ':' to the FIELD and therefore it was split too
data[data.length - 1][col] = data[data.length - 1][col] + ":" + lineData[j]
}
var previous_col = col //To remember the last FIELD saved
}
}
Browser.msgBox( "Total imported lines: " + data.length + " Columns: " + data[0].length )
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1, 1, data.length, data[0].length).setValues(data)
}
/*
Instructions. from tomjaimz commented on Oct 3, 2018
You will need: an .ics file, sourced elsewhere.
1. Open a blank spreadsheet (https://docs.google.com/spreadsheets/ and select Blank).
2. From the Tools menu select Script Editor.
3. Paste the above code into the Code.gs, replacing the existing function myFunction() { } code.
4. Save the script - give it a good name like ICS Importer.
5. Go back to your spreadsheet and reload the page.
6. Under the Add-ons menu there should now be an option corresponding to the name you gave your script in step 4. Under that option there should be an Upload item. Select it.
7. If it's your first time you'll be prompted to accept some permissions.
8. Select an .ics file using the file dialog.
After you have chosen a file it will process in the background. When it's done, the dialog will disappear.
Notes.
=======
The import will always overwrite whatever's already in your spreadsheet, so use a blank one.
You can add fields to import by changing lines 12 and 13 in the code. Some options might be DESCRIPTION and LOCATION.
There's no real error handling going on here. You could upload a non-ics file or do many other things. It's a minimum viable hack.
--- Revisions ---
Updated ImportICS function to contribution from: [Hal-software](https://gist.github.com/Hal-software) [comment](https://gist.github.com/tomjaimz/93bb639ba2bb61f99cf5cb942edc361b?permalink_comment_id=4713721#gistcomment-4713721)
--- Improvement Oportunities ---
https://developers.google.com/apps-script/guides/dialogs
https://developers.google.com/calendar/api/concepts/events-calendars
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment