n8n
n8n copied to clipboard
Google Calendar Update does not accept start date
Describe the bug If the Google Calendar node is used, with the resource 'Event' and operation 'Update'. The entered Start Date with the following ISO format '2023-02-22T14:00:00.000Z', always throws the error 'Invalid start time.'. I also tried to change the format but without any success. I looked into the code of the node and it seems like it is because the entered date gets formatted the same way.
MutedJam also pointed out the problem in forum post. It seems like google changed its API.
To Reproduce Steps to reproduce the behavior:
- Open a new Workflow
- Create a Google Calendar node, which will load events out of an calendar
- Create a second Google calendar node, which tries to update the start and end time of an previously loaded event
- See error
Expected behavior I would expect that a given ISO date string would result in an updated start date.
Environment (please complete the following information):
- OS: Ubuntu Linux 22.04 self hosted
- n8n Version 0.203.1
- Node.js Version [e.g. 16.17.0]
- Database system SQLite
- Operation mode own
Hey @tillhoffmann1411
Have you tried with the latest release of n8n?
Hey @Joffcom
Thank you for your fast reply!
I just updated n8n but unfortunately, the problem still exists.
I checked the date formatting done by n8n in this file file in line 463. The formatting logic for creating events and updating events looks similar and creating events does work without any problems. Maybe Google changed something about their patch API but I couldn't figure out why a normal formatted dateTime string should not work.
Hey @tillhoffmann1411,
I have given it a go using your steps to reproduce and for me it is working as expected.
This also appears to work if I manually input a date and time as well.
Are you able to share a workflow that reproduces the issue?
Found the problem.
If the event originally has only a date and no time ("date": "2023-02-22") and you then try to set a dateTime ("dateTime": "2023-02-22T08:00:00.000Z"), it says that the date is not valid.
The solution is to set the appropriate dateTime in the start/end object and set date to null at the same time.
Example Request Body against the Google Calendar API for a PATCH request
{ "start": { "dateTime": "2023-02-23T07:00:00.000Z", "date": null }, "end": { "dateTime": "2023-02-23T09:00:00.000Z", "date": null } }
So it looks like google internally automatically only uses date if there is no time set in the dateTime property. I have seen that n8n internally always works with dateTime only. Would it be an option to additionally set the date property to null by default when updating events?
Hey @tillhoffmann1411,
I would need to check the API Docs for Google Cal but if it is an all day event or has no time I would still expect the value to update or be set so I guess there is something that needs to be looked at there.
Bumping what is a relatively old issue to say that I'm running into this myself when updating events on a calendar via n8n. If the event itself is currently marked as all day on Google Calendar, any updates fail with something like:
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid start time."}],"code":400,"message":"Invalid start time."}} - Invalid start time.
I also looked through the source for the node, and it seems to me that what @tillhoffmann1411 suggests would work: sending null start.date
and end.date
attributes for regular events, and sending null start.dateTime
and end.dateTime
attributes for all day events. If I get a little bit of free time I will try to submit a PR, but at a glance, it looks like a couple of changes here would do the trick:
- Sending null
dateTime
attributes forstart
andend
when updating all-day events - Having an
else
in the conditional to send nulldate
attributes forstart
andend
when updating regular events
Maybe something like this? FYI, completely untested or optimized :-)
if (updateFields.allday === 'yes' && updateFields.start && updateFields.end) {
body.start = {
dateTime: null, // null because this is an all day event
date: updateTimezone
? moment.tz(updateFields.start, updateTimezone).utc(true).format('YYYY-MM-DD')
: moment.tz(updateFields.start, moment.tz.guess()).utc(true).format('YYYY-MM-DD'),
};
body.end = {
dateTime: null, // null because this is an all day event
date: updateTimezone
? moment.tz(updateFields.end, updateTimezone).utc(true).format('YYYY-MM-DD')
: moment.tz(updateFields.end, moment.tz.guess()).utc(true).format('YYYY-MM-DD'),
};
} else {
body.start = {
date: null, // null because this is a regular day event with a start time
dateTime: updateTimezone
? moment.tz(updateFields.start, updateTimezone).utc(true)
: moment.tz(updateFields.start, moment.tz.guess()).utc(true),
};
body.end = {
date: null, // null because this is a regular day event with an end time
dateTime: updateTimezone
? moment.tz(updateFields.end, updateTimezone).utc(true)
: moment.tz(updateFields.end, moment.tz.guess()).utc(true),
};
}