I appreciate this one is a bit niche but someone out there might find it useful so I thought I’d share. I had a need to override the “To” field on the email client with a different email address. I wanted a method where I could specify an email address as a recipient which would override what was there. If there wasn’t an overriding email address provided, use the default (which would be caller_id in this instance).
With “Email Client Templates” in ServiceNow you can specify the recipient that should be used in the “To” field (as well as “CC” and “BCC”). You can also configure other fields such as subject. For example, here is a simple configuration that is configured for the “incident” table and will default the email in the “To” field to be the user specified in the “caller_id” field.
This then works when clicking into the email client using the following:
It will bring up the mail client in the following way:
It turns out you can use Javascript in the email client template instead of a field name. I thought we might be able to use the URL to provide the recipient address in the form of a parameter which could override the “To” field; if it found a custom address in there, override the field. If not, respond with caller_id.
Firstly, I built the following script include:
Type | Script Include |
Name | EmailClientUtils |
Description | Custom functions for the email client. |
Client Callable | False |
var EmailClientUtils = Class.create(); EmailClientUtils.prototype = { initialize: function() { debug = true; }, checkForRecipient: function(url) { url = String(url); this.logDebug("URL: " + url); var match = url.match(/[?&]sysparm_recipients=([^&]*)/); this.logDebug("MATCH:" + match); var return_address = match ? decodeURIComponent(match[1]) : "caller_id"; this.logDebug("RETURN ADDRESS: " + return_address); return return_address; }, logDebug: function() { if (this.debug) gs.log(str, "EmailClientUtils"); }, type: 'EmailClientUtils' };
I then updated the email client template “To” field as follows. This makes the email client call the checkForRecipient function in the script include.
javascript:new global.EmailClientUtils().checkForRecipient(gs.action.getGlideURI())
Effectively the checkForRecipient function reads the presented URL (provided with gs.action.getClientURI()) and checks to see if there is a parameter called sysparm_recipients. If there is, extract and return the value. If not, return caller_id.
To utilise the function, I firstly created a new UI script. This adapts some functionality I found through my investigation that normally opens the email client (emailClientOpenPop) to accept a custom recipient, then adds a new parameter named sysparm_recipients with that recipient to the URL. It then opens the email client with that URL.
Type | UI Script |
Name | CustomEmailClient |
UI Type | Desktop |
Global | True |
var CustomEmailClient = Class.create(); CustomEmailClient.prototype = { initialize: function() { }, emailClientOpenPopCustom: function(customRecipient) { var table = g_form.getTableName(); var id = document.getElementsByName("sys_uniqueValue")[0]; if (!id) return; var url = new GlideURL("email_client.do"); url.addParam("sysparm_table", table); url.addParam("sysparm_sys_id", id.value); url.addParam("sysparm_target", table); var urlString = url.getURL() + g_form.serializeChangedAll(); urlString += "&sysparm_recipients=" + customRecipient; urlString = urlString.substring(0, urlMaxLength); popupOpenEmailClient(urlString); }, };
Finally, to use all of this I thought it might be useful to have a UI macro that we could put next to a field. Then we can click it to open the email client with that address.
Type | UI Macro |
Name | email_user |
Description | Email user in reference field using email client. |
<?xml version="1.0" encoding="utf-8"?> <j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide"> <g:reference_decoration id="show_email_${gs.generateGUID(this)}:${ref}" field="${ref}" onclick="invokeEmail('${ref}');" title="${gs.getMessage('Email User')}" image="images/icons/email.gifx" icon="icon-mail" /> <script> function invokeEmail(reference) { var s = reference.split('.'); var referenceField = s[1]; var user = g_form.getReference(referenceField, emailUser); } function emailUser(user) { var abc = new CustomEmailClient(); abc.emailClientOpenPopCustom(user.email); } </script> </j:jelly>
You can then add it to a reference field by using the following in the dictionary:
ref_contributions=email_user
It will show a little email icon next to the user, like this:
And when you click the email icon, it will bring up the mail client with that user in the “To” field:
Hope this helps. I’d imagine you can use the same method for other fields on the email client template.
Perfect solution. I also want to make cc field dynamic in a way if its clicked on the mailto box next to assigned_to only then populate the cc otherwise keep it empty. How can I achieve that?