How is it possible to display an EMail Activity Formatter of a referenced record ?

ahammoud
Tera Guru

Hello,

I am trying to display the Activity formatter of a referenced record from the Calls table [new_call] in an Incident form.

The objective is to bring the entire Activity stream, especially the Emails part.

I came across this interesting article explaining how to make a custom Activity Formatter in a UI page to display the Activity of any record from any table and it works BUT it does NOT display the emails.

http://inmorphis.com/blogs/activity-formatter-ui-page/

I noticed ServiceNow uses an "email-formatter" to display emails in their activity.xml UI macro global formatter, but that is no where to be found in the instance.

I am using Geneve patch8 UI15

Original Activity stream from referenced Record:

find_real_file.png

Activity of referenced record in a UI page (no emails)

find_real_file.png

1 ACCEPTED SOLUTION

ahammoud
Tera Guru

I found the solution for this problem. Basically we want to display the email log of a referenced record in activity formatter style on a form.


1. For this to work you first need to create an Activity Formatter for the table of choice (in this example Incident) and then add the Formatter to the section you want (or create a new form Section)


2. In the Activity Formatter created specify the UI macro Formatter you will use. (in this example   "call_email_formatter.xml")


3. Create the Following UI Macro with the following code:


NOTE: In the example below we are looking up the record in the [new_call] table that generated the Incident [incident] and then displaying the emails of the New Call in the Incident



Name: call_email_formatter


XML:


<?xml version="1.0" encoding="utf-8" ?>  




<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">  


  <g2:evaluate var="emailGr" >


  var callgr = new GlideRecord('new_call');


  callgr.addQuery('transferred_to', current.sys_id);


  callgr.query();



  if (callgr.next()){


  var emailsgr = new GlideRecord('sys_email');


  emailsgr.addQuery('instance', callgr.sys_id);


  emailsgr.addQuery('type', 'IN', 'received,sent');


  emailsgr.orderByDesc('sys_created_on');


  emailsgr.query();


  }


  </g2:evaluate>




<j2:while test="$[emailsgr.next()]">



  <!-- <table style="margin-left:-2px" width="100%"> -->


  <tbody>


  <tr>


  <td class="email-formatter">


  <img title="" src="images/email.gifx" data-original-title="Email"></img>


  <a id="$[emailsgr.getValue('sys_id')].img" class="btn btn-default btn-xs icon-remove" src="images/filter_hide.gifx" tabindex="-1" aria-expanded="false" title ="" aria-controls="$[emailsgr.getValue('sys_id')].detail" onclick="ActivityFilter.activityEmailToggle('$[emailsgr.getValue('sys_id')]', '');" data-original-title="Show email details">


  <span class="sr-only">Show email details</span>


  </a>


  <g2:evaluate var="jvar_send_receive">


  var emailStatus = 'Sent';


  if (emailsgr.type == 'received')


  emailStatus = 'Received';



  emailStatus;


  </g2:evaluate>


  <j2:if test="$[jvar_send_receive == 'Received']">


  <b>${gs.getMessage("Received")}:$[AMP]nbsp;</b>


  </j2:if>



  <j2:if test="$[jvar_send_receive == 'Sent']">


  <b>${gs.getMessage("Sent")}:$[AMP]nbsp;</b>


  </j2:if>



  <span>$[emailsgr.getValue('recipients')]</span>


  <div class="email-formatter-detail" id="$[emailsgr.getValue('sys_id')].detail">


  <div class="email-formatter-header">



  <dl class="dl-horizontal"><dt>${gs.getMessage("From")}</dt>



  <g2:evaluate var="jvar_header_sender">


  var emailSender1 = '';


  var emailSender = '';    


  emailSender1 = emailsgr.headers;


  if (emailsgr.type == 'received'){


  var emailUtil= new emailUtilFormat();


  emailSender = emailUtil.headerReceived(emailSender1);


  }



  else {


  var emailUtil= new emailUtilFormat();


  emailSender = emailUtil.headerSent(emailSender1);


  }



  emailSender;


  </g2:evaluate>



  <dd>$[jvar_header_sender]</dd><dt>${gs.getMessage("Sent")}</dt><dd>$[emailsgr.getDisplayValue('sys_created_on')]</dd><dt>${gs.getMessage("To")}</dt><dd>$[emailsgr.getValue('recipients')]</dd><dt>${gs.getMessage("Subject")}</dt><dd>$[emailsgr.getValue('subject')]</dd>


  </dl>



  </div>


  <div class="email-formatter-detail" id="$[emailsgr.getValue('sys_id')].mail_cell"><iframe id="$[emailsgr.getValue('sys_id')].body" width="100%" frameborder="0" src="email_display.do?email_id=$[emailsgr.getValue('sys_id')]" style="height: 890px;"></iframe>


  </div>


  <div class="email-formatter-reply"><button type="button" onclick="emailClientOpenPop('incident', true, 'reply', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Reply")}</button><button type="button" onclick="emailClientOpenPop('incident', true, 'replyall', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Reply all")}</button><button type="button" onclick="emailClientOpenPop('incident', true, 'forward', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Forward")}</button>


  </div>


  </div>




  </td>


  </tr>


  </tbody>


  <!-- </table> -->



