Thursday, June 6, 2013

How to Cusomize Alert Email for SharePoint 2013

Hi friends, sometimes we may want to customize email template that is sent out of the box by SharePoint  to the alert subscribers. You may want to apply some styling, add extra information about your company or add some extra URLs. One of the scenario when I required to do this was when I have Alternate Access Mapping configured for my SharePoint web application.

Lets us consider a scenario as shown below for my SharePoint 2013 web application.

Internal Web Application URLhttp://sp-realm/
Public Web Application URLhttps://access.sharepointrealm.com
Internal Website URL of Document Libraryhttp://sp-realm/Tutorials
Document LibraryResults
Internal URL of Document Libraryhttp://sp-realm/Tutorials/Results

Below is the snapshot of an email sent by Out Of the by SharePoint.




The email contains several information as shown below:

  1. Website Title: Tutorials
  2. Website URL: http://sp-realm/Tutorials
  3. Modify my alert settings URL: http://sp-realm/Tutorials/_layouts/15/mysubs.aspx
  4. Document Library Item Name: Hello World.txt
  5. View Item URL:  http://sp-realm/Tutorials/Results/helloworld.txt
  6. View Library URL:  http://sp-realm/Tutorials/Results
  7. Event Type: Added
All the URLs provided are internal URLs and will work fine when you are inside your company intranet. What if you want to access the same thing from the public internet provided that you have Alternate Access Mapping configured properly. You may want these URLs to be as under.

  1. Website Title: Tutorials
  2. Website URL: https://access.sharepointrealm.com/Tutorials
  3. Modify my alert settings URL:https://access.sharepointrealm.com/Tutorials/_layouts/15/mysubs.aspx
  4. Document Library Item Name: Hello World.txt
  5. View Item URL: https://access.sharepointrealm.com/Tutorials/Results/helloworld.txt
  6. View Library URL: https://access.sharepointrealm.com/Tutorials/Results
  7. Event Type: Added

The process goes as
  1. Create and deploy a SharePoint Project 
  2. Create an ALert Template
  3. Create a text file to store Public URL.
  4. Notify the SharePoint environment to use new Alert Template. 

