ICS-Termine

Wenn Sie Termine mit Outlook, Teams oder anderen Programmen planen, dann werden im Hintergrund per Mail so genannte ICS-Dateien versendet. Ein Blick hinter die Kulissen und Besonderheiten von Outlook und warum eine Termineinladungen mit BCC-Empfängern beim Empfänger meist die komplette Teilnehmerliste anzeigt.

ICS Format und Felder

As Format der ICS-Dateien ist ein der "RFC5545: Internet Calendaring and Scheduling Core Object Specification (iCalendar)" beschrieben und im Abschnitt 3.6.5 werden die zwingend erforderlichen Felder beschrieben. Die kleinste ICS-Datei hat dabei den folgenden Aufbau:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:MSXFAQSample
END:VCALENDAR

Damit kommen Sie natürlich nicht wirklich weiter, da keinerlei Information enthalten ist. Ein paar Daten sollten Sie schon addieren, damit Outlook und andere Programme auch einen Termin daraus formen können, z.B.

BEGIN:VCALENDAR
VERSION:2.0
PRODID:MSXFAQSample
BEGIN:VEVENT
UID:1234567@msxfaq.de
DTSTAMP:20230207T224510Z
DTSTART:20230207T224500Z
END:VEVENT
END:VCALENDAR

Wenn ich diese Information als ICS-Datei abspeichere und per Doppelklick in Outlook öffne, sehe ich einen neuen Termin mit dem Startdatum, der Standarddauer von 1h und alle Felder sin sind leer. Es ist noch keine Einladung oder Absage. Wenn ich eine Termineinladung von Outlook abfange, dann siehst das schon deutlich umfangreiche aus. Ich habe die Elemente zur Lesbarkeit etwas eingerückt, damit Sie die Blöcke besser erkennen können.

Bei einer realen Datei ist nicht erlaubt, da Feldinhaltkönnen auch über mehrere Zeilen gehen können und die Folgezeile eingerückt wird.

BEGIN:VCALENDAR
   METHOD:REQUEST
   PRODID:Microsoft Exchange Server 2010
   VERSION:2.0
   BEGIN:VTIMEZONE
      TZID:W. Europe Standard Time
      BEGIN:STANDARD
         DTSTART:16010101T030000
         TZOFFSETFROM:+0200
         TZOFFSETTO:+0100
         RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
      END:STANDARD
      BEGIN:DAYLIGHT
         DTSTART:16010101T020000
         TZOFFSETFROM:+0100
         TZOFFSETTO:+0200
         RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
      END:DAYLIGHT
   END:VTIMEZONE
   BEGIN:VEVENT
      ORGANIZER;CN="User1 (MSXFAQLAB)":mailto:user1@msfaqlab.onmicrosoft.com
      ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=User2
       /MSXFAQLBA):mailto:user2@msfaqlab.onmicrosoft.com
      DESCRIPTION;LANGUAGE=de-DE:MSXFAQ Termintest2023\n
      UID:uniqueid1
      SUMMARY;LANGUAGE=de-DE:TestFC Einladung
      DTSTART;TZID=W. Europe Standard Time:20230301T090000
      DTEND;TZID=W. Europe Standard Time:20230301T092500
      CLASS:PUBLIC
      PRIORITY:5
      DTSTAMP:20230209T084405Z
      TRANSP:OPAQUE
      STATUS:CONFIRMED
      SEQUENCE:0
      LOCATION;LANGUAGE=de-DE:
   END:VEVENT
END:VCALENDAR

Wenn Sie eine so eingerückte Datei importieren, dann fragt mich Outlook, ob die die ICS als Kalender öffnen oder importieren soll.

Der Parser von Outlook erkennt diese Datei nicht als einzelnen Termin sondern als Kalender. Ohne Einrückung wird direkt der Termin geöffnet.

