linagora / tmail-backend

GNU Affero General Public License v3.0
36 stars 17 forks source link

ICS reply extention #934

Closed chibenwa closed 4 months ago

chibenwa commented 6 months ago

Context

From within Twake mail I want to have some base level interactions with my calendar.

Hopefully we would like the integration to be as "light" as possible...

This ticket is thus an attempt to formulate an easier approach satisfying our client needs in a pragmatic fashion.

Scope

In order to make this achievable I propose to simplify the scope:

Compared to b. let's not make it possible to see from twake mail attandance to a given event.

Let's also not target to be warned about my availability for a given event from within twake mail.

User will be prompted with a simple choice yes / no / maybe that will act as "shoot and forget".

How

Twake mail will provide an extension that would take the original ICS, patch event attendance for the connected user, and sends it back to the sender. (this is the standard way to inter-operate calendars together....)

We could position a custom header on this outgoing ICS traffic allowing us to ingest it via the ICS exention we already have in James into the calendar thus updating the attendance in the calendar too.

Given I have a mail with the following ICS:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Sabre//Sabre VObject 4.1.3//EN
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:8eae5147-f2df-4853-8fe0-c88678bc8b9f
TRANSP:OPAQUE
DTSTART;TZID=Europe/Paris:20240223T160000
DTEND;TZID=Europe/Paris:20240223T163000
CLASS:PUBLIC
SUMMARY:Simple event
ORGANIZER;CN=comptetest15.linagora@avocat.fr:mailto:comptetest15.linagora@a
 vocat.fr
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVI
 DUAL:mailto:btellier@linagora.com
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVI
 DUAL:mailto:other@linagora.com
ATTENDEE;PARTSTAT=ACCEPTED;RSVP=FALSE;ROLE=CHAIR;CUTYPE=INDIVIDUAL:mailto:c
 omptetest15.linagora@avocat.fr
DTSTAMP:20240222T204008Z
SEQUENCE:0
END:VEVENT
END:VCALENDAR

When I call

{
    "using": ["urn:ietf:params:jmap:core", "com:linagora:params:calendar:event"],
    "methodCalls": [
        [ "CalendarEvent/accept", {
            "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
            "blobIds": ["0f9f65ab-dc7b-4146-850f-6e4881093965"]
        }, "c1"]
    ]
}

Then the following ICS will be generated:

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REPLY
BEGIN:VTIMEZONE
TZID:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:8eae5147-f2df-4853-8fe0-c88678bc8b9f
DTSTAMP:20240222T204343Z
SEQUENCE:0
DTSTART:20240223T150000Z
DTEND:20240223T153000Z
SUMMARY:Simple event
ORGANIZER;CN=comptetest15.linagora@avocat.fr:mailto:comptetest15.linagora@a
 vocat.fr
ATTENDEE;PARTSTAT=ACCEPTED:mailto:btellier@linagora.com
END:VEVENT
END:VCALENDAR

IE:

Wrap it in an email from connected user to the organizer of the ICS and send it.

The HTML display can be taken from OpenPaaS.

Internationalisation

As this is user facing, I8N will be needed.

We can provide a set of 3 templates per language on the classpath.

The language can then be passed into the JMAP method call:

{
    "using": ["urn:ietf:params:jmap:core", "com:linagora:params:calendar:event"],
    "methodCalls": [
        [ "CalendarEvent/accept", {
            "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
            "blobIds": ["0f9f65ab-dc7b-4146-850f-6e4881093965"],
            "language":"fr"
        }, "c1"]
    ]
}

Similarily we would also implement the CalendarEvent/reject and CalendarEvent/tentative JMAP methods.

Arsnael commented 5 months ago

I don't really get something...

If we send a reply of the attendance by patching the ics by mail, how is that gonna update the event on the calendar's organizer if it's from a mail he receives in his tmail inbox for example?

If it's just a notification back to the sender that you will attend or not the event, without an update on the calendar... I hardly see the point here?

I'm not convinced your lambda lawyer user will be happy with that for example^^'

quantranhong1999 commented 5 months ago

Not sure I get all the context.

But I tried a bit of invitations from Google Calendar and Outlook Calendar.

For Google Calendar, TMail frontend still succeeds to extract the yes / no / maybe button. Clicking those would send a mail back the the GMail sender about the event reply.

