Send Sitecore workflows notifications to users based on Sitecore roles
In many Sitecore solutions, there are different areas, where different editors and publishers maintains content in their respective areas. Sometimes these areas overlap.
In this blog post I will give an example of how to send workflow notifications to the different publishers and editors without being restricted to where in the structure the item is created/edited.
In this example, I have a Publisher Role and an Editor Role, where access rights to workflow commands and other Sitecore roles has been added.
The owner roles (owner publisher and owner editor) will inherit from these roles. the owner roles are primarily used to control which users should get notifications in this example, I also use, the owner set on the item to control access rights programmatically but I won't cover this in this blog post.
Since the publishers and editors will be given different roles we can on item creation set this droplink field programmatically based on their role:
/?sc_mode=edit&sc_itemid=" + contentItem.ID
In this blog post I will give an example of how to send workflow notifications to the different publishers and editors without being restricted to where in the structure the item is created/edited.
Creating a connection to roles and the Sitecore item
I created a droplink field on the Sitecore items which use workflows so we can connect this item to the corresponding roles.
The droplink is populated based on a data folder with items that has the Roles specified.
In this example, I have a Publisher Role and an Editor Role, where access rights to workflow commands and other Sitecore roles has been added.
The owner roles (owner publisher and owner editor) will inherit from these roles. the owner roles are primarily used to control which users should get notifications in this example, I also use, the owner set on the item to control access rights programmatically but I won't cover this in this blog post.
Since the publishers and editors will be given different roles we can on item creation set this droplink field programmatically based on their role:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void OnItemCreated(object sender, EventArgs args) | |
{ | |
User currentUser = Sitecore.Context.User; | |
if (currentUser.IsInRole("sitecore\\Mysite Publisher") || | |
currentUser.IsInRole("sitecore\\Mysite Editor"))//if the users are ourside of these roles we cannot set the owner programatically | |
{ | |
var createdArgs = Event.ExtractParameter(args, 0) as ItemCreatedEventArgs; | |
Item owner = null; | |
string userRole = ""; | |
Assert.IsNotNull(createdArgs, "args"); | |
if (createdArgs != null) | |
{ | |
Assert.IsNotNull(createdArgs.Item, "item"); | |
if (createdArgs.Item != null) | |
{ | |
Item currentItem = createdArgs.Item; | |
currentItem.Editing.BeginEdit(); | |
try | |
{ | |
Item ownersRoot = SiteConfiguration.GetOwnersRootItem();//Helper class to get the root datafolder for Owners | |
foreach (Item ownerItem in ownersRoot.Children) | |
{ | |
foreach (Role role in currentUser.Roles) | |
{ | |
if (role.LocalName == ownerItem["Publisher Role"])//Since some publishers also could create items | |
{ | |
owner = ownerItem; | |
} | |
if (role.LocalName == ownerItem["Editor Role"]) | |
{ | |
owner = ownerItem; | |
} | |
} | |
} | |
if (owner != null) | |
{ | |
if (currentItem.Fields != null && currentItem.Fields["Owner"] != null) | |
{ | |
currentItem.Fields["Owner"].Value = owner.ID.ToString();//sets the field to the correct Item ID | |
} | |
} | |
} | |
finally | |
{ | |
currentItem.Editing.EndEdit(); | |
} | |
} | |
} | |
} | |
} |
Creating worflow notification on Submit
On the submit command I created an action NotifyOnSubmit, here I send an email to all the publishers who has the corresponding role as the owner of the item. I could have used the current role of the logged in user, but this was not always the correct action when I created this logic. for another solution that would probably be a better approach
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NotifySubmit | |
{ | |
public void Process(WorkflowPipelineArgs args) | |
{ | |
var contentItem = args.DataItem; | |
var currentUser = Sitecore.Context.User; | |
Item ownersRoot = SiteConfiguration.GetOwnerssRootItem();//gets the root item of owners so we can traverse it later | |
var comment = args.CommentFields.Values.ElementAt(0);//gets the comment add this to the email | |
//############## Build you Email content #######################333 | |
// to use the send mail code below you should add emailbody, fromemail and subject | |
//I would recommend to add direct links to content editor/experience editor | |
// /sitecore/shell/Applications/Content Editor.aspx?fo= + contentItem.ID | |
// /?sc_mode=edit&sc_itemid=" + contentItem.ID | |
Log.Info("NotifySubmit - User request from: " + currentUser.Name, this); | |
foreach (Item owner in ownersRoot.Children) | |
{ | |
Role editorRole = Role.FromName(owner["Editor Role"]); | |
if (currentUser.IsInRole(editorRole)) | |
{ | |
var users = System.Web.Security.Roles.GetUsersInRole(owner["Publisher Role"]); | |
foreach (var user in users)//we travers all the users who has the correct role and send them an notification email | |
{ | |
var membershipUser = System.Web.Security.Membership.GetUser(user); | |
var email = membershipUser.Email; | |
if (email != null) | |
{ | |
var emailMessage = new MailMessage(fromEmail, email, subject, emailBody); | |
emailMessage.IsBodyHtml = true; | |
MainUtil.SendMail(emailMessage); | |
Log.Info("NotifySubmit - mail sendt to: " + email, this); | |
} | |
} | |
} | |
} | |
} | |
} |
Creating worflow notification on approve
On the awaiting approval command I created an action NotifyOnApprove action. Here we send an email to all the publishers and super administrators in the solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void Process(WorkflowPipelineArgs args) | |
{ | |
var contentItem = args.DataItem; | |
var currentUser = Sitecore.Context.User; | |
Item ownersRoot = SiteConfiguration.GetOwnersRootItem();//gets the owner root item | |
var comment = args.CommentFields.Values.ElementAt(0); | |
// build the email, you need to add fromadress, emailbody and subject | |
foreach (Item owner in ownersRoot.Children) | |
{ | |
var users = System.Web.Security.Roles.GetUsersInRole(owner["Publisher Role"]);//get all users with this role so we can send them notification | |
foreach (var user in users) | |
{ | |
var membershipUser = System.Web.Security.Membership.GetUser(user); | |
var email = membershipUser.Email; | |
if (email != null) | |
{ | |
var emailMessage = new MailMessage(fromEmail, email, subject, emailBody); | |
emailMessage.IsBodyHtml = true; | |
MainUtil.SendMail(emailMessage); | |
} | |
} | |
} | |
//We also send notification to all the super administrators | |
var administratorUsers = System.Web.Security.Roles.GetUsersInRole("sitecore\\MySite SuperAdministrator"); | |
foreach (var user in administratorUsers) | |
{ | |
var membershipUser = System.Web.Security.Membership.GetUser(user); | |
var email = membershipUser.Email; | |
if (email != null) | |
{ | |
var emailMessage = new MailMessage(fromEmail, email, subject, emailBody); | |
emailMessage.IsBodyHtml = true; | |
MainUtil.SendMail(emailMessage); | |
} | |
} | |
} |
Creating workflow notification on Reject
On the awaiting approval command I created an action NotifyReject action, Here we collect the last workflow history to get the correct email we should send the reject notification to
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NotifyReject
{
public void Process(WorkflowPipelineArgs args)
{
var contentItem = args.DataItem;
var currentUser = Sitecore.Context.User;
// build the email, you need to add fromadress, emailbody and subject
var comment = args.CommentFields.Values.ElementAt(0);// gets the last comment
Log.Info("NotifyReject - User rejected change from: " + currentUser.Name, this);
var contentWorkflow = contentItem.Database.WorkflowProvider.GetWorkflow(contentItem);
var contentHistory = contentWorkflow.GetHistory(contentItem);
if (contentHistory.Length > 0)
{
var lastUser = contentHistory.Last().User;
var submittingUser = User.FromName(lastUser, false);
var email = submittingUser.Profile.Email;
var emailMessage = new MailMessage(fromEmail, email, subject, emailBody);
emailMessage.IsBodyHtml = true;
MainUtil.SendMail(emailMessage);
Log.Info("NotifyReject - mail sendt to: " + email, contentItem);
}
}
}
Setting the owner field as required
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NotifyReject | |
{ | |
public void Process(WorkflowPipelineArgs args) | |
{ | |
var contentItem = args.DataItem; | |
var currentUser = Sitecore.Context.User; | |
// build the email, you need to add fromadress, emailbody and subject | |
var comment = args.CommentFields.Values.ElementAt(0);// gets the last comment | |
Log.Info("NotifyReject - User rejected change from: " + currentUser.Name, this); | |
var contentWorkflow = contentItem.Database.WorkflowProvider.GetWorkflow(contentItem); | |
var contentHistory = contentWorkflow.GetHistory(contentItem); | |
if (contentHistory.Length > 0) | |
{ | |
var lastUser = contentHistory.Last().User; | |
var submittingUser = User.FromName(lastUser, false); | |
var email = submittingUser.Profile.Email; | |
var emailMessage = new MailMessage(fromEmail, email, subject, emailBody); | |
emailMessage.IsBodyHtml = true; | |
MainUtil.SendMail(emailMessage); | |
Log.Info("NotifyReject - mail sendt to: " + email, contentItem); | |
} | |
} | |
} |
For all templates which have the workflow added, it is required to have the owner set on the Sitecore item for workflow notifications to be sent to the correct users. this is partially covered by setting the owner on item creation, however super admins and developers could be creating content items without these roles. I have set the owner droplink to be required so we do not end up with items with missing owners.
Recommended links to send to the publishers
/sitecore/shell/Applications/Content Editor.aspx?fo= + contentItem.ID/?sc_mode=edit&sc_itemid=" + contentItem.ID
Comments