</j2:while>




</j:jelly>




4.You will also need to create a Script Include to get the Sender info from the Emails Header:


Name: emailUtilFormat


API Name: global.emailUtilFormat



Script:


var emailUtilFormat = Class.create();


emailUtilFormat.prototype = {


  headerReceived: function(header) {


  //gs.log("We are in script Inclue email Util");



  var newHeader1 = "";


  newHeader1 = header.substring(header.lastIndexOf('Return-Path:')+12,header.lastIndexOf('Delivered-To'));



  newHeader1= newHeader1.replace('<','');


  newHeader1= newHeader1.replace('>','');



  return newHeader1;


  },



  headerSent: function(header) {


  //gs.log("We are in script Inclue email Util");



  var newHeader1 = "";


  newHeader1 = header.substring(header.lastIndexOf('From:')+5,header.lastIndexOf('Reply-To'));




  return newHeader1;


  },



  type: 'emailUtilFormat'


};




Hope this helps !



Result:



find_real_file.png


View solution in original post

1 REPLY 1

ahammoud
Tera Guru

I found the solution for this problem. Basically we want to display the email log of a referenced record in activity formatter style on a form.


1. For this to work you first need to create an Activity Formatter for the table of choice (in this example Incident) and then add the Formatter to the section you want (or create a new form Section)


2. In the Activity Formatter created specify the UI macro Formatter you will use. (in this example   "call_email_formatter.xml")


3. Create the Following UI Macro with the following code:


NOTE: In the example below we are looking up the record in the [new_call] table that generated the Incident [incident] and then displaying the emails of the New Call in the Incident



Name: call_email_formatter


XML:


<?xml version="1.0" encoding="utf-8" ?>  




<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">  


  <g2:evaluate var="emailGr" >


  var callgr = new GlideRecord('new_call');


  callgr.addQuery('transferred_to', current.sys_id);


  callgr.query();



  if (callgr.next()){


  var emailsgr = new GlideRecord('sys_email');


  emailsgr.addQuery('instance', callgr.sys_id);


  emailsgr.addQuery('type', 'IN', 'received,sent');


  emailsgr.orderByDesc('sys_created_on');


  emailsgr.query();


  }


  </g2:evaluate>




