Using the new EPiServernotification API

As from EPiServer 9.4 you can make use of the notification api. It’s mainly used within the projects feature as far as I can tell, but I found another use for it. NOTE: It’s still in beta.

Imagine you have a scheduled job e.g. It does some important processing, e.g. sending order information to SAP in a commerce environment. If the connection with SAP fails, they won’t be processed. You log the error of course, maybe send an email through your logging provider…

It would be nice though if an editor/admin is online that he, or she, gets an instant notification, so they can respond more quickly.

What you could do, is make use of the new notification api.

I added a method to my scheduled job that gets all admin users, creates a INotificationUser for them to use as the recipients, creates a INotificationUser for the admin user as the sender and uses the notifier to send the (error)message. It also calls a Custom notifier that posts a message to Slack, which can be read by the support team e.g.

private async void SendMessage(string message)
        {
            string[] usersInRole = Roles.GetUsersInRole("Administrators");

            INotificationUser notificationSender = new NotificationUser("admin");

            List<INotificationUser> notificationReceivers = 
					(from sUser in usersInRole
                   select Membership.GetUser(sUser)
                    into user
                    where user != null
                     select new NotificationUser(user.UserName))
                .Cast<INotificationUser>().ToList();

           SlackNotifier notifier = new SlackNotifier();

            await
             notifier.PostNotificationAsync(
                 new NotificationMessage()
                 {
                     ChannelName = SlackFormatter.ChannelName,
                     Content = message,
                     Subject = "Scheduled job",
                     Recipients = notificationReceivers,
                     Sender = notificationSender,
                     TypeName = SlackMessageProvider.Name
                 }
                 );

            await
                this.Notifier.Service.PostNotificationAsync(
                    new NotificationMessage
                        {
                            ChannelName = SlackFormatter.ChannelName,
                            Content = message,
                            Subject = "Scheduled job",
                            Recipients = notificationReceivers,
                            Sender = notificationSender,
                            TypeName = SlackMessageProvider.Name
                        }
                    );
        }

If you use your own channel name, you need to add a formatter for the message, which takes care of the formatting for you, e.g. add a color to the message body.

    [ServiceConfiguration(typeof(IUserNotificationFormatter))]
    [ServiceConfiguration(typeof(INotificationFormatter))]
    public class SlackFormatter : INotificationFormatter, IUserNotificationFormatter
    {
        public const string ChannelName = "epi.slack";

         // Other interface interface properties  removed

        public IEnumerable<FormatterNotificationMessage> FormatMessages(
            IEnumerable<FormatterNotificationMessage> notifications,
            string recipient,
            NotificationFormat format,
            string channelName)
        {
            // we do not want to change the messages, so we just return them as they are
            return notifications;
        }

        public UserNotificationMessage FormatUserMessage(UserNotificationMessage notification)
        {
            if (notification != null)
            {
                notification.Content = "
" + notification.Content + "
"; } return notification; }

The custom Slack notifier would look something like this

    public class SlackNotifier : INotifier
    {
        private readonly SlackClient slackClient =
            new SlackClient("https://your.webhook");

        public async Task PostNotificationAsync(NotificationMessage notification)
        {
            SlackMessage slackMessage = new SlackMessage
                                            {
                                                Channel = "#yourchannel",
                                                Text = notification.Content,
                                                IconEmoji = null,
                                                Username = "EPi Notification",
                                                Mrkdwn = false
                                            };

            await this.slackClient.PostAsync(slackMessage);
        }

        // Other interface interface methods removed
    }

If you have enabled the projects feature (else you will not see the notification icon, I hope you can use it without enabling projects in the future) you will see the notifications generated by your scheduled job.

You could also create a custom message provider for Slack and register it as the default provider for your Slack notifications in an initializable module.

See gist for the complete code examples.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s