Meeting Invitations : accepter une invitation depuis SnappyMail, sans jamais fabriquer d’iTIP
SnappyMail sait afficher une pièce jointe
.ics— le pluginics-viewerle fait bien. Mais rien ne sait agir dessus : l’invitation doit être ressaisie à la main dans l’agenda. Ce plugin ajoute l’étape manquante. Il est publié sous AGPL.
Ce que ça fait
Quand un message porte une partie text/calendar dont la méthode est REQUEST, le plugin affiche le résumé de la réunion, l’organisateur, l’horaire et le lieu, avec trois boutons : Accepter, Provisoire, Refuser. Le choix positionne votre ATTENDEE;PARTSTAT et fait un PUT de l’événement dans votre agenda.
C’est tout. Et c’est délibérément tout.
La réponse à l’organisateur n’est pas construite ici
Le point de conception central. Sous RFC 6638, l’ordonnancement appartient au serveur CalDAV : stocker l’événement dans votre propre agenda avec votre PARTSTAT positionné amène le serveur à générer et remettre lui-même le METHOD:REPLY, et à marquer l’ORGANIZER d’un SCHEDULE-STATUS.
Conséquence directe : le plugin ne construit aucun iTIP et n’a aucun chemin SMTP. Aucune réponse n’y est composée, envoyée ni mise en file.
C’est la bonne façon de faire, et c’est aussi la plus sûre : la surface d’attaque d’un plugin de webmail qui composerait et enverrait des messages au nom de l’utilisateur est sans commune mesure avec celle d’un plugin qui fait un PUT authentifié dans l’agenda de cet utilisateur.
Vérifié contre Cyrus IMAP : un PUT portant PARTSTAT=ACCEPTED revient avec SCHEDULE-STATUS=1.1 sur l’organisateur — la réponse est bien partie.
Prérequis : un serveur CalDAV avec l’ordonnancement activé. Sur Cyrus, caldav_allowscheduling, plus imipnotifier pour la remise par courriel.
Configuration
Administration → Plugins → invitations :
| Réglage | Exemple |
|---|---|
| Gabarit d’URL CalDAV | https://dav.example.com/dav/calendars/user/{user}/Default/ |
| Domaine DAV par défaut | example.com — les adresses de ce domaine utilisent la partie locale seule ; vide = toujours l’adresse complète |
| Vérifier le certificat du serveur DAV | activé |
{user}, {email}, {login} et {domain} sont substitués par compte. Rien n’est codé en dur : sans gabarit configuré, le plugin refuse d’agir plutôt que de deviner une URL. L’authentification réutilise les identifiants IMAP du compte.
Annulations et révisions : le détail qui fait la différence
C’est là qu’un plugin d’invitations se juge. Répondre à un vieux courriel ne doit pas ressusciter une réunion.
SEQUENCE ordonne les révisions d’un même UID (RFC 5545 §3.8.7.4). Avant de répondre, le plugin compare l’invitation à la copie déjà présente dans l’agenda et refuse une invitation supersédée : accepter un ancien courriel après un report ne peut pas rétablir l’ancien horaire. Une révision plus récente remplace la copie stockée, comme il se doit.
METHOD:CANCEL est reconnue : la réunion est présentée comme annulée et un bouton unique la retire de l’agenda. Annuler un événement jamais accepté n’est pas une erreur.
Subtilité : une annulation est aussi enregistrée. Supprimer l’événement retire précisément la copie à laquelle la vérification de SEQUENCE se compare ; sans cette trace, le courriel d’invitation d’origine resterait acceptable après coup — la réunion reviendrait, et l’organisateur recevrait une réponse lui annonçant que vous avez accepté une réunion annulée. Une révision ultérieure reste acceptée : c’est l’organisateur qui rétablit la réunion, pas un vieux courriel qu’on répond deux fois. Les traces expirent une fois la réunion passée.
Notes et limites
Assumées, listées dans le README :
METHOD:REPLYest la réponse d’un autre participant : aucune action requise ici.- L’invitation est confrontée à l’adresse du compte et aux identités configurées, donc une invitation envoyée à un alias est reconnue.
- L’événement est stocké sans
METHOD: un agenda contient des événements, pas des messages d’ordonnancement. - Les détails sont lus uniquement dans le
VEVENT.VTIMEZONEporte son propreDTSTARTpar règle de transition — lire le premier du document affiche une date en 1905 au lieu de celle de la réunion. Le genre de piège qu’on ne voit qu’en le rencontrant.
Licence
AGPL-3.0-or-later, la même licence que SnappyMail, dans lequel le plugin se charge. Les versions jusqu’à la v1.2.0 incluse ont été publiées sous MIT ; cette concession est irrévocable pour ces copies — qui a obtenu le plugin sous MIT le conserve sous MIT.
→ https://github.com/FathiBenNasr/snappymail-invitations
Côté organisateur, l’envoi d’invitations depuis l’agenda est traité par notre fork CalDAV.
Vous exploitez une messagerie Cyrus, Postfix ou Sendmail et vous voulez un webmail avec agenda et contacts, hébergé chez vous ? Découvrez nos services ou parlons-en. Et suivez-nous sur GitHub.