The Notification Service is made up of two parts the notification type and the notification distribution type. The INotificationType plugin type defines a type of notification and allows you to setup the name, permissions and message. When a notification is created then the INotificationDistributionType plugin type is responsible for sending the notification via a particular medium. Out of the box Verint Community provides two distribution types, the email and socket (toast) distribution types.
Why Should I Create a Notification Type?
New notification types are useful when you want to notify community members about specific events in the community, either events that occur with core functionality or because of new functionality added to the platform.
Why Should I Create a Notification Distribution Type?
Besides sending a notification via email or toast notification a new distribution type can send a notification through another medium. For example you could setup a notification distribution using a text messaging platform. Defining a distribution type is out of scope for this document.
Creating an INotificationType
To add support for sending a new type of notification through Verint Community, and implement the INotificationType plugin type. Below is a full example that creates a notification whenever a comment is created:
using System;
using System.Collections.Generic;
using System.Linq;
using Telligent.Evolution.Extensibility;
using Telligent.Evolution.Extensibility.Api.Entities.Version1;
using Telligent.Evolution.Extensibility.Api.Version1;
using Telligent.Evolution.Extensibility.Content.Version1;
using Telligent.Evolution.Extensibility.Email.Version1;
namespace Samples
{
public class SampleNotificationType : INotificationType
{
private INotificationController _notificationController;
#region IPlugin
public string Name => "Sample Notification";
public string Description => "This plugin demonstrates the INotificationType plugin type";
public void Initialize()
{
Apis.Get<IComments>().Events.AfterCreate += CommentEvents_AfterCreate;
}
#endregion
#region INotificationType
public string NotificationTypeName => "Sample";
public string NotificationTypeDescription => "Sends a sample notification.";
public string NotificationTypeCategory => "Samples";
public Guid NotificationTypeId => new Guid("3C0542FD-5AB0-4386-911C-86CCF530BAEE");
public bool IsCacheable => true;
public bool VaryCacheByUser => true;
public bool CanDeleteNotification(Guid notificationId, int userId)
{
var notification = Apis.Get<INotifications>().Get(notificationId);
return notification != null && notification.UserId == userId;
}
public string GetMessage(Guid notificationId, string target)
{
var notification = Apis.Get<INotifications>().Get(notificationId);
if (notification == null || notification.ExtendedAttributes == null)
return null;
var commentIdAttribute = notification.ExtendedAttributes.FirstOrDefault(ea => ea.Key == "TargetCommentId");
if (commentIdAttribute == null)
return null;
var commentId = Guid.Parse(commentIdAttribute.Value);
var comment = Apis.Get<IComments>().Get(commentId);
if (comment == null)
return null;
var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Id = notification.UserId });
if (user == null)
return null;
return $"The following comment was added by {user.DisplayName}: \"{comment.Body()}\"";
}
public string GetTargetUrl(Guid notificationId)
{
var notification = Apis.Get<INotifications>().Get(notificationId);
return notification != null && notification.Content != null ? notification.Content.Url : null;
}
public void SetController(INotificationController controller)
{
_notificationController = controller;
}
#endregion
private void CommentEvents_AfterCreate(CommentAfterCreateEventArgs e)
{
if (e == null
|| e.Content == null
|| e.User == null
|| !e.IsApproved
|| !e.Content.CreatedByUserId.HasValue
|| e.CommentTypeId.GetValueOrDefault(Guid.Empty) != Guid.Empty)
{
return;
}
var comment = Apis.Get<IComments>().Get(e.CommentId);
if (comment != null && comment.IsApproved)
{
AddNotifications(e.Content.ContentId, e.Content.ContentTypeId, e.CommentId, e.Content.CreatedByUserId.Value, e.UserId);
}
}
private void AddNotifications(Guid contentId, Guid contentTypeId, Guid commentId, int contentAuthor, int actorId)
{
var comment = Apis.Get<IComments>().Get(commentId);
if (comment == null)
return;
var attributes = new List<IExtendedAttribute>
{
new ExtendedAttribute { Key = "TargetCommentId", Value = comment.CommentId.ToString("N") }
};
_notificationController.CreateUpdate(new NotificationCreateUpdateOptions
{
ContentId = contentId,
ContentTypeId = contentTypeId,
LastUpdate = DateTime.UtcNow,
UserId = contentAuthor,
ActorIdToAdd = actorId,
ExtendedAttributes = attributes
});
}
}
}
The implementation of INotificationType starts with the NotificationTypeName, NotificationTypeDescription and NotificationTypeCategory which are used to identify this notification within the UI. The NotificationTypeId is the unique identifier for this type.
SetController() is called by Verint Community during plugin initialization to give the plugin a privileged API to create and manage notifications of its type, so it needs to be stored for later use.
For this implementation, the plugin attaches to the IComments.Events.AfterCreate event in the Initialize() method to handle when new comments are created. The event handler ( CommentEvents_AfterCreate() ) determines if the comment is valid and approved, loads the new comment, and calls AddNotifications() to create notifications for the comment. Within the AddNotifications() method, the notification is created to be sent to the author of the content being commented on, including an extended attribute to store the ID of the comment that was created.
When the notification is shown, the GetMessage() method is called and returns a string value of the message being sent to the user. Here the ExtendedAttributes of the notification can be read to retrieve the ID of the newly created comment to help in rendering the message of the notification. To optimize rendering of notifications, the platform supporting output caching of notification messages via the IsCacheable and VaryCacheByUser properties.
Notifications support links to enable interacting with the notification (for example, to view the newly created comment). The result of GetTargetUrl() will be used as the URL to interact with the notification. In this example, this will be the URL where the content is located.
A notification type is also responsible for identifying who can delete a notification via the CanDeleteNotification() method.
In this sample the notification is displayed when a comment is created. After , the plugin can be enabled in the administration panel, navigate to the Notifications menu and find the "My Notifications Plugin" check Enabled and click Save. Create a comment and notice the toast notification.
