n8n icon indicating copy to clipboard operation
n8n copied to clipboard

Google Calendar Update does not accept start date

Open tillhoffmann1411 opened this issue 2 years ago • 6 comments

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:

  1. Open a new Workflow
  2. Create a Google Calendar node, which will load events out of an calendar
  3. Create a second Google calendar node, which tries to update the start and end time of an previously loaded event
  4. 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

tillhoffmann1411 avatar Feb 19 '23 12:02 tillhoffmann1411

Hey @tillhoffmann1411

Have you tried with the latest release of n8n?

Joffcom avatar Feb 19 '23 12:02 Joffcom

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.

tillhoffmann1411 avatar Feb 19 '23 14:02 tillhoffmann1411

Hey @tillhoffmann1411,

I have given it a go using your steps to reproduce and for me it is working as expected.

image

This also appears to work if I manually input a date and time as well.

image

Are you able to share a workflow that reproduces the issue?

Joffcom avatar Feb 20 '23 08:02 Joffcom

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?

tillhoffmann1411 avatar Feb 22 '23 12:02 tillhoffmann1411

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.

Joffcom avatar Feb 23 '23 08:02 Joffcom

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 for start and end when updating all-day events
  • Having an else in the conditional to send null date attributes for start and end 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),
  };
}

fredoliveira avatar Jan 18 '24 17:01 fredoliveira