Page MenuHomePhabricator

Define a way for extensions to block or intervene with other notifications (Notifications middleware)
Closed, ResolvedPublic

Description

To make sure the new notification system provided flexibility in managing notification behavior and ensure feature-parity between the behaviors of Echo and Core, the Core notifications system will add a new pattern: a notifications middleware. The middleware will be invoked on notifications before they are given to the Handler, allowing developers to manipulate notifications or recipients conditionally.

Current behavior: hooks

Currently, notification developers often need to interfere with the behavior of related notifications. This includes actions such as overriding existing notifications, adding secondary notifications, or modifying the recipient list by adding or removing recipients. This is currently achieved using various hooks provided by Core and Echo, with the choice of hook determined by specific business logic requirements.

New approach: the middleware

The notifications middleware provides a unified and consistent single-point-of-entry mechanism to handle notification management by an external system. Developers will have a centralized and standardized way to manage the behavior and recipient lists of notifications between different products. The single entry-point also means easier maintainability and easier way to debug when a problem happens, since all notification modification behavior will go through a single middleware chain.

Middleware details

The middleware is a simple execution of a chain of callable code that can be registered through extension.json. Each middleware code receives an array (Batch) of Notification and RecipientSet objects that the code can manipulate. Each middleware then calls the next middleware in the chain.

Example use cases

There are multiple cases around the system where one notification type needs to intercept another. Here are some examples:

  1. Suppressing other notifications
    • MassMessage blocks mention and flow-mention notifications from being sent when agent is MassMessengerUser
    • AchievementBadges blocks thank-you-edit and welcome notifications depends on configuration
    • Flow blocks all notifications sent from flow talk page manager user.
    • BlueSpice stops watchlist notifications for BlueSpice entities
  1. Change in behaviour:
    • Echo blocks sending watchlist email based on config flag and user preferences.
    • Echo blocks sending Talk page email based on config flag

Benefits

We anticipate a number of benefits from this new approach:

  • Notification developers will have an easier time registering "interference" logic. They will have a single-entry pattern rather than finding which hook to use (from quite a number of hooks)
  • In case of bugs, it's easier to check the middleware chain, rather than having to debug multiple hooks
  • Since the middleware handles arrays of notifications ("Batch"), then even the action of invoking it at the end of the process would mean we can potentially handle multiple notifications that result from the same action in the same batch and allow middleware to decide which is prioritized.

Event Timeline

Current use cases:

  1. Suppressing notifications
    • MassMessage blocks mention and flow-mention notifications from being sent when agent is MassMessengerUser
    • AchievementBadges blocks thank-you-edit and welcome notifications depends on configuration
    • Flow blocks all notifications sent from flow talk page manager user.
    • BlueSpice stops watchlist notifications for BlueSpice entities
  1. Change in behaviour:
    • Echo blocks sending watchlist email based on config flag and user preferences.
    • Echo blocks sending Talk page email based on config flag

Change #1125171 had a related patch set uploaded (by Pmiazga; author: Pmiazga):

[mediawiki/core@master] notifications: Introduce NotificationEnvelope and NotificationBatch

https://gerrit.wikimedia.org/r/1125171

Change #1125174 had a related patch set uploaded (by Pmiazga; author: Pmiazga):

[mediawiki/core@master] POC: Introduce middleware pattern to Notifications

https://gerrit.wikimedia.org/r/1125174

Change #1125171 abandoned by Pmiazga:

[mediawiki/core@master] notifications: Introduce NotificationEnvelope and NotificationBatch

https://gerrit.wikimedia.org/r/1125171

Change #1126098 had a related patch set uploaded (by Pmiazga; author: Pmiazga):

[mediawiki/extensions/MassMessage@master] DNM: Suppress MassMessage notifications in core

https://gerrit.wikimedia.org/r/1126098

Another different but related use case is what DiscussionTools does, where it holds itself back from sending certain notifications (or sending them to certain people) if it knows that other notifications about the same edit are already going to be sent. In the new system we'd probably want to achieve this by batching the notifications for the same domain event, and sending them through the middlewares together, so that the middlewares can make these kinds of deduplication decisions.

@Catrope that's exactly the reason why Middleware works on batch/list -> not a single Notification - even at this moment this list usually has just one notitication. The idea behind this is to:

  • allow easy Notification removal - we just "empty" the batch and then pass the empty array around - this saves us from null checks in code
  • allow easy replacement/injection - in case Extensions want to replace Notification, remove it and/or inject their own -> they can do it with a list easily. When MiddleWare worked on the
  • allow future deduplication - as an idea - in the future we can trigger NotificationService::process() only once on POST_SEND and it will go through all Notifications that were triggered within the request and remove duplicates, do batching, or, as an example - guarantee rule of one notification per one title - just an IDEA./
pmiazga changed the task status from Open to In Progress.Mar 17 2025, 2:38 PM
pmiazga triaged this task as Low priority.
pmiazga moved this task from Inbox, needs triage to In progress on the MediaWiki-Platform-Team board.

@Catrope that's exactly the reason why Middleware works on batch/list -> not a single Notification - even at this moment this list usually has just one notitication. The idea behind this is to:

  • allow easy Notification removal - we just "empty" the batch and then pass the empty array around - this saves us from null checks in code
  • allow easy replacement/injection - in case Extensions want to replace Notification, remove it and/or inject their own -> they can do it with a list easily. When MiddleWare worked on the
  • allow future deduplication - as an idea - in the future we can trigger NotificationService::process() only once on POST_SEND and it will go through all Notifications that were triggered within the request and remove duplicates, do batching, or, as an example - guarantee rule of one notification per one title - just an IDEA./

Yeah, @Catrope and I discussed that, and this is where that comment comes from. There's a lot of really great potential here, especially if we also include the batching.

I'll try to spend some time writing a proper description for all of this in the description of the ticket, we should collect the cases that we think we will be resolving with the first "MVP" iteration of this, and cases that could potentially be utilizing this in the future. This is a really great pattern with a lot of potential here, we just need to be a bit mindful to stay within our scope for the quarter (and document what we think could be done later, either by us or others).

Mooeypoo renamed this task from Define a way for extensions to block Notifications from sending to Define a way for extensions to block or intervene with other notifications (Notifications middleware).Mar 19 2025, 7:41 PM
Mooeypoo updated Other Assignee, added: Mooeypoo.
Mooeypoo updated the task description. (Show Details)

Change #1125174 merged by jenkins-bot:

[mediawiki/core@master] notifications: Introduce Notification Middleware and NotificationEnvelope

https://gerrit.wikimedia.org/r/1125174