The Architecture of Courier

Courier is a module that was created to fill the communication requirements of RNG, an event management module. Courier provides an API to define re-usable templates which users can fill with content and tokens. When a rule is triggered, Courier determines which templates should be used for each user. The templates are "rendered" by filling in tokens and are added to a transmission queue. The queue is then worked during cron runs.

Some systems outlined here will appear familiar if you have used Messaging module for Drupal 6.

A number of entities and terminology are used in Courier, these are:

  • Template aka Channel aka Message: Each of these words are used interchangeably. A template represents a communication in storage (template), it is also responsible for transmitting itself (channel). This entity must implement ChannelInterface interface. A template which has its tokens filled and prepared for transmission is a 'message'.
  • Template Collection: A reference to templates, one of each template type.
  • Context: represents a common context for sending a message. A CourierContext contains tokens that are available and must be filled for each template on a Template Collection.
  • Identity: an entity representing a person, such as Drupal users, LDAP contacts, address book contact, etc.
  • Message Queue: an entity referencing multiple message entities. Courier will attempt to send each message in order of identity' preference until a message is sent.

Diagram

Flow

The following is a story of a message as implemented by the RNG module.

Message preparation

Courier defines template entities, which are a Drupal entity representation of a message.

An email template entity has fields such as 'email', 'subject' and 'body'.

A sms template has field such as 'phone_number' and 'message'

Courier implements TemplateCollection, which is an entity which references entities of one each available template entity type.

A TemplateCollection has references to one Email entity and one SMS entity.

An administrator fills the fields on the template entities with content and tokens.

Diagram

User fills fields on Email entity:

Subject: New registration for [node:title]

Body: Hi [identity:label], To view the registration go to [registration:url]

User fills field on SMS entity:

Message: [identity:label], a new registration was created for you. Go here to view: [node:url].

Message transmission

A rule is triggered, its action is to transmit a message to a user. The TemplateCollection for the rule is loaded. The users preferred channel is determined:

User has selected SMS as his preferred contact method.

The SMS entity from the TemplateCollection is loaded. Identity information is applied to the entity from a IdentityChannel plugin. The plugin modifies values on the template entity:

phone_number: users phone number.

Tokens inside fields on the SMS are detected and replaced with context relevant values:

message: user, a new registration was created for you. Go here to view: http://example.com/node/29.

The original SMS entity is cloned, the modified field values are saved to a new SMS entity. The SMS entity is added to the trasmission queue.

Diagram

Cron runs, it finds any messages that need to be transmitted:

The new SMS entity is loaded.

An attempt to transmit the message is made. If it is unsuccessful, then it will try a number of times later.

Implementation details

Identity tokens

Identity tokens are always automatically applied, there is no need to define identity tokens in CourierContext.

Entities

All Courier entities are created by module depending on Courier, via the API. Users do not have direct ability to create TemplateCollections, Templates, CourierContext etc.

IdentityChannel plugin

An IdentityChannel plugin needs to be supplied for each identity type / channel type combination. Courier supplies a plugin mapping from Drupal users (identity) to Email (channel).

Channel preferences

Identities have the option to choose channels as as ordered multiple preference. For example: a user can have the following channel preference:

  • [Enabled] SMS
  • [Enabled] Email
  • [Disabled] InstantMessage

Courier will render all enabled channels for the identity. If any of the channels fail, then the next channel in the preference list is chosen. When one of the templates is successfully sent; all template entities will be purged from the system. Some valid reasons for channel failure are: SMS message too long, phone number incorrect, InstantMessage contains invalid characters, etc.

Download the module on drupal.org.

Cover photo (unmodified): General Post Office mail sorting room, Wellington c.1900s by Archives New Zealand. License CC BY-SA 2.0