Setting RITM fields using Cart API
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-18-2016 06:41 AM
Hi all,
I was wondering if there is a way to populate fields (not variables) on RITM forms? Everything I've read talks about populating variables but I'd like to have the fields set as well based on what users send to SN via emails. Any help or suggestions is greatly appreciated. Thanks again,
- Labels:
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-20-2016 07:38 AM
Hi James,
Your current approach for matching the fields/values found in the email with the fields in the target record should still work, and combining that with the advice from Brad and Abhinay you can get this working in your inbound action.
Here's some sample script that combines some of the scripts you've already pasted but I think should achieve what you want.
var cat_id='';
if(email.body.item != undefined && email.body.item!='') {
var cat_item=email.body.item.trim();
var gr= new GlideRecord('sc_cat_item');
gr.get('name',cat_item);
cat_id=gr.getValue('sys_id');
var cart = new Cart();
var item=cart.addItem(cat_id);
var user = new GlideRecord('sys_user');
if(user.get('email',email.from.toString())){
// set requested for
//Set Variables in your Cart Item
cart.setVariable(item, 'requested_for', user.getValue('sys_id'));
}
var cartmsg = "received from: " + email.origemail + "\n\n" + email.body_text;
cart.setVariable(item,'comments',cartmsg);
var rc = cart.placeOrder();
var ritm= new GlideRecord('sc_req_item');
ritm.addQuery('request',rc.sys_id);
ritm.query();
var labelData = getLabels(ritm);
while (ritm.next()) {
for (var fieldName in email.body) {
if (labelData[fieldName]) {
var label = labelData[fieldName];
var fieldValue = email.body[fieldName];
if (label.isReference)
ritm[label.column].setDisplayValue(fieldValue);
else
ritm[label.column] = fieldValue;
}
}
ritm.update();
}
}
function getLabels(gr) {
var labelData = {};
if (!gr)
return labelData;
var elements = gr.getElements();
for (var i = 0; i < elements.size(); i++) {
var element = elements.get(i);
var columnName = element.getName();
var columnLabel = element.getLabel();
var ed = elements.get(i).getED();
var isReference = (ed == null ? false : ed.isReference());
var name = cleanLabel(columnLabel);
labelData[name] = {column: columnName, isReference: isReference};
}
return labelData;
}
function cleanLabel(label) {
var name = label.toLowerCase().replace(/[^a-zA-Z0-9_]/g, '_');
// Compact any multiple sequential underscores
while (name.indexOf("__") != -1)
name = name.replace(/__/g, "_");
// Replace any trailing underscores
while (name != '' && name.charAt(name.length - 1) == '_')
name = name.substring(0, name.length - 1);
return name;
}
It'll need amending for the extra blackilist/whitelist logic that you have and some testing for whether the user can write to the fields being updated (e.g. ritm[fieldName].canWrite() ).
I've tested this on my ServiceNow instance and it worked ok.
Hope that helps.
Regards
Nigel
P.S. Just noticed that what I've written could be done more efficiently by working out the fields to be updated on the Requested Item once rather than for each requested item that has been created for the Request so if you are likely to be creating multiple items per request you could consider re-working this a bit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-20-2016 08:17 AM
Hi Nigel,
Thank you for taking the time to look into this, I truly appreciate it. I tried your code and it did not fill the RITMs fields as said in the email. To give you some context, we send an email to SN in this format (below) and the the associated fields get set to the info in the email. The code mentioned above set a dynamic inbound action and I've been trying to merge the cart api request code and set the fields the way we do now. Again, thank you for all your help!
Accountable: Nigel Bell
Active: False
Activity due: 01:01:2017
Actual effort: 01:02
Additional assignee list: Nigel Bell
Additional comments: Testing full RITM input
Approval: requested
Approval history: Some Approval History
Approval set: 01:03:2017
Assigned to: Nigel Bell
Assigned user: Nigel Bell
Assignment Department: Servicenow
Assignment Division: Applications Development
Assignment group: Auxiliary Services
Assignment Organization: Administration
Assignment Team: Admin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-20-2016 11:20 AM
Hi,
Disappointing it didn't work on your instance. From the code you posted (which does a nice job of deriving the matching fields in the target record from the text in the email) I thought I'd provided something similar which would use the fields from the email to match with fields on the Requested Item. An example of the email I was processing on my instance:
Item:Request_by_email
Quantity:999
Configuration item:DP00349
Another user:Nigel Bell
Short description:my description for this item
Then taking the "Another user:..." line as an example, the inbound action script would then look for a field on Requested Item that has a label that matches this name (but with the appropriate replacing spaces with underscore and changing to lowercase). In my case I had added a custom reference field to Req Item with the label "Another user" and the underlying column name of "u_a_user".
From your last update it sounds like you're happy to work on getting your own scripts combined but if you want to try and add some debugging to what I sent you just let me know.
Regards,
Nigel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-09-2016 08:23 AM
I am confused from your code;
- var labelData = getLabels(ritm);
- while (ritm.next()) {
- for (var fieldName in email.body) {
- if (labelData[fieldName]) {
- var label = labelData[fieldName];
- var fieldValue = email.body[fieldName];
- if (label.isReference)
- ritm[label.column].setDisplayValue(fieldValue);
- else
- ritm[label.column] = fieldValue;
- }
- }
- ritm.update();
- }
- }
what is the difference of fieldName and fieldValue?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-11-2016 09:40 AM
Hi James,
Taking a snippet from the kind of email you send into your SNC instance, if your email body contained:
Accountable: Nigel Bell
Active: False
Activity due: 01:01:2017
then the line "for (var fieldName in email.body)" would loop over the field names from the email body and set the fieldName to the appropriate value (i.e. "accountable", "active", "activity_due").
The line "var fieldValue = email.body[fieldName];" will then set fieldValue to the value after the ":" of each fieldName - so when fieldName is "accountable", fieldValue will be set to "Nigel Bell".
Does that make sense?
Regards,
Nigel