
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 12:54 PM
*** SKIP TO THE BOTTOM OF THIS THREAD IF YOU WANT THE CODE***
USE CASE: UI Action that is used to subjectively escalate an incident to another ServiceNow instance - Incident created on other instance will have relevant metadata and attachments.
Hi Community
I have completed the initial steps I need to integrate two instances together. Effectively, I have a UI Action for the incident form, that on click, will duplicate the incident record to the opposing instance as part of an escalation.
Stating that, attachments are not being transferred at this moment and time as the record is created on the opposing instance. I am looking for a simple way to transfer any attachments that may exist as part of the initial REST call, and came across the setRequestBodyFromAttachment method. Attempted to apply it based on the following article:
Here is the code:
(function () {
try {
var body = {
short_description: current.getValue('short_description'),
description: current.getValue('description'),
// caller_id: current.getValue('caller_id'),
incident_number: current.getValue('number'),
u_lyrical_incident: current.getValue('number'),
//correlation_id: current.getValue('number'),
assignment_group: "Operations",
correlation_id: current.getValue('sys_id'),
cmdb_ci: current.getDisplayValue('u_target_system'),
// cmdb_ci: current[u_target_system].getLabel(),
comments: current.comments.getJournalEntry(-1),
};
var tosend = JSON.stringify(body);
var request = new sn_ws.RESTMessageV2('Ottos test instance', 'Otto_Post');
request.setRequestHeader("Accept", "application/json");
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestBody(tosend);
request.setRequestBodyFromAttachment(current.getValue('sys_id'));
request.setWorkflow (false); //attempt to stop loops
var response = request.execute();
var responseBody = response.getBody();
var json = responseBody;
var obj = JSON.parse(json); //define JSON parsing for the response JSON file to decode
var foundSysID = obj.result.sys_id; //decoded newly created incident sys_id on opposing instance
var foundNumber = obj.result.number;
current.correlation_id = foundSysID; //copied the sys_id incident to correlation id
current.u_customer_ticket = foundNumber;
current.u_escalated = 1;
current.update(); //update the current incident
gs.addInfoMessage("This incident has been escalated to opposing instance : " + foundNumber); //log ticket number
gs.log (tosend);
gs.log (foundnumber);
var httpStatus = response.getStatusCode();
} catch (ex) {
var message = ex.message;
}
})();
This fails with the following error:
REST Msg Outbound - RESTMessageClient : Error executing REST request: attachment does not exist with sys_id: eea0c283db851c10965e303f9d961919: com.glide.rest.util.RESTRuntimeException: attachment does not exist with sys_id: eea0c283db851c10965e303f9d961919:
Obviously I am not using this correctly or mispercieve how its going to be used.
1) What is the best method to send an attachment?
2) If this is the best method, I am clearly not understanding, and am very receptive to being corrected
Thank you for your help
Solved! Go to Solution.
- Labels:
-
Integrations
-
Multiple Versions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 01:59 PM
Back at Knowledge 17 in CreatorCon we had "Hack Labs" which were short labs to learn various concepts and the REST Attachment API was one of those. I wrote this lab that covers your use case of integrating two instances and sending the attachments along with it. See the later labs in the attachment document.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 01:59 PM
Back at Knowledge 17 in CreatorCon we had "Hack Labs" which were short labs to learn various concepts and the REST Attachment API was one of those. I wrote this lab that covers your use case of integrating two instances and sending the attachments along with it. See the later labs in the attachment document.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 02:17 PM
Thank you! I will take a look and get back to you

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 03:27 PM
You sir are clearly a rock star. Thank you VERY much - you have given me a lot to work with.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2020 08:57 PM
For those looking for the complete code I used in the UI Action - see the following as an example. The case is simple - per incident escalations
Note that you will have to change various values within the code body itself and define your own REST messages for use. There are two different REST Message targets for POST, one for updating the incident record, and one for creating the associated attachment. Attachments and incidents are in separate tables.
As well, extra fields have been added to incident records on my side of the interactions (my instance) - example the "escalated" field, which is a boolean field. When the value of this field is true, the UI Action has a condition that makes the UI Action button that triggers this code to disappear from the form. Why? If the incident has been escalated already to another instance, the button is not only no longer needed, its presence could lead to accidental clicks that create additional incidents.
Ridiculous levels of gratitude to
(function executeRule(current, previous /*null when async*/) {
var answer = "";
var attachmentMsg = "";
//Create a JSON string with the current incident attributes which will fill in incident metadata
var incidentJSON = {};
incidentJSON.caller_id = current.caller_id.toString();
incidentJSON.category = current.category.toString();
incidentJSON.impact = current.impact.toString();
incidentJSON.urgency = current.urgency.toString();
incidentJSON.priority = current.priority.toString();
incidentJSON.short_description = current.short_description.toString();
incidentJSON.u_opposing_incident = current.getValue('number'); //send current incident number to user defined field
incidentJSON.comments = current.comments.getJournalEntry(-1).toString(); // send all additional comments
incidentJSON.correlation_id = current.sys_id.toString(); // sys_id to opposing instance as correlation_id
// Encode JSON string
var requestBody = new global.JSON().encode(incidentJSON);
// Create incident in target instance via REST
var restMessage = new sn_ws.RESTMessageV2('Ottos test instance', 'Otto_Post');
restMessage.setRequestHeader("Content-Type", "application/json");
restMessage.setRequestBody(requestBody);
var response = restMessage.execute();
var responseBody = response.getBody();
//get variables for populating correlation ID, customer incident number
//send visible message to operator and update incident record with details received
var httpStatus = response.getStatusCode();
var parser = new JSONParser();
var parsed = parser.parse(responseBody);
var foundSysID = parsed.result.sys_id; //decoded newly created incident sys_id on opposing instance
var foundNumber = parsed.result.number; // decoded newly created incident number on opposing instance
current.correlation_id = foundSysID; //copy the sys_id incident to correlation id
current.u_customer_ticket = foundNumber; //copy oppocing incident number to customer ticket number field
current.u_escalated = 1; // set the escaleted box as true to force UI action for escalation to disappear
current.update(); //update the current incident
if (httpStatus.toString() == "201") {
answer = gs.addInfoMessage("This incident has been escalated to opposing instance : " + foundNumber); //log ticket number and send visible notification to operator
// Get target record's SysID
var targetRec = parsed.result;
var attachmentCount = sendAttachments(current.getTableName(), current.sys_id, targetRec.sys_id);
if (attachmentCount != "none") {
attachmentMsg = " Attachments successfully sent: " + attachmentCount[0].toString() + ". Attachments failed to be sent: " + attachmentCount[1].toString();
} else {
attachmentMsg = " Record had no attachments to send.";
}
} else {
answer = "Incident could not be sent.";
}
answer = answer + attachmentMsg;
// Set message at top of screen with results related to attachments
gs.addInfoMessage(answer);
function sendAttachments(sourceTable, sourceID, targetID) {
var answer = [0, 0]; //successful attachments, failed attachments
// Query for any attachments on the current record.
var attachmentRec = new GlideRecord("sys_attachment");
attachmentRec.addQuery("table_sys_id", sourceID);
attachmentRec.addQuery("table_name", sourceTable);
attachmentRec.query();
if (attachmentRec.hasNext()) {
while (attachmentRec.next()) {
var attachmentMessage = new sn_ws.RESTMessageV2('Ottos test instance', 'Otto_Attach_Post');
attachmentMessage.setQueryParameter("table_name", attachmentRec.table_name);
attachmentMessage.setQueryParameter("table_sys_id", targetID);
attachmentMessage.setQueryParameter("file_name", attachmentRec.file_name);
attachmentMessage.setRequestHeader("Content-Type", attachmentRec.content_type);
attachmentMessage.setRequestHeader("Accept", "application/json");
attachmentMessage.setRequestBodyFromAttachment(attachmentRec.sys_id);
var response = attachmentMessage.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
if (httpStatus.toString() == "201") {
answer[0] += 1;
} else {
answer[1] += 1;
}
}
} else {
answer = "none";
}
return answer;
}
})(current, previous);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-05-2020 06:22 AM
Awesome glad you got this working. Happy to help!