Next objectives must be addressed for completing the task:
- what will trigger the notification – time based timer job (implies WSP package on prem or Azure hosted .Net code in o365) or hitting the "Post" button in the Note Board web part (JavaScript somehow…)
- what will notification include – I guess the bare minimum that would be required is what is the page and what the last posted comment was
- what kind of notification is required – email or something else
Here is how to achieve this:
- subscribe to the "Post" button for the Note Board web part after the comment has been posted to the discussion history
$(".ms-socialCommentContents input[id$='_PostBtn']").click(function () {
//todo: your custom code here
return false;
});
- read with SocialDataService.asmx the last comment for this page
function GenerateDataXML (url) {
var d1 = new Date ();
var d2 = new Date ( d1 );
d2.setHours ( d1.getHours() - 1 );
var d3 = d2.toISOString();;
var soapXml = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<GetCommentsOnUrl xmlns=\"http://microsoft.com/webservices/SharePointPortalServer/SocialDataService\">" +
"<url>" + url + "</url>" +
"<maximumItemsToReturn>5</maximumItemsToReturn>" +
"<startIndex>0</startIndex>" +
"<excludeItemsTime>" + d3 + "</excludeItemsTime>" +
"</GetCommentsOnUrl>" +
"</soap:Body>" +
"</soap:Envelope>" ;
return soapXml;
}
Then, we can fetch the last comment made and retrieve the text and use who posted it:
$(content).find('SocialCommentDetail').each(function (index) {
if (index == 0)
{
var comment = $(this);
var owner = comment.find('Owner')[0].innerHTML;
var text = unescape(comment.find('Comment')[0].textContent);
callback(owner, text);
return false;
}
});
- then we use SP.Utilities.Utility.SendEmail to send email
function ReturnLastComment(url, callback) {
var dataXML = GenerateDataXML([url]);
var soapAction = "http://microsoft.com/webservices/SharePointPortalServer/SocialDataService/GetCommentsOnUrl";
var svcUrl = window.location.protocol + "//" + window.location.host + _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/SocialDataService.asmx";
$.ajax({
url: svcUrl,
data: dataXML,
headers: {
'SOAPAction': soapAction,
'Content-Type': 'text/xml; charset=\"utf-8\"',
'Accept': 'application/xml, text/xml, */*'
},
dataType: "xml",
method: "POST",
transformRequest: null,
success: processResult,
error: function (request, error) {
console.log('error: ' + request.responseText);
}
})
//Following function generates the require soap XML
function GenerateDataXML (url) {
var d1 = new Date ();
var d2 = new Date ( d1 );
d2.setHours ( d1.getHours() - 1 );
var d3 = d2.toISOString();;
var soapXml = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<GetCommentsOnUrl xmlns=\"http://microsoft.com/webservices/SharePointPortalServer/SocialDataService\">" +
"<url>" + url + "</url>" +
"<maximumItemsToReturn>5</maximumItemsToReturn>" +
"<startIndex>0</startIndex>" +
"<excludeItemsTime>" + d3 + "</excludeItemsTime>" +
"</GetCommentsOnUrl>" +
"</soap:Body>" +
"</soap:Envelope>" ;
return soapXml;
}
function processResult(content, txtFunc, xhr) {
$(content).find('SocialCommentDetail').each(function (index) {
if (index == 0)
{
var comment = $(this);
var owner = comment.find('Owner')[0].innerHTML;
var text = unescape(comment.find('Comment')[0].textContent);
callback(owner, text);
return false;
}
});
}
}
function bindCommentsEvents()
{
$(".ms-socialCommentContents input[id$='_PostBtn']").click(function () {
var currentPageUrl = window.location.protocol + "//" + window.location.host + _spPageContextInfo.serverRequestPath;
ReturnLastComment(currentPageUrl, function (owner, text) {
var result = "last comment: " + owner + "; " + text;
//alert(result);
var mailBody = "<br>commented by: " + owner + "<br>" + "page: " + currentPageUrl + "<br>comment: " + text;
processSendEmails(mailBody)
});
return false;
});
}
function processSendEmails(body) {
var from = 'no-reply@domain',
to = 'xxxx@domain',
body = 'A comment has just been added to one of your pages.\n' + body,
subject = 'New Comment';
// Call sendEmail function
//
sendEmail(from, to, body, subject);
}
function sendEmail(from, to, body, subject) {
//Get the relative url of the site
var siteurl = _spPageContextInfo.webServerRelativeUrl;
var urlTemplate = siteurl + "/_api/SP.Utilities.Utility.SendEmail";
$.ajax({
contentType: 'application/json',
url: urlTemplate,
type: "POST",
data: JSON.stringify({
'properties': {
'__metadata': {
'type': 'SP.Utilities.EmailProperties'
},
'From': from,
'To': {
'results': [to]
},
'Body': body,
'Subject': subject
}
}),
headers: {
"Accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
},
success: function(data) {
console.log('Email Sent Successfully');
},
error: function(err) {
console.log('Error in sending Email: ' + JSON.stringify(err));
}
});
}
- Outgoing email settings must be configured if on-premises
- make sure the function that subscribes to click button of the Post button (bindCommentsEvents) is invoked on your page load – it could be through Script Editor web part
- if there is more than one web part on your page you may need to adjust your jquery selector
Read full article!