In dem Beispiel wird unter "BEGIN:VTIMEZONE" auch die Zeitzone definiert, was für den Termin nur wichtig ist, wenn darauf auch im VEVENT verwiesen wird. Für den Termin interessant it der Block zwischen "BEGIN:VEVENT" und "END:VEVENT"

Um mehr über die ICS-Dateien im Einsatz zu erfahren, habe ich einen Termin mit Outlook erstellt und an ein IMAP4-Postfach gesendet. So kann ich einfach die ICAL-Datei per Thunderbird abrufen, denn Outlook versteckt die Anlage, wenn es einen Termin erkennt. Ich habe zu einem Termin eingeladen, zugesagt, dann aktualisiert und zuletzt wieder abgesagt.

Im Hintergrund hat Outlook verschiedene Mails mit ICS-Anlagen an die Empfänger gesendet, die ich genauer betrachtet habe.

Mail-Header

Bei einer per Mail übertragene Einladung gib es den "Envelope Header" und den "Mail-Header". Der erste Header ist für die Benutzer nicht sichtbar aber enthält die Empfänger, an die der SMTP-Server die Mails zustellen muss. Der Mail-Header sieht der Anwender. BCC Empfänger sind daher im Mail-Header nicht enthalten sondern nur im Envelope Header.

Mit der ICS-Datei als Anlage kommt nun eine dritte Empfängerliste dazu. Im Mail-Header steht klassischerweise nur der Absender, die Empfänger und der Betreff. Die eigentliche Termininformation steckt in einer ICAL-Anlage. Dennoch finden sich im SMTP-Header zwei Felder:

Feld Einladung Update Absage
x-ms-exchange-calendar-series-instance-id:

In x-ms-exchange-calendar-series-instance-id steht wohl eine binäre ID, die wohl proprietär für Microsoft ist und bei allen Mails unverändert erhalten blieb.

--boundary....
...
Content-Type: text/calendar; 
charset="utf-8"; 
method=REQUEST
...
Content-Type: text/calendar; 
charset="utf-8"; 
method=REQUEST
...
Content-Type: text/calendar; 
charset="utf-8"; 
method=CANCEL

Bei einer Einladung von einem UNIX-System habe ich auch folgende Einbindung als Anlage gesehen.

--_004_212342JavaMailLINUX1_
Content-Type: text/calendar; name="einladung.ics"
Content-Description: calendar1.ics
Content-Disposition: attachment; filename="einladung.ics"; size=10187;
	creation-date="Tue, 02 Feb 2022 14:53:17 GMT";
	modification-date="Wed, 03 Feb 2022 14:37:08 GMT"
Content-ID: <9D0A2AB5DF21EC4F9E5B74F964838CE7@eurprd08.prod.outlook.com>
Content-Transfer-Encoding: base64

In dem Fall zeigt Outlook keine Mail mit einer ICS-Anlage zum Anklicken an, sondern wechselt direkt in die Terminanzeige.

Interessant ist dabei, woher Outlook welche Informationen nimmt, da es immer mehrere Quellen gibt:

Feld Quelle Quelle

Titel der Einladung

ICS:SUMMARY

Den Text "TestFC Einladung" übernimmt Outlook aus dem Feld "SUMMARY" der ICS-Datei. Er ignoriert also den "Subject" aus dem SMTP-Header oder andere Quellen

Body der Einladung

SMTP:Body

Diese Information bezieht Outlook nun wieder aus dem Body der Mail.

 Die Testmail hatte sowohl einen TEXT als auch einen HTML-Body. Je nach ihren Präferenzen wird einer davon angezeigt. Outlook ignoriert hier die Felder "Description" und "X-ALT-DESC" aus der ICS-Anlage

Termindaten

ICS

Der Start und Ende-Termin u.a. kommt allerdings wieder aus der ICS-Datei. Dafür gibt es ja keine Felder in der Mail sebst

Maildatum

SMTP:Date