<j2:while test="$[emailsgr.next()]">



  <!-- <table style="margin-left:-2px" width="100%"> -->


  <tbody>


  <tr>


  <td class="email-formatter">


  <img title="" src="images/email.gifx" data-original-title="Email"></img>


  <a id="$[emailsgr.getValue('sys_id')].img" class="btn btn-default btn-xs icon-remove" src="images/filter_hide.gifx" tabindex="-1" aria-expanded="false" title ="" aria-controls="$[emailsgr.getValue('sys_id')].detail" onclick="ActivityFilter.activityEmailToggle('$[emailsgr.getValue('sys_id')]', '');" data-original-title="Show email details">


  <span class="sr-only">Show email details</span>


  </a>


  <g2:evaluate var="jvar_send_receive">


  var emailStatus = 'Sent';


  if (emailsgr.type == 'received')


  emailStatus = 'Received';



  emailStatus;


  </g2:evaluate>


  <j2:if test="$[jvar_send_receive == 'Received']">


  <b>${gs.getMessage("Received")}:$[AMP]nbsp;</b>


  </j2:if>



  <j2:if test="$[jvar_send_receive == 'Sent']">


  <b>${gs.getMessage("Sent")}:$[AMP]nbsp;</b>


  </j2:if>



  <span>$[emailsgr.getValue('recipients')]</span>


  <div class="email-formatter-detail" id="$[emailsgr.getValue('sys_id')].detail">


  <div class="email-formatter-header">



  <dl class="dl-horizontal"><dt>${gs.getMessage("From")}</dt>



  <g2:evaluate var="jvar_header_sender">


  var emailSender1 = '';


  var emailSender = '';    


  emailSender1 = emailsgr.headers;


  if (emailsgr.type == 'received'){


  var emailUtil= new emailUtilFormat();


  emailSender = emailUtil.headerReceived(emailSender1);


  }



  else {


  var emailUtil= new emailUtilFormat();


  emailSender = emailUtil.headerSent(emailSender1);


  }



  emailSender;


  </g2:evaluate>



  <dd>$[jvar_header_sender]</dd><dt>${gs.getMessage("Sent")}</dt><dd>$[emailsgr.getDisplayValue('sys_created_on')]</dd><dt>${gs.getMessage("To")}</dt><dd>$[emailsgr.getValue('recipients')]</dd><dt>${gs.getMessage("Subject")}</dt><dd>$[emailsgr.getValue('subject')]</dd>


  </dl>



  </div>


  <div class="email-formatter-detail" id="$[emailsgr.getValue('sys_id')].mail_cell"><iframe id="$[emailsgr.getValue('sys_id')].body" width="100%" frameborder="0" src="email_display.do?email_id=$[emailsgr.getValue('sys_id')]" style="height: 890px;"></iframe>


  </div>


  <div class="email-formatter-reply"><button type="button" onclick="emailClientOpenPop('incident', true, 'reply', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Reply")}</button><button type="button" onclick="emailClientOpenPop('incident', true, 'replyall', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Reply all")}</button><button type="button" onclick="emailClientOpenPop('incident', true, 'forward', '$[emailsgr.getValue('sys_id')]');">${gs.getMessage("Forward")}</button>


  </div>


  </div>




  </td>


  </tr>


  </tbody>


  <!-- </table> -->



</j2:while>




</j:jelly>




4.You will also need to create a Script Include to get the Sender info from the Emails Header:


Name: emailUtilFormat


API Name: global.emailUtilFormat



Script:


var emailUtilFormat = Class.create();


emailUtilFormat.prototype = {


  headerReceived: function(header) {


  //gs.log("We are in script Inclue email Util");



  var newHeader1 = "";


  newHeader1 = header.substring(header.lastIndexOf('Return-Path:')+12,header.lastIndexOf('Delivered-To'));



  newHeader1= newHeader1.replace('<','');


  newHeader1= newHeader1.replace('>','');



  return newHeader1;


  },



  headerSent: function(header) {


  //gs.log("We are in script Inclue email Util");



  var newHeader1 = "";


  newHeader1 = header.substring(header.lastIndexOf('From:')+5,header.lastIndexOf('Reply-To'));




  return newHeader1;


  },



  type: 'emailUtilFormat'


};




Hope this helps !



Result:



find_real_file.png