Message Bus

27 Aug 2017 » Analytics Tips , Launch

Unless you have been living in a cave, you should already have a data layer in your websites. OK, maybe that is too harsh; however, at least, you should have a plan to put one in place. Once you have a good data layer, the next step I recommend is that you deploy a message bus.

The concept of a message bus

message bus diagram I will use the words “message bus” for a concept, for which you might have a different expression. In general, a message bus is a software library that decouples emitters and receivers of information. An emitter sends a packet of data into the bus. Receivers listen to the bus for messages and process only those messages relevant to the receiver. Message senders do not care about who is going to receive it and many receivers can receive the same message.

Another very typical way of expressing this concept is the publisher-subscriber pattern or pubsub for short.

Static vs dynamic data

As I have said at the beginning of this post, I strongly recommend adding a data layer to your websites. In fact, I wonder how have we managed to live without one in the past. I have seen many problems with my clients, which could have been avoided using a data layer. However, a data layer has one important limitation: its data is static. Usually, the data is loaded on page load. This means that any modification to the data, while the visitor is on the page, will not be reflected until the next page load.

Let’s consider a typical example, which I will use throughout the rest of the post. You have an add-to-basket button, which makes an AJAX call without refreshing the page. If the basket is empty on page load and the visitor clicks on the button, a new product will be added to the basket. But the digitalData.cart object will still reflect an empty basket.

You could consider updating the data layer, which I would recommend anyway. However, other parts of the website might need to be notified of the change. This is where the message bus comes into play. The code executed when a change happens, can send a message carrying information about the change that has just happened. Optionally, the notification can contain the new data.

Single-Page Applications

Another typical example, where a message bus becomes very interesting, are the single-page applications (SPA). In the last few years, these type of websites have become very common. For those of you who are not familiar with them, these are websites that load a canvas when the user lands on the website, but all interactions are managed in JavaScript. No more page load happen and any changes to the UI are managed by JavaScript libraries.

Coming back to the data layer and message bus, you can immediately see how a data layer is useless on its own. When the landing page is loaded, its corresponding data layer would also be loaded. Unless you add some specific code, as the user interacts with the website, the data layer would become more and more obsolete. You need a way to keep the data layer updated and notifying the different libraries of these changes. A message bus fits nicely in this scenario.

DTM

DTM event based rule If you are using DTM (or any other type of tag manager for what matters), you probably have seen the following problem. During the implementation, you have created some event-based rules to capture when users click on HTML elements. In the rule, you use CSS selectors to identify the elements. These rules will typically invoke s.tl() and will be used, for example, in add-to-basket buttons. However, a few months later, the design changes, including the CSS. Nobody remembers the DTM code, so, the this is not changed. Once the code goes life, the add-to-basket code stops working, the metrics drop to 0 and your friendly marketer stops being that friendly with you, even when it is not your fault.

How could the previous problem be avoided? This is how I have solved it in DTM.

For each of the events, which needs to be tracked in Analytics, I create direct call rule instead of the event-based rule. I then create a listener or subscriber in DTM in a page load rule. This is pure JavaScript code. The listener’s processes the incoming messages, checks if it is of any interest and, if so, invokes the corresponding direct call rule using _satellite.track(). The website developers, on the other hand, need to send a message to the bus for every user interaction, for every AJAX response, for every timer… In summary, for anything happening on the website.

There is still a piece missing. It is very probable that you need to track some eVars/props/events. This means there is a need to send parameters (for example, the SKU of the product being added to the basket). To achieve this, there are two different approaches:

  • In the message bus. When sending the message, send all associated information in the actual message. Then, in the DTM listener, extract that information and store it somewhere where DTM can read it:
    • In simple cases, you can do with _satellite.setVar("variable name",value). This will create a dynamic data element, which you can retrieve with the %variable name% construct.
    • In more complex cases, where there could be dozens of variables, it is usually better to store the data from message bus in a JavaScript object and create DTM data elements to read them.
  • Updating the data layer. Before sending the message, the sender will update the data layer with the new data. Then, in the direct call rule, your data elements will just need to read from the data layer. Although this might seem a better option, it can become very complex and requires all parties to know where and how to update the data layer.

With this elegant solution, any changes in the HTML or CSS should not have any impact on the Analytics implementation. The only caveat is that any changes in the UI still need to invoke the same code.

Beyond web analytics

So far in this post I have been considering only the web analytics implementation. However, nothing prevents you from using the message bus for more than just that. The idea is still the same: changes in one part of the web application need to trigger actions in other parts of the application. I do not know exactly how SPAs are created, but a message bus should be very useful in this particular case, to connect the different pieces of code.

Continuing with our add-to-basket example, you could use the message bus to update the UI. Usually, this means showing an overlay with the new product added for a few seconds and updating the cart icon.

Example

Before finishing, I would like to illustrate the whole process with an example. I will also show how to include the intent and the success.

  1. The user clicks on the add-to-basket button associated with a product.
  2. The button handler sends a message with the event information.
  3. One listener sends an AJAX call to the servers, to get confirmation that the product can be added to the basket.
  4. The DTM listener invokes a direct call rule to track the intent with a custom event.
  5. The servers respond with a success message.
  6. The AJAX response handler sends a message to the bus with the information from the AJAX call.
  7. The basket listener updates the icon in the basket, showing there are more items in the basket.
  8. The DTM listener invokes another direct call to rule to track the success with the scAdd event.

Let’s now consider the case of an error and how well it fits in this solution.

  1. The user clicks on the add-to-basket button associated with a product.
  2. The button handler sends a message with the event information.
  3. One listener sends an AJAX call to the servers, to confirm that the product can be added to the basket.
  4. The DTM listener invokes a direct call rule to track the intent with an event.
  5. The servers respond with an error message: the product is out of stock.
  6. The AJAX response handler sends a message (different from the success case) to the bus with the information from the AJAX call.
  7. The error listener shows the error message in an overlay.
  8. The DTM listener invokes a third direct call to rule to track the out-of-stock condition.

In case you are wondering how to implement the message bus, do not try and re-invent the wheel. Use an existing, open source library. In the projects I have worked with, I recommend the following code: https://github.com/mroderick/PubSubJS.



Related Posts