Das Datum, wann die Einladung versendet wurde, kommt aus dem "Date"-Feld des SMTP-Headers

In den meisten Fällen senden Client heute heute eine Multipart-Mime-Message mit einer Text-Version, einer HTML-Version und der eigentlichen ICS-Datei. In der Multipart Mime-Boundary ist bei der "Method" aber auch schon ein Unterschied bei der Absage zu sehen.

ICS-Felder

Interessanter ist dann die ICAL-Anlage, die ich aus der Mail mittels BASE64-Decodierung extrahier habe. Ich geben hier nur die Abschnitte wieder, die mir wichtig erscheinen und sich unterscheiden

Feld Einladung Update Absage
METHOD
REQUEST
REQUEST
CANCEL
PRIORITY
5
5
1
DTSTAMP
20230209T084405Z
20230209T084423Z
20230209T084441Z
SEQUENCE
0
1
2
X-MICROSOFT-CDO-APPT-SEQUENCE
X-MICROSOFT-CDO-OWNERAPPTID
X-MICROSOFT-CDO-BUSYSTATUS
X-MICROSOFT-CDO-INTENDEDSTATUS
X-MICROSOFT-CDO-ALLDAYEVENT
X-MICROSOFT-CDO-IMPORTANCE
X-MICROSOFT-CDO-INSTTYPE
X-MICROSOFT-DONOTFORWARDMEETING
X-MICROSOFT-DISALLOW-COUNTER
X-MICROSOFT-LOCATIONS
0
-989255705
TENTATIVE
BUSY
FALSE
1
0
FALSE
FALSE
[]
1
-989255705
TENTATIVE
BUSY
FALSE
1
0
FALSE
FALSE
[]
2
-989255705
FREE
FREE
FALSE
2
0
FALSE
FALSE
<leer>
BEGIN:VALARM
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
ACTION:DISPLAY
END:VALARM
VALARM
REMINDER
-PT15M
DISPLAY
VALARM
VALARM
REMINDER
-PT15M
DISPLAY
VALARM
<leer>
<leer>
<leer>
<leer>
<leer>

Der Unterschied zwischen einer erste Einladung und einem Update ist minimal. Eigentlich hat sich nur die "SEQUENCE" geändert. Erst bei einer Absage wird neben der SEQUENCE auch noch die METHOD und die PRIORITY geändert. Zusätzlich ändern sich noch ein paar Microsoft-spezifischen Felder.

Die PRIORITY muss ein Wert zwischen 0 und 9 annehmen und anscheinend möchte Outlook mit einer "1" die höchstmögliche Priorität vorgeben. Die SEQUENCE-Nummer beginnt bei 0 muss mit jedem Update hochgezählt werden.

Feld: SEQUENCE

Wenn es manchmal hektisch zugeht, dann wird ein Termin mehrfach aktualisiert und da die Einladungen als Mails versendet werden, kann die Übertragung schon einmal unterschiedliche Wege nehmen und damit die Reihenfolge der Ankunft nicht mehr passt. Damit hier nicht ein älterer aber später eintreffende Termininformation eine schon verarbeitete jüngere Information überschreibt, muss eine "SEQUENCE" Nummer immer wieder hochgezählt werden. Sie beginnt in der Regel bei "0" und wird mit jedem Update erhöht.

Der Anwender sieht dies auch, wenn eine solche veraltete Aktualisierung im Postfach erscheint und Outlook verarbeitet diese nicht.

Wie immer gibt es aber auch hier eine Ausnahme. Bei einem CANCEL akzeptiert Outlook auch die gleiche SEQUENCE-Nummer aber sie darf nicht niedriger sein.

Feld: METHOD:CANCEL

