- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 10:45 AM
Has anyone written an Email Script to display variables related to a Task record that was create using a Record Producer, rather than a Catalog Item? Basically, I need to create a notification for a Service Management application and display the variables (questions and answers) that were submitted by a user in the Record Producer.
Regards,
Robin
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 11:37 AM
From my experience, variables for record producers are stored in the question_answer table. It is unclear if ServiceNow has changed this since I wrote my solution for Eureka, but if they still store the variables there, then this solution should still apply.
1. Create a Script Include to parse the variables:
Name: reqUtils
Description: Custom Script Include with record producer functions
Script:
var reqUtils = Class.create();
reqUtils.prototype = {
initialize: function() {
},
parseVars: function(rec) {
var qaArr = this._getBlank(rec.sys_id);
for (var i in rec.variables) {
var dStr = rec.variables[i].getDisplayValue();
var vStr = rec.variables[i];
if (!vStr.nil()) {
var qObj = this._getQuestion(rec.sys_id, vStr);
qObj.answer = dStr;
qaArr.push(qObj);
}
}
qaArr.sort(function(a, b) {
return a.order-b.order;
});
return qaArr;
},
_getBlank: function(qID) {
var qa = new GlideRecord('question_answer');
qa.addQuery('table_sys_id', qID);
qa.addQuery('value', '');
qa.query();
var rArray = [];
while (qa.next()) {
if (qa.question.visible_summary) {
var result = {"order": qa.question.order,
"question": qa.question.getDisplayValue(),
"answer": ''
};
rArray.push(result.toString());
}
}
return rArray;
},
_getQuestion: function(qID, v) {
var qa = new GlideRecord('question_answer');
qa.addQuery('table_sys_id', qID);
qa.addQuery('value', v);
qa.query();
var result = '';
if (qa.next()) {
result = {"order": qa.question.order,
"question": qa.question.getDisplayValue()
};
}
return result;
},
type: 'reqUtils'
};
What I do in the parsVars function is:
a. Get a listing of blank questions which contains the order, question, and blank for an answer.
b. Get a listing of answered questions which contains the order, question, and answer.
c. I combine both of these listings together into an array and sort by the order.
d. I return the sorted array of questions and answers for processing on the notification side.
2. Create a Notification Email Script:
Name: rec_prod_variables<br/>
Script:
template.print("<b><u>Options:</u></b>\n");
var sInc = new reqUtils();
var vArr = sInc.parseVars(current);
for (y = 0; y < vArr.length; y++) {
var q = vArr[y].question;
var a = vArr[y].answer;
template.space(4);
template.print(" " + "<b>" + q + "</b> = " + a + "\n");
}
What I do in the rec_prod_variables Notification Email Script is:
a. Print out a line for Options (you can change this to your needs).
b. Call the script include.
c. Assign the vArr variable to the results of the parseVars function.
d. Iterate through the returned array
e. Assign the question to the q variable
f. Assign the answer to the a variable
g. Print the line (you can change this to your needs)
All you need to do is use the following syntax in your notification:
${mail_script:rec_prod_variables}
Let me know if you have any questions.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 10:50 AM
Hi Robin,
This should help you get started in the right direction.
Get variable label and values on record in scoped app.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 11:26 AM
This is what I did. This is a mail script in my notification that gets fired from a event in the workflow.
<mail_script>
template.print("Summary of Requested item:\n");
var item = new GlideRecord("sc_req_item");
item.addQuery("sys_id", current.sys_id);
item.query();
while(item.next()) {
template.print(item.number + ": " + item.cat_item.getDisplayValue() + "\n");
template.print(" Item Options:\n");
var keys = new Array();
var set = new GlideappVariablePoolQuestionSet();
set.setRequestID(item.sys_id);
set.load();
var vs = set.getFlatQuestions();
for (var i=0; i < vs.size(); i++) {
if(vs.get(i).getLabel() != '') {
template.space(4);
template.print(' ' + vs.get(i).getLabel() + " = <span style='color:red'>" + vs.get(i).getDisplayValue() + "</span>\n");
}
}
}
</mail_script>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 11:37 AM
From my experience, variables for record producers are stored in the question_answer table. It is unclear if ServiceNow has changed this since I wrote my solution for Eureka, but if they still store the variables there, then this solution should still apply.
1. Create a Script Include to parse the variables:
Name: reqUtils
Description: Custom Script Include with record producer functions
Script:
var reqUtils = Class.create();
reqUtils.prototype = {
initialize: function() {
},
parseVars: function(rec) {
var qaArr = this._getBlank(rec.sys_id);
for (var i in rec.variables) {
var dStr = rec.variables[i].getDisplayValue();
var vStr = rec.variables[i];
if (!vStr.nil()) {
var qObj = this._getQuestion(rec.sys_id, vStr);
qObj.answer = dStr;
qaArr.push(qObj);
}
}
qaArr.sort(function(a, b) {
return a.order-b.order;
});
return qaArr;
},
_getBlank: function(qID) {
var qa = new GlideRecord('question_answer');
qa.addQuery('table_sys_id', qID);
qa.addQuery('value', '');
qa.query();
var rArray = [];
while (qa.next()) {
if (qa.question.visible_summary) {
var result = {"order": qa.question.order,
"question": qa.question.getDisplayValue(),
"answer": ''
};
rArray.push(result.toString());
}
}
return rArray;
},
_getQuestion: function(qID, v) {
var qa = new GlideRecord('question_answer');
qa.addQuery('table_sys_id', qID);
qa.addQuery('value', v);
qa.query();
var result = '';
if (qa.next()) {
result = {"order": qa.question.order,
"question": qa.question.getDisplayValue()
};
}
return result;
},
type: 'reqUtils'
};
What I do in the parsVars function is:
a. Get a listing of blank questions which contains the order, question, and blank for an answer.
b. Get a listing of answered questions which contains the order, question, and answer.
c. I combine both of these listings together into an array and sort by the order.
d. I return the sorted array of questions and answers for processing on the notification side.
2. Create a Notification Email Script:
Name: rec_prod_variables<br/>
Script:
template.print("<b><u>Options:</u></b>\n");
var sInc = new reqUtils();
var vArr = sInc.parseVars(current);
for (y = 0; y < vArr.length; y++) {
var q = vArr[y].question;
var a = vArr[y].answer;
template.space(4);
template.print(" " + "<b>" + q + "</b> = " + a + "\n");
}
What I do in the rec_prod_variables Notification Email Script is:
a. Print out a line for Options (you can change this to your needs).
b. Call the script include.
c. Assign the vArr variable to the results of the parseVars function.
d. Iterate through the returned array
e. Assign the question to the q variable
f. Assign the answer to the a variable
g. Print the line (you can change this to your needs)
All you need to do is use the following syntax in your notification:
${mail_script:rec_prod_variables}
Let me know if you have any questions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2016 12:13 PM
Thanks Christopher, that looks like it should do everything I need.
I do however have one question. My email notification is for an approval, so 'current' is the sysapproval_approver record. How do I pass the record for the item that's being approved to the parseVars function?