While this is not the case for Outlook Calendar. The invitation from Outlook Calendar has no yes / no / maybe buttons therefore TMail frontend can not do anything to allow users to tell the Outlook invitator about the event reply.

I guess this extension is more about notifying Outlook invitators about the event reply?

Then likely tmail frontend should only call this extension if it can not extract the yes / no / maybe buttons. Otherwise for example Google invitators could receive 2 mails about the event reply.

Arsnael commented 5 months ago

Ok misunderstood.

Take this as context:

I guess this extension is more about notifying Outlook invitators about the event reply?

It seems so yes

Then likely tmail frontend should only call this extension if it can not extract the yes / no / maybe buttons. Otherwise for example Google invitators could receive 2 mails about the event reply.

Hmmm maybe the result of the current workaround in place on TMail at the moment? I guess That could change? Unsure, but good raise from you, might be good to test it as well

So the work could be divided into 5 issues:

Regarding the internationalization, we could first go with dummy template on previous tasks, then do the proper refactoring for introducing proper templates depending on the language. Let's say we have two languages at first: fr (french) and en (english). There should be a template from each language for each method (2 x 3 = 6). Default templates would be provided under a default folder. The template folder should be configurable, to allow organizations customizing their own templates.

vttranlina commented 5 months ago

IMO,


Q:

I18N will be needed.

We will hard-fixed code for the template message? Or should accept add/update template it via web-admin?

Arsnael commented 5 months ago
  • We already CalendarEvent/parse, and almost all fields can be extracted from ics => We don't need more task for parsing

Not about parsing here, more about taking the same ICS and tranforming it into a reply one by just modifying a few fields with the help of the ical4j lib?

  • the click yes/no/maybe will be the responsibility of the client (mobile), james server just receives the request with method + ids

Yes, obviously

  • After receiving the request from a client, James will

    • JMAP HTTP response

Yes

  • Send notification emails to relevant people

Only to the sender, we drop of the other attendants to keep it simple

  • do another internal job (maybe send a message to a special queue?, that I remember we did similar with GCSSara)

Not that I understood of

Q:

I18N will be needed.

We will hard-fixed code for the template message? Or should accept add/update template it via web-admin?

As explained, default hardcoded templates under a default folder. The folder location will be configurable, which would allow entities to overrides default templates with their own

vttranlina commented 5 months ago

Not about parsing here, more about taking the same ICS and tranforming it into a reply one by just modifying a few fields with the help of the ical4j lib?

I am still a bit confused here, The generated "reply invite.ics" file (when Alice clicks YES) will be done by Thunderbird or James?

Arsnael commented 5 months ago

TMail, it's tmail feature

vttranlina commented 5 months ago

Just quickly searched ChatGPT When Alice clicks YES/NO/MAYBE, the imap client will send the IMAP Command to update flags this email to the Mail server C: C0001 STORE 42 +FLAGS (\Yes_join_event) .

If I understand correctly, Tmail needs an IMAP processor, to parse commands, generate reply ICS file + reply email

quantranhong1999 commented 5 months ago

If I understand correctly, Tmail needs an IMAP processor, to parse commands, generate reply ICS file + reply email

This is more a JMAP and web mail extension. The blue bar originally is only for JMAP and web mail for example.

chibenwa commented 5 months ago

If I understand correctly, the frontend team can also position flags so that TMail remembers answers it sent.

However this is another topic.

BTW to my knowlege those keywords are yet-to-be registered on the IANA registry: https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml

quantranhong1999 commented 5 months ago

I think in the future we can improve this feature a bit.

Today I think when the User clicks multiple times (maybe the user missed clicks or the network is laggy so the user clicks multiple times) at the Yes/No/Maybe button, then TMail server likely would send a bunch of spam replies to the sender.

Solution: Maybe 1 table in the database to store the state of the reply, or frontend side can set the JMAP keyword to remember if the user sent ICS reply for this mail.

Arsnael commented 5 months ago

@quantranhong1999 future maybe? But I think for now the scope has been reduced to something rather simple. Quoting from the initial description:

User will be prompted with a simple choice yes / no / maybe that will act as "shoot and forget".

I think "shoot and forget" is explicit enough :)