Bei der Absage eines Termins durch die Methode "CANCEL" gibt es ebenfalls ein paar Dinge zu beachten:

  • Sequence-Nummer gleich oder höher als die vorherigen Updates
    Dies weicht von den anderen REQUEST-Optionen ab.
  • UID muss übereinstimmen
    Sonst kann Outlook nicht den passenden Eintrag finden. Es versteht sich von selbst, dass Sie möglichst eindeutige UIDs pro Termin generieren müssen. Wenn Sie mehrere Termine mit der gleichen UID haben, weil Sie z.B. fälschlicherweise mehrere PUBLISH-Einladungen angenommen haben, dann können diese mit mehreren CANCEL-Absagen natürlich nacheinander gelöscht werden.
  • Immer nur ein Termin
    Ein Cancel entfernt bei Zustimmung des Benutzers immer nur einen Termin. Wenn Sie z.B. zwei Elemente mit der gleichen UID per PUBLISH eingetragen haben, dann wird nur der erste gefundene Eintrag entfernt. Mehrfache "CANCEL"-Meldungen räumen dann immer einen weiteren Termin weg.
  • Outlook markiert zur Löschung beim Öffnen
    Sobald Sie die CANCEL-Nachricht öffnen, wird der Termin im Kalender schon "weiss" gekennzeichnet aber noch nicht gelöscht

    Wenn Sie die Mail mit der Absage ohne weitere Aktion schließen, dann bleibt der Termin in dem "Abgesagt"-Status aber weiter im Kalender stehen.
  • Outlook löscht schon beim Druck auf den Button
    Wenn Sie in der Absage aber oben auf den Button drücken, dann wird der Termin im Kalender ohne weitere Rückfrage entfernt. Es kommt zwar noch eine Rückfragen, aber die bezieht sich auf die Löschung der Absagemail selbst.
  • Absage ohne Termin
    Wenn Sie eine Absage für einen Termin bekommen, den Sie schon lange selbst gelöscht haben, dann zeigt Outlook dennoch die Absage ohne weitere Hinweise an. Bestätigen Sie die Absage einfach, damit die Mail gelöscht wird.

Achtung:
Outlook prüft bei einer Absage nur die UID und die korrekte SEQUENCE. Wenn ich z.B. über einen Trojaner oder schlechten Code die UID eines Termins erraten oder ermitteln kann, reicht eine Mail mit einer entsprechend präparierten ICS-Datei, um den Termin im Kalender zu löschen.

ICS:METHOD

Wie ein Client mit den Daten umgehen soll, wird über das Feld "METHOD" definiert. Die eigentliche RFC5545 definiert dazu keine Werte.

No methods are defined by this specification. This is the subject of other specifications, such as the iCalendar Transport- independent Interoperability Protocol (iTIP) defined by [2446bis].
https://www.rfc-editor.org/rfc/rfc5545#section-2.1

Stattdessen wird auf "2446bis iCalendar Transport-Independent Interoperability Protocol (iTIP)", Work in Progress, April 2009" verwiesen, die im Dezember 2009 zur RFC 5546 geworden ist.

Am geläufigsten sind die folgenden Metehoden: 

Methode Beschreibung

REQUEST

Das ist die normale Methode um einen Termin anzufragen. Die RFC 5545 schreibt dazu:

"REQUEST" refers to the method for requesting a scheduling calendar component be created or modified
Quelle: https://www.rfc-editor.org/rfc/rfc5545#section-2.1

Der Anwender bekommt den Termin mit seinem Kalender angezeigt, um die Vereinbarkeit zu prüfen und darauf zu reagieren.

Auch Updates von Terminen sind immer wieder ein Request mit der gleichen UID und höheren SEQUENCE.

CANCEL

Mit diesem Verb kann der Organisator einen früher versendeten Termin wieder absagen. Er muss nur die UID und eine gleiche oder höhere SEQUENCE mitliefern.

PUBLISH

Ein PUBLISH wird normal verwendet, wenn Sie ein oder mehrere Termine in einer ICS-Datei als Kalender-Feed bereitstellen. Outlook und andere System können so einen Datenquelle z:B. per HTTPS abonnieren und einbinden.

