Closed konraddecker closed 9 months ago
Same here, seems that fetching the ics url timed out, which leads into removal of all existing calendar entries.
Would it be possible to check whether the content is empty to give it a retry? Putting that URL into a browser to download the ics manually take a while, so I assume it's just a timeout issue.
I was experiencing the same issue separately, and was able to analyze the problem and come up with a solution. Please refer to the information below.
Microsoft Outlook/365's calendar share is outputting ICS files that are incompliant to ICS standards. The specific issues that affect GAS-ICS-Sync are as follows:
This issue can be resolved by fixing the ICS file to comply to ICS standards before parsing.
Add the following changes in the Helpers.gs
file:
Revise fetchSourceCalendars()
function as shown below:
function fetchSourceCalendars(sourceCalendarURLs){
var result = []
for (var source of sourceCalendarURLs){
var url = source[0].replace("webcal://", "https://");
var colorId = source[1];
callWithBackoff(function() {
var urlResponse = UrlFetchApp.fetch(url, { 'validateHttpsCertificates' : false, 'muteHttpExceptions' : true });
if (urlResponse.getResponseCode() == 200){
var urlContent = RegExp("(BEGIN:VCALENDAR.*?END:VCALENDAR)", "s").exec(urlResponse.getContentText());
// Attempt to fix ICS file if initial parse was unsuccessful
if(urlContent == null){
var urlContent = RegExp("(BEGIN:VCALENDAR.*?END:VCALENDAR)", "s").exec(fixICS(urlResponse.getContentText()));
}
if(urlContent == null){
Logger.log("[ERROR] Incorrect ics/ical URL: " + url);
return;
}
else{
result.push([urlContent[0], colorId]);
return;
}
}
else{ //Throw here to make callWithBackoff run again
throw "Error: Encountered HTTP error " + urlResponse.getResponseCode() + " when accessing " + url;
}
}, defaultMaxRetries);
}
return result;
}
Add a fixICS()
function as shown below:
// Fix ICS file from Microsoft Outlook/365 that is incompliant to ICS standards
function fixICS(text) {
// Split the text into lines
const lines = text.split('\n');
// Flag to track if a new event is encountered
let veventSectionEntered = false;
// Process lines in forward order
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('BEGIN:VEVENT')) {
// Check if this is the first encounter of BEGIN:VEVENT
if (!veventSectionEntered) {
veventSectionEntered = true;
continue;
}
// Skip if END:VEVENT is already added
if (lines[i-1].startsWith('END:VEVENT')) {
continue;
}
// Add `END:VEVENT` with a line break before the current `BEGIN:VEVENT`
lines.splice(i, 0, 'END:VEVENT');
}
}
// Check if `END:VCALENDAR` is missing and add it if necessary
if (!lines[lines.length - 1].startsWith('END:VCALENDAR')) {
lines.splice(lines.length - 1, 0, 'END:VCALENDAR');
}
// Join lines with line breaks
return lines.join('\n');
}
The code above is a very crude attempt to fix this issue; this does solve the sync issue, but please add a comment below if you have a more elegant solution.
It is unclear as to why this issue suddenly appeared. Did Microsoft Outlook/365 suddenly began writing ICS file incorrectly? Is there something wrong on the parser side? I would appreciate any details and discussions below.
Same here, seems that fetching the ics url timed out, which leads into removal of all existing calendar entries.
Would it be possible to check whether the content is empty to give it a retry? Putting that URL into a browser to download the ics manually take a while, so I assume it's just a timeout issue.
As for the issue of all existing calendar entries being removed, you may want to implement some changes in the code to prevent this from happenig. The issue below provides a solution you can use. https://github.com/derekantrican/GAS-ICS-Sync/issues/343
thanks, the fix worked.
Is this an Office365 error? Some calendars take longer to download the ics file?
Is this an Office365 error
Yes, this is a bug in the latest Outlook version. See #386 for more.
@Kucladell Thanks for your solution, I have not had time to thoroughly test this, just 2 quick inputs:
lines.splice(lines.length , 0, 'END:VCALENDAR');
or just use lines.push('END:VCALENDAR');
@konraddecker Glad to be able to help! Thank you as well for confirming that the fix indeed works.
@jonas0b1011001 Thank you for the detailed input! I am not well versed in Javascript (and programming in general) so I deeply appreciate your feedback. As for the points you raised:
lines.push()
but this ended up with a blank line before the last line, so I ended up with this botch. The current fix above works only because the parser reads from BEGIN:VCALENDAER to END:VCALENDAR and ignores anything that comes after. ~I will have another go at this.~(Edit: A better solution is proposed, so removed comments on improving my code.)
@jonas0b1011001 I see that you proposed a more elegant solution at https://github.com/derekantrican/GAS-ICS-Sync/pull/386 . I suggest you go ahead with this!
Just logged in to say thanks for @Kucladell for the fix. It was driving me crazy
@arcegabriel Thank you for the kind words! A more elegant solution is coming up soon by @jonas0b1011001, but glad to be able to help in the meantime. This is the first time I shared my code to someone else so this means a lot to me.
Closing via #386 . Release with the fix coming shortly
My syncing started doing this sometime before I got up for the day, but by mid-morning it started working again! Not sure what microsoft is doing, but I'm very glad there may be a solution I should implement when it happens again.
Thank you!
The problem
Unfortunately the sync stopped working for me recently. The following error is displayed in the console (see Screenshot)
I have already recreated the Outlook calendar share and generated new links. Unfortunately it does not work.
is this bug known? Is there a fix for this?
Version of GAS-ICS-Sync
5.7
Additional information & file uploads
No response