/ #tips&tricks 

Noteboard to send e-mails to author

The noteboard WebPart that is introduced in SharePoint 2010 is pretty cool since it allows you to share comments and thoughts on any given pag, enabling more social interaction on your site. Yet there are two different versions (or implementations) of the WebPart:

  • The one on the MySite
  • The one you can add to pages yourself

The version on the MySite is a bit different configured as the one you can add yourself. The WebPart that can be added to the page allows you to share comments and ideas on any given page but will not notify anyone once a user adds a comment to a page, while the one on the mysite works a bit different. Whenever someone adds a question to a user’s mysite the noteboard WebPart will send a notification to that person’s mysite. Having such a notification can come in handy thus I would have expected it to be a configuration option to the default WebPart.

Due to unknown reasons that is not the case, having no options to configure a noteboard. However if you would open something to decompile the code you will soon find out that the WebPart added to the mysite is in fact the same WebPart you can add to the page yourself, and will set only one extra property, the EditorEmail with some handy reflection, as the guys at SharePoint Blues prove in a nice post about extending the SocialCommentControl.

Based on those findings, I created a new version of the WebPart that allows you to set the contact e-mail for a noticeboard. The Editor Email can be set using a configuration property in the WebPart itself, or by leaving it blank. If left blank the WebPart will try to resolve the e-mail address based on the author of the current page.

Whenever one of these values are found they are set to the Social Comment WebPart (that will act like the noteboard), and whenever a user adds a comment to the page the configured users email will receive word of that update.

The WebPart is pretty self explanatory and straight forward:

using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using Mavention.SharePoint.NoteBoard.WebControls;
using Microsoft.SharePoint;

namespace Mavention.SharePoint.NoteBoard.WebParts.NoteBoard
{
    /// <summary> 
    /// WebPart container for the SocialComments control. the functionality in the control is an extension of an OOB WebControl. Since we need it  
    ///     as a WebPart, we use this container. 
    /// </summary> 
    [ToolboxItemAttribute(false)]
    public class NoticeBoard : System.Web.UI.WebControls.WebParts.WebPart
    {
        [Category("Mavention Settings")]
        [WebDescription("Enter the ContactEmail adress used for the Social Comment WebPart.")]
        [WebBrowsable(true)]
        [WebDisplayName("Contact E-mail")]
        [Personalizable(PersonalizationScope.Shared)]
        public string ContactEmail { get; set; }

        /// <summary> 
        /// Sets up the internal SocialComment WebControl 
        /// </summary> 
        protected override void CreateChildControls()
        {
            SocialComments socialComments = new SocialComments();
            
            // Construct the Contact Email, if it is empty lets use the author of the page
            string cEmail = ContactEmail;
            if (string.IsNullOrEmpty(cEmail))
            {
                SPFieldUserValue userValue = new SPFieldUserValue(SPContext.Current.Web, SPContext.Current.ListItem[SPBuiltInFieldId.Author].ToString());
                if (!string.IsNullOrEmpty(userValue.User.Email))
                {
                    cEmail = userValue.User.Email; 
                }
            }
            socialComments.EditorEmail = cEmail;                               
            Controls.Add(socialComments);
        }
    }
}

And for the SocialCommentsControl I made a slightly simplified version

using System;
using System.Web.UI;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Portal.WebControls;
using Microsoft.SharePoint.Utilities;

namespace Mavention.SharePoint.NoteBoard.WebControls
{
    /// <summary>
    /// Extension of SocialCommentControl which sends an E-mail whenever a comment is posted.
    /// Code courtsesy of http://www.sharepointblues.com/2011/04/06/extending-the-socialcommentcontrol/ with minor adjustments.
    /// </summary>
    public class SocialComments : SocialCommentControl, ICallbackEventHandler
    {
        /// <summary>
        /// The recipient of the mails.
        /// </summary>
        public string EditorEmail { get; set; }

        /// <summary>
        /// DOM fix 
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            // the DOM is a terrible thing to break
            // http://www.sharepointblues.com/2010/09/28/fix-disabled-page-scrolling-on-navigation-settings/
            Controls.Add(new LiteralControl("</div>"));
        }

        /// <summary>
        /// CallBack Event to actually send the e-mail
        /// </summary>
        /// <param name="eventArgument"></param>
        public void RaiseCallbackEvent(string eventArgument)
        {
            base.RaiseCallbackEvent(eventArgument);

            try
            {
                if (EditorEmail == null)
                {
                    return;
                }

                string currentUser = SPContext.Current.Web.CurrentUser.Name;

                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPListItem item = SPContext.Current.ListItem;
                    string url = SPContext.Current.Web.Url + "/" + item.Url;

                    XmlDocument document = new XmlDocument();
                    document.LoadXml(eventArgument);
                    XmlElement documentElement = document.DocumentElement;

                    /*
                        eventArgument when added:
                        <Item  type='Add'>
                            <Title>News</Title>
                            <RTEContents>This is a new comment</RTEContents>
                        </Item>

                         eventArgument when edited
                        <Item type='Edit' 
                        SequenceId='0' 
                        CommentId='144' 
                        CurrentPage='1' >
                        <RTEContents>This is an&#160;edited comment</RTEContents>
                        </Item>
                    */
                    if (documentElement != null)
                    {
                        string oEvent = documentElement.GetAttribute("type");
                        if (oEvent != "Get")
                        {
                            if (oEvent == "Add" || oEvent == "Edit")
                            {
                                var contentElement = (XmlElement)documentElement.SelectSingleNode("./RTEContents");
                                var content = SPHttpUtility.NoEncode(contentElement.InnerText);
                                var subject = string.Format("Comment added: {0}", SPContext.Current.Web.Title);
                                var message = string.Format(@"Content: {0}<br/><br/>By : {1}<br/><br/>Url: {2}", content, currentUser, url);
                                if (!SPUtility.SendEmail(SPContext.Current.Web, true, false, EditorEmail, subject, message))
                                {
                                    // log error sending mail
                                }
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                // Log error
            }
        }
    }
}