
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 10-23-2020 06:30 AM
Hello!
OUTLINE
1. Introduction
2. What's The Big Deal With Outlook?
3. How Do We Fix This?
4. STEP 1: New Script Include
5. STEP 2: Update Our Email Script(s)
6. What's The End Result?
1. INTRODUCTION
This article explains how to utilize buttons with rounded corners that are compatible with both Outlook and HTML clients such as Gmail.
These are highly likely to be compatible with most email clients, but I don't want to make that claim without testing. And I don't want to test that, haha!
2. WHAT'S THE BIG DEAL WITH OUTLOOK?
Why single Outlook out from HTML clients, you ask? Good question. Have you seen what Outlook does to ServiceNow's email "buttons"?
Once you get back from the 1990s, which that button brought you back to, I'll explain.
The Outlook Desktop Client uses VML to draw shapes. Not HTML. Interesting, isn't it? Wikipedia calls VML a "depreciated format" used for "legacy reasons only". Haha, I'm sure they have good reasons, but man that complicates things. (I'm guessing they like VML's mysterious, complicated, and undocumented current-use aspect, as it causes a border-to-entry which probably helps keep their product proprietary, making it difficult to copy/imitate their product.) This means that it ends up taking our HTML shapes that we feed to it, does its best to translate the HTML into VML - while dropping a lot of "words" that it cannot comprehend - and we end up with these ugly rectangles with 90 degree edges, and malformed padding and borders.
3. HOW DO WE FIX THIS?
Three words. Outlook Conditional Comments. I'm no expert, I just did a bunch of research on this so that I could stop Outlook's tyranny, as I like to call it. I'm sharing with you what I found in my research and development.
CREDIT WHERE IT'S DUE: Thank you VanAlbert! This gentleman provided the answer to the Rounded corners in outlook without images Stack Exchange question, which I heavily used to produce this solution. I just translated it to ServiceNow speak in a re-usable format, that's all. 😉
If you follow these steps, you too can generate professional, modern looking buttons from ServiceNow that do not break in the Outlook email client, while still remaining compatible with HTML email clients.
4. STEP 1: New Script Include
First, let's create this script include. This has code that detects if the email client is "mso" (Outlook) and uses VML if it is, HTML if it's not. This creates compatibility for Outlook's legacy rendering scheme, while retaining compatibility with our normal HTML clients.
We're housing this in a script include for convenience, to allow easy re-use elsewhere.
Just call one of the two script includes below and feed it the variables (message, size, colors, link, border-radius) that fit your own unique situation, and you've got your own customized button, anywhere you want to include it, easy!
Object: | Script Include |
Name: | OutlookRoundedButtonDynamic |
Application: | Global |
Accessible from: | This application scope only |
Client callable: | FALSE |
Description: | Script include for creating rounded buttons usingy using VML for the Outlook client, while using HTML for all others. This version dynamically sizes the button to fit the text via the mso-fit-shape-to-text attribute. |
Script: |
function OutlookRoundedButtonDynamic(Message, FontSize, FontColor, bgColor, BorderRadius, Arcsize, Hyperlink){ |
Object: | Script Include |
Name: | OutlookRoundedButtonFixed |
Application: | Global |
Accessible from: | This application scope only |
Client callable: | FALSE |
Description: | Script include for creating rounded buttons usingy using VML for the Outlook client, while using HTML for all others. This version uses a fixed size via the width and height attributes. |
Script: | function OutlookRoundedButtonFixed(Message, FontSize, FontColor, Width, Height, bgColor, BorderRadius, Arcsize , Hyperlink){ //Arcsize: VML uses Arcsize, HTML uses border-radius. 20% arcsize equals roughly 7px border-radius. //Pros: Allows you to control the padding (indirectly via Width & Height), and to choose fixed-size buttons when desired. //Cons: The Width/Height attributes render inconsistently on a few machines. We had a few desktop computers that were shrinking the buttons in Outlook by roughly 20%, causing the text to clip. VDI Outlook, OWA, and HTML all rendered the size consistently, just these two desktop's Outlook were shrinking it. (One such machine's symptoms disappeared after some misc system updates.) //Assemble the HTML string in logical pieces, pulling in the Variables var ifmso = '<!--[if mso]>'; //Microsoft Outlook (Outlook Conditional Comments) var thenVML = '<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="' + Hyperlink + '" style="width:' + Width + 'px; height:' + Height + 'px; mso-position-horizontal:center; mso-wrap-style:none;" stroke="false" arcsize="' + Arcsize + '" fillcolor="#' + bgColor + '"><v:textbox style="v-text-anchor:middle"><center style="color:#' + FontColor + '; font-family:sans-serif; font-size:' + FontSize + 'px; font-weight:bold;">' + Message + '</center></v:textbox></v:roundrect><![endif]--><!--[if !mso]> <!-->'; var elseHTML = '<a href="' + Hyperlink + '" style="width:' + Width + 'px; height:' + Height + 'px; line-height: ' + Height + 'px; background-color:#' + bgColor + '; color:#' + FontColor + '; font-size:' + FontSize + 'px; font-weight:bold; font-family:sans-serif; text-decoration:none; text-align:center; border-radius:' + BorderRadius + 'px; -webkit-border-radius:'+ BorderRadius + 'px; -moz-border-radius:' + BorderRadius + 'px; display:inline-block;">' + Message + '</a>'; var endif = '<!-- <![endif]-->'; //Return the compiled HTML string return ifmso + thenVML + elseHTML + endif; }
|
5. STEP 2: Update our Email Script(s)
Second, let's get in the incident_take_me_to_the_incident email script, clear out the old shape code, and utilize our new button script include.
NOTE: I've also merged a survey notification into my version of this email script, which is shown below. Please consider this and remove it as needed to fit your personal use cases.
Object: | Email Script |
Name: | incident_take_me_to_the_incident |
Application: | Global |
Newlines to HTML | FALSE |
Script: |
(function runMailScript(current, template, email, email_action, event) { //Get Instance Base URL //Find Relevant Survey, Get sysID, & Print Message })(current, template, email, email_action, event); |
6. WHAT'S THE END RESULT?
Congratulations, you now have an email notification script with rounded buttons that render correctly in Outlook instead of being corrupted! All while also rendering correctly in HTML email clients, and contained in an easy to re-use package. Mission accomplished. High-five!
I hope that you find this article insight and helpful in your pursuits. Thanks!
Kind Regards,
Joseph
- 4,978 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This is great
Question for ya,
Our users are creating requests and incidents from Service Portal.
A series of notifications are sent to users by email with the incident and/or request link from the email template.
The problem we are having is that those URL reference are redirecting users to the ServiceNow platform back-end instead of the Service Portal incident to request link.
What is the best way to define in email template the link to the SP?
I tried using the following along with your updated take_me_to_the_incident but I was unsuccessful at getting it to load properly.
var url = '<a href="' + gs.getProperty('glide.servlet.uri') + 'sp?id=ticket&table=' + current.getTableName() + '&sys_id=' + current.sys_id + '">' + current.number + '</a>';
template.print(url);

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You're not trying to make that link you posted into an Outlook button, right? Looks like you're just trying to add a plain bit of hyperlinked text to your email.
If so... I don't know. Your URL schematic looks correct, except it might be worth replacing "current.sys_id" with "current.getUniqueValue()" to see if that fixes your invalid link.