Convert to Case: Displaying email contents

There are two ways to create case from an incoming email:

  1. Automatic record creation rules
  2. Convert to Case button in the email command bar

converttocase.png

Once a case is created, there may be so many other activities associated with that case and the email that was used to create the case might be all the way down in the activity feed. For quick reference you might just want to see the email content right on the case itself.

If you try to copy the email’s description field that stores the email content into a multiline text field on the case, you’ll face issues because of rich text emails. Most email sent these days are HTML emails, and Dynamics CRM doesn’t have a rich text field yet. So when you copy a rich text content into a field you will get everything i.e. content+markup. For example below is a simple email sent from outlook.

outlookemail

This is what will be copied to the text field on the case, when you copy the email entity’s description field. Now I will show you an approach to do this using a HTML webresource and Javascript. Below is the code for the HTML webresource that is embedded into the Case form.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Email Body</title>
</head>
<body>
	<h3>Case Source Email</h3>
	<div id="description"></div>
</body>
<script>
	var RYR = window.RYR || {};
	var Xrm = parent.Xrm;
	
	RYR.retrieveEntityWebApi = function(entityName,recordId,additionalCriteria) {
		var headers = new Headers({
		"Accept": "application/json",
		"Content-Type": "application/json; charset=utf-8",
		"OData-MaxVersion": "4.0",
		"OData-Version": "4.0"
		});
			
		fetch("/api/data/v8.0/"+entityName+"?$select=activityid,description&$filter=_regardingobjectid_value eq "+recordId, 
		{   method: 'GET',
			headers: headers,
			credentials: 'include' //without this header, the request will fail
		})
		.then(function(response){
			return response.json();
		})
		.then(function(c){
			if(c.value && c.value.length > 0) {
				document.getElementById('description').innerHTML = c.value[0].description;
				Xrm.Page.ui.tabs.get('general').sections.get('emailsection').setVisible(true);
			}
		})
		.catch(function(err) {
			console.log(err);
		});
	};
	
	RYR.retrieveEntityOData = function(entityName,recordId,additionalCriteria,callback) {
		var odataUrl = "/XRMServices/2011/OrganizationData.svc/"+entityName+"?$select=ActivityId,Description&$filter=RegardingObjectId/Id eq (guid'"+recordId+"')";
		if(additionalCriteria) {
			odataUrl += additionalCriteria;
		}				
		var retrieveReq = new XMLHttpRequest();
		retrieveReq.open("GET", odataUrl, false);
		retrieveReq.setRequestHeader("Accept", "application/json");
		retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
		retrieveReq.onreadystatechange = function () {
			if(callback) {
				callback(this);
			}
		};
		retrieveReq.send();
	};	
	
	var processEmailResults = function (response) {
			if (response.readyState == 4) {
				var emails = JSON.parse(response.responseText).d.results;
				if(emails.length > 0) {
					document.getElementById('description').innerHTML = emails[0].Description;
					Xrm.Page.ui.tabs.get('general').sections.get('emailsection').setVisible(true);
				}
			}
	};
	
	var retrieveEmailBody = function() {
		var recordId = Xrm.Page.data.entity.getId().substr(1,36);//Get rid of '{' and '}'
		if(!window.fetch ||
			!Xrm.Page.context.getVersion ||
			Xrm.Page.context.getVersion().split('.')[0] !== '8') {
			RYR.retrieveEntityOData('EmailSet',recordId,'&$top=1&$orderby=CreatedOn',processEmailResults);
		}
		else {
			RYR.retrieveEntityWebApi('emails',recordId,'&$top=1&$orderby=CreatedOn');
		}
	};
	
	if(Xrm.Page.ui.getFormType() === 2) retrieveEmailBody();
	
	window.RYR = RYR;
</script>	
</html>

This is how it looks on the Case form

Case

As I was just experimenting with various features, I have tried two approaches: standard XHR with the old OData endpoint and using fetch API with the Web API endpoint in Dynamics CRM 2016. I believe this is a better approach going forward. You can just include fetch polyfill and start using fetch today.

I initially didn’t want to try a code based approach. I created a Quick View Form on the email entity, stored the initial email record as a lookup field in the case and then use the Quick View Form to display the email on the case. But it didn’t display the email content.

I suspect this is because of the  warning “The email below might contain script or content that is potentially harmful and has been blocked.” displayed on the email. My theory is that once the email is tagged as unsafe by CRM, you cannot use Quick View Form to display its contents.

emailwarning

References:

  1. https://developer.mozilla.org/en/docs/Web/API/Fetch_API
  2. https://davidwalsh.name/fetch
  3. MSDN – Web API EntityType Reference
  4. MSDN – Retrieve an entity using Web API
  5. MSDN – Query data using Web API
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s