Feature Project Proposal: Notifications API

Most of the situations where WordPress sends an outgoing email can be classified as a notification. X just happened on your website and you should be aware of it.

Back when WordPress was a youngster, the only way to reliably notify a user was via email. In 2016 we have many more options, including push notifications to mobile platforms, desktop notifications to browsers, messages to chat apps, endless services via webhooks, SMS messages, or even notifications in the WordPress admin area. The list goes on. For many users, email is no longer the optimal delivery mechanism for ephemeral notifications.

To that end, let’s think about replacing wp_mail() with a modern API that allows developers to route notifications to services other than email, allow them to better modify notifications and the way in which they’re formatted, and allow them to do so without stepping on each others’ toes.

The current lack of a notifications API (or even an email sending API) can be easily summed up:

Problem: Plugin A wants to provide HTML emails, and Plugin B wants to send emails via an email delivery service such as Mandrill. Plugin C wants to disregard emails and send Slack notifications. It’s very difficult for these to co-exist.

Notification Destinations

There are only two types of destination for a notification in WordPress. Most notifications are actually notifications to a user account that get delivered via email because it’s the only contact information available for every user account. The remaining notifications are explicitly notifications to an email address rather than a user account (or not yet attached to a user account), such as when a user signs up for a blog and needs to click a confirmation link before their user account gets created.

With this in mind, you might be able to imagine a notification class in WordPress core that defaults to delivering notifications via email, but which can be extended by a plugin on a per-user and per-notification basis to deliver notifications via any of the means listed above. WordPress core would support delivery via email and provide the API that allows plugins to implement delivery via other means.

With a well-designed API, multiple plugins can co-exist in order to deliver different notifications via different mechanisms, format email notifications as HTML, easily disable notifications, change the delivery mechanism for email notifications, or provide a UI for users to manage their notification preferences and destinations.

Planning a Notifications API

I’d like to begin work on a feature project with the intent of designing and implementing such an API. I’d like to get input from authors of existing plugins that provide functionality such as delivering notifications via a service other than email, that override the default email delivery mechanism, or that implement extra notifications (such as e-commerce sale notifications), in order that the API can be backwards compatible and that we can get some plugin implementations built during the API’s development.

I already have some technical ideas regarding how the API might look, but I’m conscious that such an API needs to be well-designed before anyone jumps into writing code. Maybe we can even try some test-driven development? Who knows.

In addition, consultation and involvement with the team that are working on the two-factor authentication feature project is important as it implements several delivery mechanisms for 2FA codes that could potentially be made simpler with a notifications API.

Get Involved

Feedback is most welcome in the comments. Would you like to help out? Yes? Great. Let’s plan a date and time for a meeting in Slack and go from there.

Finally, a reminder that feature projects are not tied to a specific release of WordPress. This won’t make 4.7. It would be great if it was mature enough for 4.8, but we won’t be aiming for a particular release just yet.

I think it’s a great idea, John. However, where you said “let’s think about replacing wp_mail()” I assume (hope) you mean “let’s think about replacing the use of wp_mail() for notifications.” wp_mail() is quite ubiquitous throughout the plugin universe. Replacement would have repercussions, unless of course wp_mail() were to be updated to use the new API. Maybe I’m reading it wrong, but just throwing that in if I’m not.

I think I’ve already said I’d be interested in helping out in the past – if not, consider this registering my interest ;).

One point of concern though: would `wp_mail()` be a wrapper for the notification API? Or would the notification API (if/when configured to do so) make use of `wp_mail()`? I ask, because the purpose of `wp_mail()` is very much tied to it’s means of delivery. There will be instances where plug-ins are using `wp_mail()`, when an alternative means of transport is not appropriate or not possible.

This really boils down to who has final say on the means of transport, and in particular whether `wp_mail()` will continue to only trigger e-mails – you hint as much in your reply to Chad. I dare say this is will get thrashed out in the details, but something to keep in mind.

I have expressed my interest in this in the past and I’d love to help shape such an API.

As mentioned in other comments, it should be possible to queue notifications, e.g. by storing them in the database until delivered. One particular use case I’m talking about is when you want to send 1 weekly digest email instead of an email for every event. See https://wordpress.org/plugins/digest/.

I have seen this idea brought up before, and I’ve been hoping that someone would pick it up. I’ll try to contribute as I have time (which sometimes won’t be much).