Sie können aber auch eine ICS-Datei per Mail als Einladung mit der METHOD=PUBLISH versenden. Das ist aber nicht sehr freundlich, denn der Anwender bekommt dann den Termin ohne die Kalendervorschau angezeigt:

Zudem ignoriert Outlook die SEQUENCE-Nummern und UIDs, so dass Termine immer wieder neu angelegt werden. Ein "Update" einer früheren Einladung ist nicht möglich, es sei denn ich sende vorher ein "CANCEL" zum Entfernen des vorherigen Termins.

Verwenden Sie daher PUBLISH besser nicht mit einem per Mail versendeten Termin.

REPLY

Analog dazu kann der Anwender dann auf einen Termin mit einer Zusage antworten, indem er eine ICS-Datei zurücksendet. Dazu ist es natürlich erforderlich, dass die ICS-Datei die Teilnehmer auch dazu auffordert, z.B. durch einen Eintrag wie:

ATTENDEE;ROLE=OPT-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=user1:mailto:user1@msxfaq.de

Die RFC 5545 selbst dokumentiert keine Methoden:

No methods are defined by this specification. This is the subject of other specifications, such as the iCalendar Transport- independent Interoperability Protocol (iTIP) defined by [2446bis].
https://www.rfc-editor.org/rfc/rfc5545#section-2.1

Stattdessen wird auf "2446bis iCalendar Transport-Independent Interoperability Protocol (iTIP)", Work in Progress, April 2009" verwiesen, die im Dezember 2009 zur RFC 5546 geworden ist

Outlook Testserie

Natürlich habe ich Outlook etwas gestresst, indem ich eine ICS bzw. EML-Datei immer wieder etwas angepasst und an Outlook übergeben habe. Hier ein paar Testergebnisse:

  • Erneute Einladung mit anderem Text aber gleicher UID/SEQUENCENUMBER
    Kein Update. Outlook erkennt den bestehenden Termin aber aktualisiert ihn nicht
  • Erneute Einladung mit anderem DESCRIPTION aber gleicher UID/SEQUENCENUMBER
    Kein Update. Outlook erkennt den bestehenden Termin aber aktualisiert ihn nicht
  • Erneute Einladung mit anderem SUMMARY aber gleicher UID/SEQUENCENUMBER
    Kein Update. Outlook zeigt den Termin mit geändertem Betreff an, erkennt den bestehenden Termin aber aktualisiert ihn nicht
  • Erneute Einladung mit X-ALT-DESC aber gleicher UID/SEQUENCENUMBER
    Kein Update. Outlook zeigt den Termin mit geändertem Betreff an, erkennt den bestehenden Termin aber aktualisiert ihn nicht
  • Erneute Einladung mit geändertem X-ALT-DESC, gleicher UID und SEQUENCENUMBER+1
    Termin wird aktualisiert
  • Beliebige Änderungen mit SEQUENCENUMBER <= höchste verarbeitete Nummer
    Das Element wird angezeigt aber nicht übernommen.
  • Änderung von DTSTAMP
    Hat keine Auswirkungen.
  • ICS-Datei mit mehreren VEVENT-Einträgen per Doppelklick importieren
    Es wird immer nur der erste Eintrag importiert
  • ICS-Datei mit mehreren VEVENT-Einträgen per "Datei - Import" importieren
    Es werden alle VEVENT-Einträge in den Kalender importiert. Bestehende Termine werden anhand der UID gefunden und aktualisiert, wenn DTSTAMP neuer und die SEQUENCE nicht niedriger ist.

Outlook orientiert sich also wie erwartet an der UID zum Wiedererkennen des Termins und übernimmt nur Elemente mit einer höheren SEQUENCE-Nummer. Der Titel des Termins wird aus dem Feld "SUMMARY" übernommen. Beim Import einer ICS-Datei wird der Inhalt von "DESCRIPTION" nur dann in Outlook sichtbar, wenn eine X-ALT-DESC nicht gepflegt ist. Beide Felder werden aber ignoriert, wenn die Einladung als Mail zugestellt wird.

