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.