This module creates a schedule of messages related to a specific entity type/bundle, and sends them on the appropriate day.
The initial use case is to send a series of reminders of a membership expiration. This module provides the ability to add multiple scheduled messages to an entity type, and send them as a membership nears and passes expiration.
For the initial use case, Scheduled Messages are implemented as a plugin that may be attached to an entity type and bundle. All entities created from that bundle inherit the message schedule.
Update: The 2.x branch of this module has been completely refactored. Now a scheduled message is an Entity type, not a plugin. You create a scheduled message entity type (a scheduled message template) for each message template you want to automate, link it to a triggering entity type/bundle/field and a recipient entity type/bundle, and set some basic conditions. This creates scheduled message instances for each combination of trigger and recipient, and at the calculated send time, it creates and sends the actual message using either Message or Easy Email module.
Whenever the triggering entity is updated, Scheduled Messages updates its list of messages related to that entity. This is particularly useful to allow different messages based on different states of the source entity.
Example - Membership term expiration
The scenario we built this for is for a membership system. The membership system has a "membership term" that has an "active" date range, and a "revoke" date. In this system, the period between the end date of the active rage and the "revoke" date is a grace period.
The membership_term entity type has an associated State Machine workflow, with states of Pending, Active, Expiring, Expired, and Renewed.
With Scheduled Message, we have set up 4 reminder emails:
- 4 weeks ahead of expiration date
- 1 week ahead of expiration date
- 3 weeks after the expiration date
- 1 week before the revocation date
The first two only go out if the membership term is "Active." The second two only go out if the membership term is "Expiring". This prevents messages from getting sent if the member has already renewed.
Dependencies
Currently needs either:
... or Easy Email.
Basic approach
First, install the Scheduled Message submodule for the message template system you want to send.
Next, identify (or create) the "trigger entity" -- for example, an RNG event, a commerce order, some other notification date on a node, etc.
For the recipient entity, make sure there is an email address, and identify (or create) an entity reference between the trigger and the recipient (this can be on either side...)
For the message entity, create a message template using whichever module you want to use. You can define fields on this template to receive values -- entity references, text fields, etc for Scheduled Message to populate from either the Trigger or the Recipient.
Then, under Admin -> Structure -> Scheduled Message Templates, add a scheduled message template. There are 4 sections to configure:
- Trigger
- Recipient
- Conditions
- Message template
Trigger
The Trigger section identifies an entity type, bundle, date field, and a time offset for triggering the scheduled message.
Recipient
The Recipient section identifies an entity type, bundle, and email field name.
Conditions
The Condition section contains a list of built-in "conditions", and there is an api to inject your own conditions (not yet documented). The built-in ones include:
- Trigger status (e.g. the trigger entity must be published)
- Recipient state (a specific value to match in the recipient state field)
- Recipient state field (a field on the recipient to check for a specific value -- e.g. workflow state, string)
- Link entity (which entity has the entity reference field -- trigger, or recipient?)
- Link Field (machine name of the entity reference field)
Message
Message module to use (plugin-driven, plugins for Message and Easy Email -- but Message is currently untested)
Template ID (the message template or easy email template id)
Field Map (a text area where you can create a mapping, 1 per line, from a field on the trigger or recipient to the message template, e.g. to populate merge fields)
Scheduling algorithm
I borrowed the basic approach from Webform's scheduled message feature.
When any entity of a type that is configured for scheduled messages is saved, Scheduled Message loads the schedule for this entity type and bundle, and creates an individual "scheduled message" item for all matching pairs, but only if the calculated date is in the future.
When the date arrives, during a cron run the conditions are checked, and if they pass, it creates the message from the designated template, populates values using the map, and adds the actual message to a queue. A queue worker then sends all the queued messages.
Finally, if the configuration entity for an entity type configured to use Scheduled Messages is changed, it adds all of the entities of that type to a queue to update the set of messages that should be sent. This process ignores messages that would have a past "send date" (or have already been sent) but adds any new messages and updates existing ones.
Current status
Right now this only works with custom entity types that implement a GetMessages method on the configuration entity type, which returns a ScheduledMessagePluginCollection. Also the EditForm for the entitytype needs to include and process the plugin collection.
Completely revamped! This should work for a wide variety of uses. The administration form needs a lot of love, and I'm sure there are a lot of corner cases that won't work -- feel free to file issues/provide patches...
Update January 2024: We no longer use/maintain this module -- we now use ECA and Views for scheduled messages, with Easy Email. Send a message if you're interested in taking it over! - John
Project information
Seeking new maintainer
The current maintainers are looking for new people to take ownership.- Project categories: E-commerce, Site structure
8 sites report using this module
- Created by freelock on , updated
Stable releases for this project are covered by the security advisory policy.
There are currently no supported stable releases.
Releases
Drupal 10 compatibility and bug fixes
Development version: 2.x-dev updated 29 Dec 2022 at 00:47 UTC