Teams in ICS

Eine Besonderheit sind natürlich Termine in Verbindung mit Microsoft Teams. Natürlich werden die für das Team-Meeting erforderlichen Zugangsdaten sowohl in die TEXT als auch HTML-Body der Mail eingetragen, so dass der Empfänger selbst ohne ICS-kompatiblen Client das Meeting verstehen und beitreten kann. Hier am Beispiel von Thunderbird, der gut die SMTP-Body-Version anzeigt:

Zusätzlich finden wir aber auch im SMTP-Header der Einladung die Links zum Teams-Meeting.

-MICROSOFT-SKYPETEAMSMEETINGURL:https://teams.microsoft.com/l/meetup-join/
 19%3ameeting_xxxx%40thread.v2/0?context=%7b%22Tid%22%3a%22<tenantid>%22%2c%22Oid%22%3a%22<meetingid>0186effe82c%22%7d
X-MICROSOFT-SCHEDULINGSERVICEUPDATEURL:https://api.scheduler.teams.microsof
 t.com/teams/<tenantid>/<meetingid>/19_meeting_<session>@thread.v2/0
X-MICROSOFT-SKYPETEAMSPROPERTIES:{"cid":"19:<session>@thread.v2"\,"private":true\,"type":0\,"mid":0\," rid":0\,"uid":null}
X-MICROSOFT-ONLINEMEETINGCONFLINK:conf:sip:frank.carius@netatwork.de\;gruu\
 ;opaque=app:conf:focus:id:teams:2:0!19:meeting_xxxxxxx-thread.v2!xxxxxxxxxxxxx

Irgendwie komisch, dass hier noch der Name "Skype" statt Teams oder SkypeforBusiness auftaucht. Aber vielleicht gibt es doch das ein oder andere Programm, welches genau diese Header auswertet, um dem Anwender den Beitritt ins Meeting zu vereinfachen.

Teilnehmer verbergen

Sie haben nun gelernt, dass die Empfänger einer Einladung und die Teilnehmer in der ICS-Einladung selbst zwei unterschiedliche Listen sind. Die Empfänger der Mail können Sie recht einfach mit "BCC" verbergen, so dass die Teilnehmer nicht wissen, wer noch die Einladung bekommen hat. Die Teilnehmer in der ICS-Datei sind damit aber dennoch weiterhin bei allen Empfängern sichtbar. Dies kann aber zumindest in Outlook for the Web gesteuert werden. Hier gibt es einen Punkte "Teilnehmer verbergen":

Damit kann ich in der ICS-Datei die Teilnehmerliste ausblenden, dass kein Empfänger diese mehr sieht. In der ICS-Datei gibt es dann keine "ATTENDEE"-Felder mehr sondern nur noch der ORGANIZER" ist sichtbar. Leider ist diese Funktion wohl in Teams, Outlook und anderen Clients nicht verfügbar.

Zusammenfassung

ICS-Dateien und deren Spezifikation in der RFC5545 und RFC5546 beschreiben sehr gut die Funktion und Definition. Für Anwender ist es aber erst einmal ungewöhnlich, wenn ich eine Termineinladung an mehrere Personen per Mail sende und in der ICS-Anlage eine andere Teilnehmergruppe adressiert ist. Für Outlook und Exchange ist die Mail und deren Empfänger nur das Transportmittel der Einladung aber nicht mit den Teilnehmern identisch. Alle Funktionen einer Mai, inklusive der Versand per "BCC" funktioniert nicht, da in der ICS-Datei die Teilnehmer aufgeführt werden. Das mag überraschen aber ist eigentlich auch logisch.

Weitere Links