1. Create and deploy a SharePoint Project

  1. Open Visual Studio 2012 and create a new project. The project template we select here is "SharePoint 2013 - Empty Project". Lets name the solution and project as "SampleAlertHandler" and click OK. 
  2. We will deploy this solution as a farm solution. So lets give internal URL of the SharePoint web application and choose "Deploy as a farm solution" and click Finish button.
  3. Lets add a new class file and name it "CustomAlertHandler.cs". Open the CustomAlertHandler.cs and replace the code with the following code snippet. using System;
    using System.Text;
    using System.Web;
    using System.Collections.Generic;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Utilities;
    using System.IO;

    namespace SampleAlertHandler
    {
        public class CustomAlertHandler : IAlertNotifyHandler
        {
            public bool OnNotification(SPAlertHandlerParams ahp)
            {
                try
                {
                    using (SPSite site = new SPSite(ahp.siteUrl + ahp.webUrl))
                    {
                        //Open the Web
                        using (SPWeb web = site.OpenWeb())
                        {
                            //Get Current Site
                            string webName = web.Name;


                            //Get the list that has been modified
                            SPList list = web.Lists[ahp.a.ListID];

                            //get the item that has been changed
                            SPListItem item = list.GetItemById(ahp.eventData[0].itemId);

                            //path to reach to that item
                            //Lets try to make the Site URL Configurable
                            //We will read the site URL from a text file for external URL, otherwise it will be the interal URL
                            string siteURL = String.Empty;
                            
                            try
                            {
                                siteURL = File.ReadAllText(@"C:\SiteURL\SiteURL.txt");
                                if (siteURL == String.Empty)
                                    siteURL = SPHttpUtility.UrlPathEncode(ahp.siteUrl, true);
                            }
                            catch (Exception ex)
                            {
                               siteURL = SPHttpUtility.UrlPathEncode(ahp.siteUrl, true);
                            }

                            string FullPath = SPHttpUtility.UrlPathEncode(siteURL + ahp.webUrl + "/" + list.Title + "/" + item.Name, true);
                            //path to reach to that list
                            string ListPath = SPHttpUtility.UrlPathEncode(siteURL + "/" + ahp.webUrl + "/" + list.Title, true);
                            //path to reach to that web
                            string webPath = SPHttpUtility.UrlPathEncode(siteURL + "/" + ahp.webUrl, true);

                            
                                                    
                            string to = ahp.headers["to"].ToString();
                            string subject = list.Title.ToString();
                            string body = string.Empty;
                            
                            //Determine what type of event has occured
                            string EventType = "";

                            var eventType = (SPEventType)ahp.eventData[0].eventType;
                            if (eventType == SPEventType.Add)
                            {
                                EventType = "Added";
                            }
                            else if (eventType == SPEventType.Modify)
                            {
                                EventType = "Changed";
                            }
                            else if (eventType == SPEventType.Delete)
                            {
                                EventType = "Deleted";
                            }

                            //this way you can build your email body
                            //also you can apply the bussiness logic that which field to show
                            //change your highlighted words every thing you can do                                             

                            body =
                               "<style type=\"text/css\">" +
                               ".ItemTitle { font-size: larger; font-weight: bold; font-style: italic}" +
                               ".EventType { font-size: larger; }" +
                               ".SmallFonts {font-size: smaller; }" +
                               "</style>";

                            body +=
                                 "<div>" +
                                 "<a class=\"SmallFonts\" href=" + webPath + ">" + webName + "</a><br/>" +
                                 "<div><span class=\"ItemTitle\">" + item.Name.ToString() + "</span><span class=\"EventType\"> has been added</span></div>" +
                                 "<div>" +
                                 "<a class=\"SmallFonts\" href=" + webPath + "/_layouts/mysubs.aspx>Modify my alert settings</a> | " +
                                 "<a class=\"SmallFonts\" href=" + FullPath + ">View " + item.Name + "</a> | " +
                                 "<a class=\"SmallFonts\" href=" + ListPath + ">View " + list.Title + "</a>" +
                                 "</div>";

                           
                            SPUtility.SendEmail(web, true, false, to, subject, body);
                        }
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
        }
    }
  4. Deploy the solution in Release mode. 
  5. Verify that the assembly named SamplerAlertHandler.dll is successfully deployed in GAC for .NET Framework 4.5. Click here to know how to verify that your assembly has been deployed in GAC

2. Modify the Alert Template

The Alert Template used by SharePoint 2013 is located inside 15 hive folder. i.e. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\XML

Inside XML folder, you will find several XML files and the one we require is alerttemplates.xml. Rather than modifying this file directly, we make a copy of this file.

  1. Copy alerttemplates.xml and name it custom_alerttemplates.xml.
  2. Open custom_alerttemplates.xml with any editor tool. Lets use Visual Studio 2012 as we are already using this IDE to build our solution. 
  3. Search for the key word "DocumentLibrary" using Ctrl + F. You will find an AlertTemplate tag as <AlertTemplate Type="List" Name="SPAlertTemplateType.DocumentLibrary">
  4. Find the <Properties> tag inside this AlertTemplate tag and copy following two lines of code inside <Properties> and </Properties> tag. <NotificationHandlerAssembly>SampleAlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a3902394782e8e4e</NotificationHandlerAssembly> <NotificationHandlerClassName>SampleAlertHandler.CustomAlertHandler</NotificationHandlerClassName>
  5. You will require a public key token and version number of your assembly. Click here to find out public key token and version number of your assembly . In my case, the public key token is 33a1b5598fa37cf2 and it may be different for you. Also the version number is 1.0.0.0 for me. 


3. Create a text file to store Internet URL


We could have hardcoded the Internet URL or public URL for our web application. But in order to make it more configurable, our solution reads the Internet URL stored in a text file. 

Lets create a text file named SiteURL.txt inside C:\SiteURL folder and lets write the internet URL in one line as https://access.sharepointrealm.comThis is the public URL of the web application as we specified in Alternate Access Mapping. 

 You can change this Internet URL at any time. 

4. Notify the SharePoint environment to use new Alert Template. 


We will have to use stsadm command for updating the alert template. In SharePoint 2013 environment, the stsadm is available inside 15 hive folder. 
  1. First, open the dos command prompt in Run As Administrator mode. If stsadm is not configured as class path in Environmental Variable, you can navigate to following folder inside command prompt and type stsadm to see if it works. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\bin
  2. Type following command and hit enter.stsadm -o updatealerttemplates -filename "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\XML\custom_alerttemplates.xml" -url "http://sp-realm"
    Include your internal web application URL in place of http://sp-realm
  3. Now reset IIS server and SharePoint Timer Service.
Now you can add new alert to your document library and existing alerts are also affected by this new change. Upload new documents, Delete some existing documents or modify some existing documents to test your functionality. 


Here is the new Alert Email with almost same look and feel except the URLs are changed.











Cheers
















6 comments:

  1. Hi there, just a few erratas:
    The Alert Template used by SharePoint 2013 is located inside 15 hive folder. i.e. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\XML

    The folder should really be ...\15\... up there


    For the extra bit (since the two blog links are dead), to find out the PKI, just hop into the terminal prompt and navigate to the binary which the dll is stored (the project folder, in the release/bin folder): sn -T [name of dll], should reveal the PKI.

    Hope that helps

    ReplyDelete
  2. Dear Friend ,

    Actually my requirement is like I have Two Document Library like Test A and Test B but both i have sent alert configuration.But client received two mails from two document lirbary thats fine .but client need one alret mail summry from both document library.
    Could please tell me how we can approach.




    ReplyDelete
  3. Great solution. I just implemented it in my environment.

    Just a hint: If you want to debug this, you have to attach Visual Studio Debugger to the owstimer.exe-process.

    ReplyDelete
  4. And another hint. Your solution works great for customizing the alert template and adding some more program logic. But if you only want to change the URL of the links inside the e-mail according your aam, you could use the property SPWebApplication.UseExternalUrlZoneForAlerts . See https://technet.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebapplication.useexternalurlzoneforalerts for details.

    ReplyDelete
  5. this is not working for daily and weekly alert.

    ReplyDelete
  6. Sharepoint Realm: How To Cusomize Alert Email For Sharepoint 2013 >>>>> Download Now

    >>>>> Download Full

    Sharepoint Realm: How To Cusomize Alert Email For Sharepoint 2013 >>>>> Download LINK

    >>>>> Download Now

    Sharepoint Realm: How To Cusomize Alert Email For Sharepoint 2013 >>>>> Download Full

    >>>>> Download LINK ow

    ReplyDelete