Ready to Learn?Ex Libris products all provide open APIs

  • Primo resources
  • Alma resources
  • Rosetta resources
  • Leganto resources
  • bX resources
  • SFX resources
  • Aleph resources
  • Voyager resources

Tech Blog

 

Real Time Notifications with Alma Webhooks

We were introduced to Alma's support for webhooks in a previous blog post. Webhooks allow us to respond to events that happen inside of Alma. Initial support was provided for the job end event. A recent Alma version has added a new event for patron notifications. We can now configure Alma to send a webhook call for certain notifications, in addition to the existing email and SMS notification channels.

There are several use cases for such a webhook. We can use it to integrate with an SMS provider such as Twilio to send SMS messages immediately, rather than the previous file-based integration. If our institution has a mobile app, we can send notifications to users by integrating with mobile messaging services such as AWS's Push Notification Service (SNS). We can also create a real-time messaging interface in our library portal, which is the scenario we'll walk through below.

Configuring the Integration Profile

In order to enable this additional event type, we can either create a new webhook integration profile or add notification support to an existing profile. The webhook integration profile now has a section where we indicate which events we're interested in receiving. The rest of the profile remains the same, with a listener URL and secret. 

Webhooks Notifications Profile

In addition, we need to configure the notification types for which we wish to receive a webhook. Click the "Configure notification types" button and enable the notifications marked WEBHOOK in the channel column.

Webhooks Notifications Configuration

Webhook Listener

Our webhook listener is very similar to the basic listener we saw in the Getting Started post. We handle the challenge in the GET method. In the POST method, we validate the signature and confirm that the event type is 'notification'. Then we construct a notification object consisting of a few properties- title, body, and date. We can populate the title and body as we desire based on the information we receive with the webhook.

var action = req.body.action.toLowerCase();
var body = req.body.notification_data;
var username = body.receiver.primary_id;
if (action == 'notification' && username) {
  var notification = {
    id: req.body.id,
    title: body.user_request[0].title,
    body: body.sms_content,
    date: dateFormat(req.body.time, "d/mmm/yy HH:MM")
  };
}
 

Persisting the Notifications

In order to save the notifications for the user until they'e read and dismissed, we need to persist them to some data store. In this example, we're using MongoDB to store a document per user. The document includes the username and an array of notifications. We add our new notification to the array and save the document back to the database.

getRecord(req.app.db, username, function(err, record) {
  // Check to see if notification has already been handled
  if (!record.notifications.some(n=>n.id == notification.id)) {
     record.notifications.push(notification);
     updateRecord(req.app.db, record);
  }
});

One additional note- we want to protect against notifications being handled multiple times. This may happen if there is a communication failure between our webhook listener and Alma, in which case Alma will try to resend the webhook. To handle this scenario, Alma conveniently provides us with a unique ID on the webhook. We can check to see if this ID already exists in our notification array. If it doesn't, we go ahead and add it.

User Interface

Of course your user interface depends on the needs of your application. In this example, we're showing a notifications icon with an alert bubble displaying the number of notifications. We retrieve the notifications from the server with an AJAX call from the client, and we use the response to populate the bubble and the list of notifications.

We also provide an option to clear the notifications, which calls a method on the server that empties the notification array and saves the document back to the database.

Webhooks Notifications List

 

Real Time Communication

In order to facilitate the real time aspect of our real time notifications, we've implemented WebSockets. Whereas normal web applications respond to requests from the browser, WebSockets allows two-way communication between a web browser and a web server. When a webpage is loaded, a WebSocket connection is made to the server and remains open. Here is some client-side JavaScript which does that:

// Set up WebSocket connection
var HOST = location.origin.replace(/^http/, 'ws')
var socket = new WebSocket(HOST);
socket.onopen = function() {
  console.log('Socket open.');
};

When the socked it opened with the server, we store the connect object in an array of client connections. When the socked is closed, the connection is removed from the array. When our server responds to a webhook notification from Alma, it can check to see if the user is connected and if so, send a message to the user's browser indicating that a new notification has arrived. We do this by emitting a Node event when a notification is added, as follows:

req.app.emit('notificationReceived', {username: username, notification: notification});

We added an event handler in the WebSocket connection. The handler looks for the user's WebSockets connection in the client array. If connected, it sends the notification to the browser:

app.on('notificationReceived', function(data) {
  console.log('notificationReceived', data);
  var ws = clients[data.username];
  if (ws)
    ws.send(JSON.stringify(data));
});

The browser can then show a pop up notification and update the message bubble with the new number of notifications:

socket.onmessage = function(message) {
  console.log('Socket server message', message);
  let data = JSON.parse(message.data);
  showNotification(`${data.notification.title} - ${data.notification.body}`);       
  getNotifications();
};

Below we see a request being cancelled in Alma, with our user interface responding when the webhook is received on the server:

Webhook Notifications

Summary

As more event types are added to Alma's webhooks support, additional opportunities for advanced integrations will be possible. Keep an eye on the Alma release notes for news of future webhook events.

The code for this blog post is available in this Github repository.

Github