- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 11-04-2022 06:24 AM
We recently added support for two additional languages to our instances. While there is a lot of good information about doing that set up for the service portal and traditional displays, I didn’t find much about doing that setup for notifications. After a bit of struggling, I came up with an approach that looks to work well with a minimum of effort.
The important thing to recognize is that most of the documentation for localization assumes that the language to be used is that of the currently logged on user. While that is fine for interactive displays, in most cases, it doesn’t work when sending out notifications. Typically, notifications are triggered by one user, e.g. a fulfiller, or the system to the caller on an incident, opened by on a request, etc. It therefore becomes necessary for the notifications to have a simple way to determine the language to use based on who is getting the notification rather than who is sending it.
We have an additional “wrinkle” that I had to deal with when setting this up. Notifications that go to end users are “branded” which means that the actual message is embedded between images and “useful links” where the text around those links must be in the same language as the body of the message.
Identifying the language
The challenge in identifying what language to use is twofold. First, different tables hold similar information in differently named fields, in incident we need caller_id while in sc_req_item we need opened_by. The second challenge is that not all users will have recorded a language preference.
The language preference is stored by user in sys_user_preference with a name of user.language. If a user has never stated a preference, which means that they are fine with the system default, there will be no user.language record. If the user has identified a language, it will be in the value field of the user.language record. That value will be the two-character internal code (en = English, fr = French, etc.) the values are all lower case.
The approach that I took for resolving this first challenge was to write a function that takes current, the object triggering the notification as an argument. That function then checks sys_user_preference for a user.language record. If found, it returns the value. If not found, it returns the value for the system property glide.sys.language (the system’s default language).
One decision you get to make is how you want to identify the way you check for the language. Since I had a relatively small group of tables to reference, I just used an if/then/else structure. You might also set up a property where you store name value pairs, or use a table to hold the data. You use getTableName() to know the relevant table.
checkLanguage: function(current) {
var theLanguage = gs.getProperty(“glide.sys.language”);
var userPref = new GlideRecord("sys_user_preference");
var theTable = current.getTableName();
if (theTable == "incident") {
userPref.addQuery("user", current.caller_id);
} else if (theTable == "sc_request" || current.getTableName() == "sc_req_item") {
userPref.addQuery("user", current.opened_by);
} else if (theTable == "sysapproval_approver") {
userPref.addQuery("user", current.approver);
} else if (theTable) == "asmt_assessment_instance") {
userPref.addQuery("user", current.user);
}
userPref.addQuery("name", 'user.language');
userPref.query();
if (userPref.next()) {
theLanguage = userPref.value;
}
return theLanguage;
},
Setting up the text
The approach that I took for setting up the individual messages was to have them all generated by mail scripts. First, I set up the various parts of the messages in sys_ui_message. Employing a technique from the TechNow episode on localization (#70 Translating Your Instance). All languages are included and the key is in ugly form, e.g. (incident_has_been_opened_1). This allows me to have one script for each notification regardless of how many languages are being supported.
To retrieve the correct text, the script starts out with a call to checkLanguage() to determine the language to be used. From there I created a function similar to gs.getMessage that goes out to sys_ui_message with two parameters, the key and the language.
fetchMessage: function(theKey, theLanguage) {
var part1;
var theMessages = new GlideRecord("sys_ui_message");
var theMessagesQuery = "key=" + theKey + "^language=" + theLanguage;
theMessages.addEncodedQuery(theMessagesQuery);
theMessages.query();
theMessages.next();
part1 = theMessages.message;
return part1;
},
The reason that the message may need to be set up in pieces is so that you can include information from the current object, e.g. number, short description, etc. The other thing you will have to do is potentially include HTML if the message includes one or more links.
Here is a simple example that takes two strings and concatenates them around the first parameter of the event that triggered the notification:
function runMailScript( /* GlideRecord */ current, /* TemplatePrinter */ template,
/* Optional EmailOutbound */
email, /* Optional GlideRecord */ email_action,
/* Optional GlideRecord */
event) {
var theScript = new MyFunctions();
var theLanguage = theScript.checkLanguage(current);
var part1 = theScript.fetchMessage("team_created_1", theLanguage);
var part2 = theScript.fetchMessage("team_created_2", theLanguage);
template.print(part1 + " " + event.parm1 + " " + part2);
})(current, template, email, email_action, event);
Templates, subject, etc.
As I mentioned above, many of our notifications are branded. That meant that I needed to create email layouts for each language. Layouts and templated cannot be dynamically assigned. Once I had those, it was a simple case of taking the first version of the notification, adding a language identifier to the name.
Within the template, I include an advanced condition where I call checkLanguage(). The condition then looks to see if the language matches that of the template which is hard coded. If it does, answer is set to true if not answer is set to false. That automates the decision quickly and easily.
Since I need to create a language specific version of each notification, I just set the subject hard coded. If you are not working with templates, you can do it via the mail script that is setting up the message email.setSubject().
A few final notes on accurate translations. Some of my colleagues who are located outside of the U.S. and are native speakers of a language other than English recommended using DeepL to do the translations. Based on what they told me and my experience with DeepL it does a very good job. The longer the text, the better.
Regardless of what translation tool you use, be sure to have your translations validated by native speakers. If you have internal colleagues who can do that you will save a lot of money compared to hiring professional translators.
Finally, make sure that the text you are using is relevant to all users. I had several catalog items that were initially U.S. centric and the suggested text made sense to Americans. When I asked my overseas colleagues, they looked at them and their response was “what’s that”.
Conclusion
I make no claims to being a great expert on localization. What I describe above is based on my experience. This article only covers notifications. There is a lot more to getting your site fully translated.
Localization is not a trivial task. Make sure that you have adequate time and resources before starting such a project. If you work with a support partner, take full advantage of that relationship. After a few hours with such a SME from our support partner I had a much better understanding of what needed to be translated and how to do the translations.
What turned out to be the biggest frustration for us was trying to get the language picker onto the service portal login screen. The bottom line is that you can’t. Since I have a relatively small number of languages, I just posted the one line how to log in in all three languages along with the relevant flag (not necessary but it looks nicer). I then put the language picker at the top of the service portal landing page.
I hope that this article helps you get through the process a little easier. Please feel free to reach out if you have any questions. I can’t guarantee that I’ll have all the answers.
- 1,433 Views

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Why not just use the multilingual email notification plugin ?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@johnfeist,
Ok, so there's a lot to unpack here,
You might find these links useful:
Our CSC page -> https://www.servicenow.com/success/playbook/globalization-localization.html
Our dedicated Forum here on Community -> https://www.servicenow.com/community/internationalization/ct-p/international-localization
Our "In Platform Language Support Guide" -> https://www.servicenow.com/community/international-localization-blog/in-platform-language-support-gu...
And prior to Tokyo, this would have been the most common approach to multi-lingual email notifications -> https://www.servicenow.com/community/international-localization/emails-in-other-languages-easy-to-co...
However, now with the Tokyo release being out, if you check the Email notification section of the Language support guide you'll find the answer you are looking for,
Many thanks,
kind regards