Icalendar ICS update not working in google calendar

google-calendar-apiicalendarrfc2445rfc5545

I have some trouble with the ICS attachment to Gmail/Google calendar addresses.
When I have to edit an event I send an update by mail with an ICS file with the same UID of the original event. However, GCalendar adds a second event. How can I overcome this?

This is first ICS file content:

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130425T090000
DTEND:20130425T100000
DTSTAMP:20130206T101100
ORGANIZER;CN=Test test:mailto:test@test.com
ATTENDEE:test@test.eu
UID:CALEVENT_TS090519840000000005
DESCRIPTION:test
SUMMARY:test
LOCATION:Test
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

And this is the update ICS file content:

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130425T100000
DTEND:20130425T110000
DTSTAMP:20130206T101100
ORGANIZER;CN=Test test:mailto:test@test.com
ATTENDEE:test@test.eu
UID:CALEVENT_TS090519840000000005
DESCRIPTION:test
SUMMARY:test
LOCATION:Test
SEQUENCE:2
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

When I receive the update files and I click on "add this event to calendar" I will find two different events.

This is the original raw email:

Delivered-To: test@test.eu
Received: by 10.216.231.19 with SMTP id k19csp190640weq;
        Sat, 9 Feb 2013 08:01:11 -0800 (PST)
X-Received: by 10.194.7.136 with SMTP id j8mr15530679wja.38.1360425671327;
        Sat, 09 Feb 2013 08:01:11 -0800 (PST)
Return-Path: <test@test.eu>
Received: from mxavas8.aruba.it (mxavas8.aruba.it. [62.149.157.18])
        by mx.google.com with SMTP id 45si59706250eeg.83.2013.02.09.08.01.11;
        Sat, 09 Feb 2013 08:01:11 -0800 (PST)
Received-SPF: neutral (google.com: 62.149.157.18 is neither permitted nor denied by best guess record for domain of test@test.eu) client-ip=62.149.157.18;
Authentication-Results: mx.google.com;
       spf=neutral (google.com: 62.149.157.18 is neither permitted nor denied by best guess record for domain of test@test.eu) smtp.mail=test@test.eu
Received: (qmail 4991 invoked by uid 89); 9 Feb 2013 16:01:10 -0000
Delivered-To: test.eu-test@test.eu
Received: (qmail 4424 invoked by uid 89); 9 Feb 2013 16:01:04 -0000
Received: from unknown (HELO mxcmd03.ad.aruba.it) (10.10.10.67)
  by mxavas8.ad.aruba.it with SMTP; 9 Feb 2013 16:01:04 -0000
Received: from smtpdg11.aruba.it ([62.149.158.229])
    by mxcmd03.ad.aruba.it with bizsmtp
    id yFwi1k01A4xF4Fy01G14N7; Sat, 09 Feb 2013 17:01:04 +0100
Received: from localhost ([79.54.181.227])
    by smtpcmd04.ad.aruba.it with bizsmtp
    id yG141k0074umbYX01G140P; Sat, 09 Feb 2013 17:01:04 +0100
