SharePoint – Customizing Alert emails using IAlertNotifyHandler


I have read so many articles and worked for so many days to customize alert email for immediate, daily, weekly alerts and finally achieved alternative solution. The solution is listed below,

Steps:-

1) Use IAlertNotifyHandler interface to intercept the email and modify it.

2) We can create our own class that inherits from the IAlertNotifyHandler interface and uses the OnNotification method. This will allow you to intercept the outgoing alert emails and modify them. We can access most of the properties for the alert and with some xml parsing and SharePoint object model code, we can extract all the information we need to build up the email. We can then construct the HTML stub to display the email based on your requirements and send the email out using SharePoint’s SendMail functionality.

3) see sample code below along with the steps to set up the scenario.

4) Create a class project that inhertits from the IAlertNotifyHandler interface. Include the Microsoft.SharePoint and Microsoft.SharePoint.Utilities namespaces in the project.

This is the code:

public class AlertUpdate : IAlertNotifyHandler
{
public bool OnNotification(SPAlertHandlerParams alertHandler)
{
string siteUrl = alertHandler.siteUrl;
using (SPSite site = new SPSite(siteUrl + alertHandler.webUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
// to apply only to specific site within site collection
if (web.Url == “Sitename”)
return CustomAlertNotification(web, alertHandler, siteUrl);
else
{
//for other SharePoint sites use the OOTB Alert Email
SPUtility.SendEmail(web, alertHandler.headers, alertHandler.body);
return false;
}
}
catch
{
//if it fails due to configuration still the default alert should work
SPUtility.SendEmail(web, alertHandler.headers, alertHandler.body);
return false;
}
}
}
}

