Extensible James server: Connecting emails with OpenPaaS Calendar

The James project gives us a working mail server to play with, and customizing the behaviour of this server to implement business features is easy.

At Linagora, as part of the OpenPaaS solution, we heavily rely on the James server, and actively develop features using the functionalities of James. Today this post aims at presenting you how James allows to decorate email with calendar events.

On the right of these emails, you can see a calendar icon indicating this email contains an event.

Well, Inbox adds aUX component that interacts with the OpenPaaS calendar. It is displayed only if the email contains some information about an event: invitation / modification, for instance. It allows you from the Inbox module to interact with the calendar module.

In the middle of this message, a bar is appended to give events information, and control on Calendars from Inbox.

Cool! But… Where is James?

James detects that the mail is related to an event. That for instance it contains a text/calendar mime attachments. James parses the given attachment, publish its details on a message queue. OpenPaaS calendar listens to this message queue, and store the event information (that can be later on retrieved by INBOX). We also need to tell INBOX about this event. The way we do it is by adding specific headers to the message.

The feature architecture

To implement this feature on James side, we can rely on James MTA functionalities, that can be customized through the Mailet API. A mailet represent an action, a modification or side effect applied on incoming emails. We can combine mailets together in order to build more complicated behaviour.

Under the hood, the full pipeline looks like this:

Implementation with standard James mailets: the flow of mail through ICAL related mailets

Here:

StripAttachment mailet is used to locate MimePart that are attachments and match the text/calendar format. These mime parts are then added to the email as an attribute. Attributes are information attached to Email during mailet processing and allow passing information around mailets without actually altering the mail. It allows writing composable mailets.

MimeDecodingMailet reads this mime part and retrieves the underlying binary file, also attached to an attribute.

ICalendarParser mailet then parses ICal data, again attached as an attribute.

— We can then from the ICAL data edit the mail to put relevant headers on it with the ICALToHeader. This allows Inbox to know this email is linked to a specific event, and how to process to retrieve it from OpenPaaS calendar.

— We then have a ICALToJsonAttribute for transforming the ICAL data to JSON, also stored as an attribute.

— The AmqpForwardAttribute then post the JSON for OpenPaaS calendar module on a RabbitMQ message queue.

The associated configuration looks like this:

Portion of mailetcontainer.xml to configure the ICAL pipeline related mailets.

All the mailets are contributed as core James components. This means one can easily implement similar features, with only editing the configuration. This also demonstrate James Inbound capabilities, and how one can build an advanced feature with small, well defined, generic building block: mailets.