Date: Sat, 9 Feb 2013 17:01:04 +0100
Return-Path: test@test.eu
To: test@test.eu
From: Event notification <test@test.eu>
Reply-To: Event notification <test@test.eu>
Subject: New Event
Message-ID: <238497c6d05cffae45716486e74a8009@localhost>
X-Priority: 3
X-Mailer: PHPMailer 5.2.2 (http://code.google.com/a/apache-extras.org/p/phpmailer/)
MIME-Version: 1.0
Content-Type: multipart/mixed;
    boundary="b1_238497c6d05cffae45716486e74a8009"
X-Spam-Rating: mxavas8.ad.aruba.it 1.6.2 0/1000/N

--b1_238497c6d05cffae45716486e74a8009
Content-Type: multipart/alternative;
    boundary="b2_238497c6d05cffae45716486e74a8009"

--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

test

        DateTimeRoom
        02/05/201309.00 - 10.15ROOM1


--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;">
<style type="text/css">
<!--
    td{ background-color: #eee; }
-->
</style>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; color: #333;">
<p style="text-align:center;"><img src="images/logo2.png" alt="Logo" /></p>
<hr style="border: 1px solid #ccc; width: 80%;" />
<div style=" width: 80%; margin: 10px auto;">
    <h4></h4>
    <h3>test</h3>
    <table style="width: 400px; table-layout: fixed; border: 1px solid #ccc;">
        <tr><th>Date</th><th>Time</th><th>Room</th></tr>
        <tr><td>02/05/2013</td><td>09.00 - 10.15</td><td>ROOM 1</td></tr>
    </table>
</div>
</body>
</html>



--b2_238497c6d05cffae45716486e74a8009--

--b1_238497c6d05cffae45716486e74a8009
Content-Type: text/calendar; name="event.ics"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="event.ics"

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:tsCalendar
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130502T090000
DTEND:20130502T101500
DTSTAMP:20130209T170100
ORGANIZER:mailto:test@test.eu
ATTENDEE:mailto:test@test.eu
UID:CALEVENT_TS090519840000000013
DESCRIPTION:test
SUMMARY:test
LOCATION:ROOM1 (floor: prova)
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR


--b1_238497c6d05cffae45716486e74a8009--

Here are the other tests with the ORGANIZER email the same as the Sender email and ATTENDEE email the same as Receiver email.

Creating http://tny.cz/6396ba62
Updating http://tny.cz/08ac81c0

Best Answer

Some of the answers provided are not (entirely) correct.

In short, your ATTENDEE property needs more arguments to make sure Google Calendar considers it an update:

ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=Recipient Name;X-NUM-GUESTS=0:mailto:recipient@gmail.com

I had the same problem and to find the answer I:

  1. Sent myself an invitation using Google Calendar itself + an updated invitation
  2. Compared the two .ics files
  3. Ran many different self-generated variations on those two .ics files to find out which parameters were really necessary

These are my findings:

  • Increment SEQUENCE from 0 to 1 (or further if you want to update updates)
  • METHOD has to be REQUEST (*1)
  • Email sender does NOT need to be the same as ORGANIZER (Sidenote: It is however, not possible in Google Calendar to update an ORGANIZER)
  • ORGANIZER does NOT need to be listed as an ATTENDEE
  • Email recipient has to be an ATTENDEE
  • Also (as mentioned above), the ATTENDEE needs additional parameters, not just :mailto
  • STATUS does NOT need to be provided. EDIT: This is the case when sending invites to google calendar / chrome / mac, but the invite doesn't get a proper preview in other combinations it seems
  • Arguments that take several lines in the doc should be indented by one space on the next line
  • In iCalender objects generated by Google Calendar you may notice that lines that are too long are broken into several lines into the document, however this is not required (e.g. you can provide a description that is a very long string, just make sure it only takes one line or cut it in lines where every line is indented with one space)
  • Bonus Tip: Use same UID in original invite and update (this is actually not required BUT makes sure your historical test results remain unaffected...)
  • Bonus Tip 2: for easier testing, also change the SUMMARY and subject of your email each time

Cleaned up example:

BEGIN:VCALENDAR
PRODID:-//YourCompany/AppName//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20180331T150000
DTEND:20180331T160000
DTSTAMP:20180331T150000 // make sure to populate this dynamically
ORGANIZER;CN=organizer@gmail.com:mailto:organizer@gmail.com
UID:BESTIDEVER123
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=Recipient Name;X-NUM-GUESTS=0:mailto:recipient@gmail.com
CREATED:20180331T150000  // make sure to populate this dynamically
DESCRIPTION:Best event evah
LAST-MODIFIED:20180331T150000 // make sure to populate this dynamically
LOCATION:
SEQUENCE:0 // don't forget to increment this!!
SUMMARY:A Wonderful Event
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

(*1) The only question that I could not figure out is how to have a METHOD:PUBLISH that can be updated - I am trying to make a calendar publishing app that should NOT take replies. If anyone can figure that out I would be very grateful. :-)

Related Topic