While implementing various pieces of our Service-Oriented Architecture we, at Namshi, realized that a central notification service would have been very good in order to abstract the way we notify our customers and everyone in the company (ie. skype messages when a task is due a certain date).
We initially implemented all of this inside a Symfony2 bundle, but soon realized that we could abstract and generalize our implementation in order to extract it into a library for the public domain, and that’s how notificator was born.
Aim of the library: a monolog-like implementation for notifications
The aim of this library is to provide a very clean abstraction for a task, handling notifications, that can be spread across multiple channels (for example emails, skype messages, desktop notifications, …): by following this target, we soon realized that by merging together 2 simple things, Monolog and the concept of event dispatching, we could have easily reached our goal.
Honestly, it’s true that you can achieve the same goal with Monolog, but the problem, there, is that it’s a library specifically built for logging, thus, when your domain deals with simple notifications, your code would really be inexpressive.
Even though Notificator is way simpler, we took a lot of inspiration from Monolog: for example, the concept of handlers is a total steal ;–)
Installation
The library is available via composer, as you can see from its packagist page.
Using semantic versioning, I recommend you
to pick a minor release (1.0
, for example)
and stick to it in your composer.json
:
what we try to do is that, if there is a BC break
in the API, we increase the minor version (1.0.X
to 1.1.X
, for example).
At the end, you should require it like this:
1
|
|
Hello world! example
Just to give a very rough and simple example on how this
library works, let’s see how you can trigger a notification
via both email (with PHP’s mail
function1)
and the notify-send
utility available on ubuntu (I’ve already spoke
about it in a previous post).
First of all, we would need to create a plain-old-php-class representing the notification, which implements 2 interfaces:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
At this point we need 2 notification handlers, which will separately handle the notification:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
We’re basically there: with a bunch of code we can now trigger
a notification both via email and notify-send
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
At this point, if you run this example2, you should see a notification popping up on your desktop and, in a few seconds, you will also receive an email to the address you’ve given, with the subject “Test email” and “Hello!” in the body.
By the way, if you want to see some examples on how the library works, check them out on github.
Sending notifications via RabbitMQ
It is no news that we heavily rely on RabbitMQ in our SOA, so it’s pretty obvious that, to implement the notification service, we send messages containing the notifications, that will be intercepted by our notification service, which relies on Notificator.
To do so, we take advantage of the great job done by Alvaro Videla on RabbitMQ for PHP and Symfony2, through the PHP AMQP library and the RabbitMQ bundle.
If you are familiar with them, you know that in order to consume messages,
you have to declare your consumer as a callback of the actual, generic
rabbitmq consumer, through the config.yml
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
We already provide a very basic consumer callback to be used with the RabbitMQ bundle.
The main idea behind this is that the publisher serializes the notification
and sends it through RabbitMQ, while the consumer unserializes and
triggers it through the Manager
. The publisher code would be very, very simple:
1 2 3 4 5 6 7 |
|
and to start consuming messages you would only need to start the consumer:
1
|
|
FOSS
I’ve tried to write a pretty extensive README that you can use as a reference, on Github (check the tests, as well, to get an idea of the internals): if you spot any typo or mistake, don’t hesitate to reach out and point it out.
This library is part of the efforts, from Namshi, to be able to give back to the OSS community as much as possible: you are therefore strongly encouraged to open a PR or express your opinion if you find that something should be fixed or could be improved (there’s a lot of room for improvement, starting by implementing many more handlers).
- Only used for its simplicity here, please do not use it in production, use stuff like SwiftMailer instead! ↩
- I mostly took the example code from the README of the library on github, so forgive me if there are synthax errors or some typo. You can anyhow have a look at the examples (in the examples/ folder) to check some working code ↩