Sending History Notes using Custom Workflow

Long time back we wrote a post to get history notes using custom workflow, in this post we are providing updated version of the code supported for CRM 2011/2013/2015.

Requirement: If you have requirement to send notification when new note is added to any entity record where you have notes relationship enabled, for example let’s say when any notes entered to any critical opportunity, you want to notify to sales manager and want to send him latest notes with history notes as well.

Solution: We can write custom workflow for this, you can use source code from this post to build custom workflow and can register it to CRM environment. If you are new to Custom workflow development then first check our Step By Step Creating Custom Workflow, post for how to setup custom workflow assembly using Visual Studio.

public class GetHistoricalNotes: CodeActivity {
	public InOutArgument <string> HistoryNotes {
	protected override void Execute(CodeActivityContext context) {
		string notestMessage = string.Empty;
		//Create the tracing service
		ITracingService tracingService = context.GetExtension < ITracingService > ();
		//Create the context
		IWorkflowContext wkfContext = context.GetExtension < IWorkflowContext > ();
		IOrganizationServiceFactory serviceFactory = context.GetExtension < IOrganizationServiceFactory > ();
		IOrganizationService service = serviceFactory.CreateOrganizationService(wkfContext.UserId);
		//Get RegardingID
		Entity currentNotes = (Entity) service.Retrieve("annotation", wkfContext.PrimaryEntityId, new ColumnSet(new string[] {
		//GetAll Related Notes
		notestMessage = GetNotes(currentNotes.GetAttributeValue < EntityReference > "objectid").Id, service);
	this.HistoryNotes.Set(context, notestMessage);

In above code we are reading additional columns from annotation (notes) entity and passing regardingobject id to below method:

private string GetNotes(Guid regarding, IOrganizationService crmservice) {
	StringBuilder notesStringBuilder = new StringBuilder();
	ColumnSet columSet = new ColumnSet(new string[] {
		"notetext", "objectid", "subject", "createdby", "createdon"
	QueryExpression query = new QueryExpression() {
		EntityName = "annotation",
		ColumnSet = columSet,
		Criteria = {
			Conditions = {
				new ConditionExpression("objectid", ConditionOperator.Equal, regarding)
	EntityCollection historynotesCollection = crmservice.RetrieveMultiple(query);
	if (historynotesCollection != null && historynotesCollection.Entities.Count > 0) {
		foreach(Entity notes in historynotesCollection.Entities) {
			if (notes.Contains("subject") && !string.IsNullOrEmpty(notes["subject"].ToString())) {
				notesStringBuilder.AppendLine("Subject :" + notes["subject"].ToString());
			if (notes.Contains("notetext") && !string.IsNullOrEmpty(notes["notetext"].ToString())) {
				notesStringBuilder.AppendLine("\n Description :" + notes["notetext"].ToString());
			if (notes.Contains("createdon") && !string.IsNullOrEmpty(notes["createdon"].ToString())) {
				notesStringBuilder.AppendLine("\n CreatedOn :" + notes.GetAttributeValue < DateTime > ("createdon").ToShortDateString());
			if (notes.Contains("createdby") && !string.IsNullOrEmpty(notes["createdby"].ToString())) {
				notesStringBuilder.AppendLine("\n Created By :" + notes.GetAttributeValue < EntityReference > ("createdby").Name);
	return notesStringBuilder.ToString();

After using above code we can build our workflow assembly and can register to our CRM environment using latest plug-in registration tool. After that we can design a workflow where first we need to select our custom workflow step and then we can use it in email step like below:


One thought on “Sending History Notes using Custom Workflow

  1. Pingback: Sending History Notes using Custom Workflow - Microsoft Dynamics CRM Community

Leave a Reply