Setting up a Notifications System in Symfony Projects

December 15th, 2016

Wiki / Symfony / Case Studies / Events // Myroslav

This information was initially presented at the #SymfonyCafeKyiv in December ‘16 by Myroslav Berlad, a Grossum software developer.

Notifications are a convenient thing for any kind of service (unless the system has been created to spam and annoy everyone). It’s good for users to know what’s new, whether there are pending requests or incoming messages, etc.

As the developers’ team has been working on a project, a need for a notification system arose.

We needed four types of notifications and the team agreed that writing our own solutions would take too much time, so we decided to use proven vendor API solutions.

  1. Push notifications (a message that pops up on a mobile device): GCM (google cloud messaging) - a mobile notification service developed by Google that enables third-party application developers to send notification data or information from developer-run servers to applications.
  2. Text messages (short message service, text messaging between mobile device users ): TurboSMS - a Ukrainian SMS sender service
  3. Email (messaging between computer device users): Mandrill is an email marketing service (that was merged with MailChimp)
  4. Web notifications & dynamic interface updates (targeted website user notifications / interface updates): Socket.io is a JavaScript library for real-time web applications. It enables real-time, bidirectional communication between web clients and servers. It has two parts: a client-side library that runs in the browser, and a server-side library for node.js.

How to implement a notification service?

There were two ways of doing this:

  • Symfony way: get some bundles, configure them, live happily ever after.
  • Our way: get some troubles. Cry.

How to do it Symfony-way?

A brief structure of our project’s architecture looks like this:

PUSH:

We decided to use RMSPushNotifications Symfony bundle for this. It allows sending notifications/messages for mobile devices and supports such platforms as iOS, Android (C2DM, GCM), Blackberry and Windows Phone (toast only).

Another bundle that we have used is EndroidGCM, which is a Google Cloud Messaging bundle used with Symfony projects. 

TEXT MESSAGE / SMS

EMAIL:

SOCKET:

Project architecture thoughts:

“Okay, this looks good. However, PHP is not a very good option to choose to run server daemon on. Also, it would be nice to post notifications with the same API.”

Additional parameters that we introduced for the project:

  • Reusable solution
  • Simple API for notifications
  • No PHP running as a daemon

Our way:

When we thought about the possible path for the messages to take, the solution turned out like this:

Symfony -> Rabbit -> Node -> Target

SYMFONY APPLICATION

To integrate Symfony2 and Symfony3 and RabbitMQ, we used php-amqplib (formerly known as oldsound/rabbitmq-bundle)

NODEJS

For the NodeJS part, we have decided to use AMQP 0-9-1 (e.g. RabbitMQ) library and client.

SMPP

SMPP client and server implementation in node.js.

MANDRILL / MAILCHIMP

For the email integration and notifications, we have used Mandrill (merged with Mailchimp). We used a node.js wrapper for the MailChimp API.

SOCKET

Finally, we have arrived at the socket settings. We used socket.io, a node.js real-time framework server for this. 

CHECK THE REQUIREMENTS:

  • Same notification API for all cases - CHECK
  • No PHP running as a daemon - CHECK

But what about a reusable solution?

Welcome, Docker! https://www.docker.com/

docker-compose up

Using Docker, we have created a container with all the necessary settings for our project. (Read more about working with Docker and here are some practical application examples.)

Okay, now we’re meeting all three requirements.

  • Same notification API for all cases - CHECK
  • No PHP running as a daemon - CHECK
  • Reusable solution - CHECK

However, a new question arises: should a new project handle notifications in its own way?

The short answer is: No.

These thoughts have led us to the creation of a solution that can be easily shared.

We present you...

Grossum Symfony Notification Bundle

Installation is fairly simple:

Grossum Notification Server

cp docker-compose.yml.dist docker-compose.yml docker-compose up

All requirements are met.

Our plans for the future of the bundle:

  • Write unit tests :)
  • Make flexible bundle configuration
  • Refactor NodeJS server part(simple, but can be better and cleaner)
  • Split node and docker into 2 separate repositories

CURRENT STATUS

  • The solutions seems to work :)
  • 3 projects use this solution, and hope more :)
  • Team received experience with RabbitMQ
  • Team received experience with NodeJS
  • Team received experience with splitting app into separate microservices
  • Team received experience with docker

Bonus:

You can use RabbitMQ, not as a part of GrossumNotificationServer, but you can consider it as your app message bus.

"A Message Bus is a combination of a common data model, a common command set, and a messaging infrastructure to allow different systems to communicate through a shared set of interfaces. Sending a message does not require both systems to be up and ready at the same time." Read more here.

Need help with a Symfony2 or Symfony3 project? We can help!

WATCH THE PRESENTATION:

Watch the video from the #SymfonyCafeKyiv:


Author: Myroslav

Myroslav is Grossum's developer with experience in Symfony2/3 framework, EmberJS, node, docker, and other. He is fluent with REST API and CLI background tasks. He loves challenging tasks in projects and is not afraid to stand up to them. He is a speaker at #SymfonyCafeKyiv and other. In his free time, he likes to play League of Legends, read books, and play guitar.

Tags Symfony Cafe Development Hacks

See all blog

x

Grossum Startup Guide:
Five Things to Consider Before Web & Mobile Development

Get the Guide