This is a proposal for a feature I'd like to add to the Echo extension. I thought I had better pass it by the Collaboration team before working on it, to see if it fits in with their vision for the extension's architecture.
What?
Add infrastructure to the Echo extension to enable proactive scheduled notifications.
Why?
At the moment Echo is a purely reactive extension; notifications are created from various hook functions in response to actions being taken by the user. This stops us from being able to offer nice features which require notifications to be issued at a set time:
- T2582: Remind me of this article in X days
- T153817: Notify users when their user group membership is about to expire, or has expired
- Others?
How?
The proposed implementation is to add a column event_scheduled_timestamp to the echo_event table. This column would be NULL except for events scheduled to take place in the future, in which case it would contain the timestamp of when to show the notification.
A maintenance script would be run via cron, as frequently as possible (ideally every few minutes, but hourly would be workable too), to issue notifications for events that have passed the scheduled time. It would delete the row from the echo_event table and then fire it as a non-delayed event.
There needs to be a standard way to cancel these notifications by ID (e.g. if the user groups are assigned permanently/revoked entirely and thus won't expire, or the user cancels the article reminder)
There should be a EchoEvent::createScheduled that returns either a $scheduled_event_id (event_id from echo_event) or an EchoEvent (can an EchoEvent exist if it hasn't been fired yet?) in which case getId would similarly be used.
To cancel, you could call EventMapper::cancelScheduledById, which would delete it from echo_event.
FAQ
What would use this infrastructure?
T2582 could potentially be solved by storing reminders as scheduled Echo events, or inserting scheduled Echo events in parallel with metadata in another table.
To solve T153817, the cronjob-executed maintenance script could be extended to also look at core's user_groups table and identify user groups whose expiry date is impending, or are going to expire in two days or two weeks.
Why couldn't the cronjob directly query user_groups and issue notifications immediately? Then we wouldn't need the extra column on echo_events.
We want to be able to issue a notification like "Your user rights have expired." Since the row is liable to disappear from user_groups any time after the group membership expires, we have to detect user_groups that are about to expire, place them in a holding location (echo_events with echo_scheduled_timestamp non-NULL), then issue the notification after the expiry time has passed.