I would like to point out that your example seems to me to be a bit wrong-headed, but perhaps I am interpreting it incorrectly. The impression I get is that there would be several different classes, and plugins would choose to use whichever class they wanted based on the type of notification they want to send. In other words, this would be hard-coded. I think that this is missing a huge opportunity for giving users the option (via plugins built for that purpose) to switch from one form of notifications to another. So if I have a plugin that usually sends me emails, but I want to change that to Slack notifications instead, I should be able to do that very easily just by filtering the delivery method. Perhaps this was part of the idea, but if so it wasn’t clear to me.

The aim is to build a base API that also provides an email delivery mechanism by default, and which allows plugin authors to implement delivery mechanisms for any service they desire, such as Slack. It would then be up to individual plugins to determine when to override an email with a Slack message, or this logic could be provided by a standalone plugin that includes a UI for users to choose their notification preferences.

John, a notification API is a fabulous idea whose time has come. Thank you. On the other hand, I wholly agree with J.D. that control of where the notifications go should be in the hands of users, not plugin owners. User control of destination is very, very important to making a notifications as useful as it could be. Probably the very core of the improvement.

This is a great idea. I’d love to help on this. Seriously DM me (Shelob9 in Slack) when you’re ready to get started.

In my plugin Caldera Forms, I built infrastructure for alternative delivery of email notifications. We have only implimented it for SendGrid so far, but will be adding support for other services soon.

The code for that is here:
CalderaWP/Caldera-Forms/tree/master/classes/email

Beacuse altering wp_mail() for one specific type of email is a giant pain/impossible, this system prevents sending to wp_mail() when used. Totally the kind of thing a core notifications API would be helpful for.

This is a good idea. I’d love to have a notification hub for all events fired in the system and defined by developers. Each event can have several phases that developers can hook into to do something. Also a list of supported notification media (desktop notification, email, sms, push notifications) should be provided (or easy to be included).

This is a game changer for the system and all plugins (like e-commerce ones).

I think this would be an awesome plugin and I’m all for improving `wp_mail()` to add more hooks to make it more flexible. I don’t think a notifications API should be part of core. A message sent via email is different from a message sent to Slack. I don’t think it is as easy to say all my notifications should go to Slack. There is a lot of nuance which gets complicated. Would WordPress have an option as part of core to enable Slack notifications? Functionality that relies on 3rd party APIs sounds like a burden to have to maintain in core and is better suited as a plugin so updates can be distributed more quickly instead of pushing a point release to the millions of sites running WordPress that may or may not make use of the notification channel.

Remember when core had a list of default IM fields in the user profile? That feature was removed (https://core.trac.wordpress.org/ticket/11541) because it was decided that they couldn’t cater to everyone. @dd32 sums it up nicely
> In my opinion, All IM fields should be striped from core. Its impossible to cater for everyone, whilst not over-doing it.
> Every culture group and country prefer different networks, in the past, there were a limited selection so it was fine, Today, You might as well include FaceBook, Myspace, Orkut, Tagged, Bebo, Windows Live Spaces (different from MSN AFAIK?)

I’m curious to see what comes of a feature plugin and how it might handle the issue of trying to be all things to all people. But I still don’t think it is core functionality.

This proposal is about building an API that allows plugins to implement any number of destinations. Core will only implement support for email.

With this in mind, you might be able to imagine a notification class in WordPress core that defaults to delivering notifications via email, but which can be extended by a plugin on a per-user and per-notification basis to deliver notifications via any of the means listed above.

Hi @johnbillion. Thanks for getting this posted; I’ve enjoyed talking with you about it previously about how BuddyPress would make use of this if it were well-architected. I’m not prepared to commit any time at this point until your techinical roadmap/architecture plans are posted, though I understand you are probably wanting unbiased approaches from others to test your implementation ideas against. Please keep communicating frequently and often, and I’ll stick my head in when things have moved on a bit.

Like the idea very, very much. Already asked the core contributors in there session @ WordCamp Nuremberg about such an development. Would be a huge achievement for admins running multiple WP instances getting notifications not by mail, but forwarded to logstash/ELK-stack, graylog, … or any other logging plattform.

Notifications are almost the very definition of an ‘action’. Hooking actions is what WordPress is great at. As developers we can add as many as we like for as many services, notification types as we want. It’s backwards compatible and can fallback to wp_mail if necessary.