private bool CustomAlertNotification(SPWeb web, SPAlertHandlerParams alertHandler, string siteUrl)
{
SPList list = web.Lists[alertHandler.a.ListID];
StringBuilder body = new StringBuilder();
string style = “.style1 {font-size: 10pt;font-family: Arial;border:0px;}”;
int eventCount = alertHandler.eventData.Count();
string listPath = HttpUtility.UrlPathEncode(siteUrl + “/” + alertHandler.webUrl + “/lists/” + list.Title);
string webPath = HttpUtility.UrlPathEncode(siteUrl + “/” + alertHandler.webUrl);
for (int i = 0; i < eventCount; i++)
{
string eventType = null;
if (alertHandler.eventData[i].eventType == 1) eventType = “Added”;
else if (alertHandler.eventData[i].eventType == 2) eventType = “Changed”;
else if (alertHandler.eventData[i].eventType == 3 || alertHandler.eventData[0].eventType == 4) eventType = “Deleted”;
if (eventType != null)
{
try
{
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration(“1.0”, null, null);
doc.InnerXml = alertHandler.eventData[i].eventXml;
XmlNode titleNode = doc.SelectSingleNode(“.//Field[@Name = ‘Title’]”);
XmlNode bodyNode = doc.SelectSingleNode(“.//Field[@Name = ‘Body’]”);
string titleValue = null;
string bodyValue = null;
string header = null;
if (eventType == “Deleted”)
{
titleValue = titleNode.Attributes[“Old”].Value;
bodyValue = bodyNode.Attributes[“Old”].Value;
}
else
{
//alternative way of getting item id
int itemId = int.Parse(alertHandler.eventData[i].itemFullUrl.Substring(alertHandler.
eventData[i].itemFullUrl.LastIndexOf(‘/’) + 1).Replace(“_.000”, “”));
SPListItem item = list.GetItemById(itemId);
if (eventType != “Changed” || eventCount > 1)
{
titleValue = item[“Title”].ToString();
bodyValue = item[“Body”].ToString();
}
else
{
if (titleNode.Attributes[“New”] != null)
titleValue = titleNode.Attributes[“New”].Value;
else
titleValue = titleNode.Attributes[“Old”].Value;
if (bodyNode.Attributes[“New”] != null)
bodyValue = bodyNode.Attributes[“New”].Value;
else
bodyValue = bodyNode.Attributes[“Old”].Value;
}
}
int index = titleValue.IndexOf(‘.’);
if(index == -1)
header = titleValue;
else
header = titleValue.Substring(0, index);
body.AppendFormat(“{0} <table cellpadding=”5″ cellspacing=”5” > “, style);
body.AppendFormat(” <tr> <td>link to SharePoint site</td></tr>”, webPath);
body.AppendFormat(” <tr> <td> {0} </td></tr>”, titleValue);
body.AppendFormat(” <tr> <td> {0} </td></tr></table>”, bodyValue);
}
catch
{//ignored excepetion
}
//send email only if all alerts are processed
if ((alertHandler.eventData.Count() – 1) == i)
{
SPUtility.SendEmail(web, alertHandler.headers, body.ToString());
}
}
}
if (eventCount > 1)
return true;
else
return false;
}
}

5. Compile the project and deploy the dll into GAC.

6. Make a copy of the alertTemplates.xml file found at this location: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML. Always work with a copy of AlertTemplates.xml, not the original.

7. Call this new file “CustomAlertTemplates.xml” and save the file. In the file “CustomAlertTemplates.xml” search for the keyword “properties” : Include these additional lines into the properties block:
<NotificationHandlerAssembly>AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</NotificationHandlerAssembly>
<NotificationHandlerClassName>AlertHandler.AlertUpdate</NotificationHandlerClassName>
<NotificationHandlerProperties></NotificationHandlerProperties>

The entire stub should look like this now:
<Properties>
<ImmediateNotificationExcludedFields>ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments;</ImmediateNotificationExcludedFields>
<DigestNotificationExcludedFields>ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments;</DigestNotificationExcludedFields>
<NotificationHandlerAssembly>AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</NotificationHandlerAssembly>
<NotificationHandlerClassName>AlertHandler.AlertUpdate</NotificationHandlerClassName>
<NotificationHandlerProperties></NotificationHandlerProperties>
</Properties>

Note: Please update the PublicKeyToken to your assembly PublickKeyToken
Note:- Include the above XML stub in each alert template section to whichever list type you want to associate in the alert template file.

8. Run this command from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN: stsadm -o updatealerttemplates -filename “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML\customalerttemplates.xml” -url

9. Run this command from the command prompt: iisreset

10. Run this command from the command prompt: services.msc

11. From the services window, restart the Windows SharePoint Services Timer.

Your custom email alert handler should be configured at this point. Create a new alert and you should get the updated custom email.

Let me know your feedback.

Thanks

Advertisements

About Mahi

Hi, Welcome to Mahi's 12 hive Blog. I am Micrososft Certified Technical Specialist in SharePoint. Love to blog the stuff which i experienced in my projects. Thanks Mahi
This entry was posted in MOSS 2007, SharePoint Object Model, SharePoint Server 2010. Bookmark the permalink.

4 Responses to SharePoint – Customizing Alert emails using IAlertNotifyHandler

  1. Brijesh H Patil says:

    Hi Mahi,

    I have a question,
    Will this piece of code work for the Daily Summary and Weekly Summary?

    I created a handler that works for only “Immediate” alert types. My concern is with the “Daily” and “Weekly” summary. Many thanks for your effort on explaining the concept.
    Just waiting for your reply, kindly help me out in the Daily and Weekly summary reports.

    • Brijesh H Patil says:

      I had used the above code for my requirement on the Summary alerts and an exception is thrown at the following code
      int itemId = int.Parse(alertHandler.eventData[i].itemFullUrl.Substring(alertHandler.eventData[i].itemFullUrl.LastIndexOf(‘/’) + 1).Replace(“_.000″, “”));
      SPListItem item = list.GetItemById(itemId);

      Please let me know am I missing out anything, I am waiting for a reply on this.

      Many Thanks
      BRIJESH

    • Mahi says:

      Hi Brijesh,

      This works fine only with Immediate Alert. I haven’t tested with Daily/Summary.

      Thanks
      Mahipal

  2. Hi there, just wanted to say, I enjoyed this blog post.

    It was funny. Keep on posting!

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s