From 26fff845e3564adfc98fb22f44f1e91858b29e1c Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sun, 26 Oct 2025 13:04:15 +0000 Subject: [PATCH 1/4] Create GenericEmailUtility.js --- .../GenericEmailUtility.js | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Client-Side Components/UI Actions/Email Watermark Utility/GenericEmailUtility.js diff --git a/Client-Side Components/UI Actions/Email Watermark Utility/GenericEmailUtility.js b/Client-Side Components/UI Actions/Email Watermark Utility/GenericEmailUtility.js new file mode 100644 index 0000000000..1626209823 --- /dev/null +++ b/Client-Side Components/UI Actions/Email Watermark Utility/GenericEmailUtility.js @@ -0,0 +1,80 @@ +var GenericEmailUtility = Class.create(); +GenericEmailUtility.prototype = { + initialize: function() {}, + + // Generate an Outlook (mailto) link with watermark tracking + get_Outlook_link: function() { + try { + const email_payload = JSON.stringify({ + "REQUESTOR_ID": "", + "TITLE": "", + "BODY": "", + "REQUEST_ID": "", + "TABLE_ID": "" + }); + + var mailtoLink = false; + const raw_data = this.getParameter("sysparm_email_body") || email_payload; + + if (global.JSUtil.notNil(raw_data)) { + var email_data = JSON.parse(raw_data); + + const to = this.getEmail(email_data.REQUESTOR_ID); + const cc = gs.getProperty("instanceEmailAddress"); // instance default CC + const subject = email_data.TITLE || ''; + const body = email_data.BODY || ''; + + const watermark = this.getWatermark(email_data.REQUEST_ID, email_data.TABLE_ID); + + // Construct mailto link + mailtoLink = 'mailto:' + to + '?cc=' + cc; + + if (subject) + mailtoLink += '&subject=' + encodeURIComponent(subject); + + if (body) + mailtoLink += '&body=' + encodeURIComponent(body); + + if (watermark) + mailtoLink += encodeURIComponent("\n\nRef: " + watermark); + } + + return mailtoLink; + + } catch (ex) { + gs.error("Error in get_Outlook_link(): " + ex.message); + return false; + } + }, + + // Fetch watermark ID (creates one if missing) + getWatermark: function(record_id, table_name) { + var wm = new GlideRecord('sys_watermark'); + wm.addQuery('source_id', record_id); + wm.orderByDesc('sys_created_on'); + wm.query(); + + if (wm.next()) { + return wm.getValue('number'); + } + + wm.initialize(); + wm.source_id = record_id; + wm.source_table = table_name; + wm.insert(); + + return wm.getValue('number'); + }, + + // Retrieve user’s email address + getEmail: function(user_id) { + if (global.JSUtil.notNil(user_id)) { + var user = new GlideRecordSecure('sys_user'); + if (user.get(user_id)) + return user.email.toString(); + } + return ''; + }, + + type: 'GenericEmailUtility' +}; From 45656e393aeb857d7f9787394a96f10cbd09489d Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sun, 26 Oct 2025 13:05:35 +0000 Subject: [PATCH 2/4] Create Send Email UI Action --- .../Send Email UI Action | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action diff --git a/Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action b/Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action new file mode 100644 index 0000000000..000424a283 --- /dev/null +++ b/Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action @@ -0,0 +1,25 @@ +function onClick(g_form) { + var separator = "\n--------------------------------\n"; + var email_body = "Record URL:\n" + g_form.getDisplayValue('number') + separator; + email_body += "Short Description:\n" + g_form.getValue('short_description') + separator; + email_body += "Description:\n" + g_form.getValue('description') + separator; + + var email_data = {}; + email_data.REQUESTOR_ID = g_form.getValue('caller_id') || g_form.getValue('opened_by') || g_form.getValue('requested_for'); + email_data.TITLE = g_form.getValue('short_description') || 'ServiceNow Communication'; + email_data.BODY = email_body; + email_data.REQUEST_ID = g_form.getUniqueValue(); + email_data.TABLE_ID = g_form.getTableName(); + + var ga = new GlideAjax('GenericEmailUtility'); + ga.addParam('sysparm_name', 'get_Outlook_link'); + ga.addParam('sysparm_email_body', JSON.stringify(email_data)); + ga.getXMLAnswer(function(response) { + var mailto_link = response; + if (mailto_link && mailto_link != 'false') { + window.open(mailto_link); + } else { + g_form.addErrorMessage('Unable to generate Outlook link.'); + } + }); +} From 14413999c0c59975b2b07f9eb2bc1326b743f563 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sun, 26 Oct 2025 13:06:13 +0000 Subject: [PATCH 3/4] Rename Send Email UI Action to Send Email UI Action.js --- .../{Send Email UI Action => Send Email UI Action.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Client-Side Components/UI Actions/Email Watermark Utility/{Send Email UI Action => Send Email UI Action.js} (100%) diff --git a/Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action b/Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action.js similarity index 100% rename from Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action rename to Client-Side Components/UI Actions/Email Watermark Utility/Send Email UI Action.js From 4f95baa76f67617ef0e2b1a6d8df1f7b32f782dd Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sun, 26 Oct 2025 13:15:48 +0000 Subject: [PATCH 4/4] Create README.md --- .../Email Watermark Utility/README.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Client-Side Components/UI Actions/Email Watermark Utility/README.md diff --git a/Client-Side Components/UI Actions/Email Watermark Utility/README.md b/Client-Side Components/UI Actions/Email Watermark Utility/README.md new file mode 100644 index 0000000000..29a7da7425 --- /dev/null +++ b/Client-Side Components/UI Actions/Email Watermark Utility/README.md @@ -0,0 +1,56 @@ +# Outlook Email Watermark Utility for ServiceNow + +# Overview +This reusable utility allows users to send emails **outside ServiceNow** (e.g., using Outlook or any default mail client) while still maintaining the conversation within ServiceNow. +By embedding a unique watermark reference, any replies to the email will automatically append to the original record's activity feed. + +This helps teams collaborate externally without losing internal record visibility — ideal for customers or vendors who communicate via Outlook. + +--- + +# Objective +- Enable ServiceNow users to send Outlook emails directly from a record. +- Maintain conversation history in ServiceNow using watermark tracking. +- Make the solution **generic**, reusable across tables (Incident, Change, Request, etc.). +- Prevent dependency on outbound mail scripts or custom integrations. + +# Components + +## 1. Script Include: GenericEmailUtility +Handles the logic for: +- Constructing the mailto: link. +- Fetching recipient and instance email addresses. +- Generating or retrieving the watermark ID. +- Returning a formatted Outlook link to the client script. + +## Key Methods +1. get_Outlook_link() - Builds the full Outlook mail link with subject, body, and watermark. +2. getWatermark(record_id, table_name) - Ensures a watermark exists for the record. +3. getEmail(user_id) - Fetches the email address for the target user. + +## 2. UI Action (Client Script) +Executes on the record form when the button/link is clicked. +It gathers record data, constructs a payload, calls the Script Include using GlideAjax, and opens Outlook. + +## Key Steps +1. Collect field data like requestor, short description, and description. +2. Pass record details to the Script Include (GenericEmailUtility). +3. Receive a ready-to-use Outlook link. +4. Open the mail client with prefilled details and watermark reference. + +## How It Works +1. User clicks "Send Outlook Email" UI Action on a record. +2. Script gathers record data and passes it to GenericEmailUtility. +3. The utility builds a 'mailto:' link including the watermark. +4. Outlook (or default mail client) opens with pre-filled To, CC, Subject, and Body fields. +5. When the recipient replies, ServiceNow uses the watermark to append comments to the correct record. + +## Example Usage +**User clicks “Send Outlook Email”** on a Request record: +Outlook opens prefilled like this: + +image + + +image +