Inserting Attachments in ServiceNow from JIRA without MID-Server using REST

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-16-2017 04:43 AM
We were successfully able to insert attachments in ServiceNow from JIRA and hence below code can be used for other third party tools.
var targetInstanceURL = "https://jira.******.com/secure/attachment/"+attachment ID+"/";
var targetUserID = "..";
var targetUserPassword = "...";
var sa = new GlideSysAttachment();
var StringUtil = GlideStringUtil();
var answer = "";
var attachmentMsg = {};
sendAttachments();
function sendAttachments() {
var answer = [0, 0]; //successful attachments, failed attachments
//gs.log('Found a attachment##');
var attachmentMessage = new sn_ws.RESTMessageV2();
attachmentMessage.setHttpMethod("get");
attachmentMessage.setBasicAuth(targetUserID, targetUserPassword);
attachmentMessage.setEndpoint(targetInstanceURL);
attachmentMessage.saveResponseBodyAsAttachment("incident", current.sys_id, fileName); // Attachment API documentation for this function
var response = attachmentMessage.execute();
// var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
if (httpStatus.toString() == "201") {
answer[0] += 1;
} else {
answer[1] += 1;
}
return answer;
}
I am still searching for ways to insert files in JIRA from SN without MID-Server.
Do let me know in case of any questions !!!!
Thanks
Rohit
- Labels:
-
Integrations
-
Scripting and Coding
- 9,448 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-14-2018 08:45 PM
Hi harishdasari,
I've made very little changes since posting save for an MD5 sum for the boundary, but to put it all together you will need:
An async business rule which is triggered on insert into the sys_attachment table filtered according to you requirements (eg. Table name is incident) which calls our function:
var j = new JiraIntegration();
var gr = new GlideRecord("incident");
gr.get(current.table_sys_id);
if( gr.isValid() ){
j.addAttachment(current.sys_id, ""+gr.correlation_id, ""+gr.number);
}
An outbound post rest message called 'Jira Issue Attachments' to endpoint ${base_url}/rest/api/2/issue/${issueKey}/attachments with content ${attachmentBody} to post the attachment to Jira
The following function is defined in the JiraIntegration script include which follows the patterns of John Anderson PoC:
addAttachment : function( attachment, key, number ){
var gr = new GlideRecord("sys_attachment");
if (gr.get(attachment)) {
var ga = new GlideSysAttachment();
var digest = new GlideDigest();
var attachmentStream = ga.getContentStream(attachment);
var boundary = digest.getMD5HexFromInputStream(attachmentStream);
var file_name = gr.file_name;
var content_type = gr.content_type;
var r = new sn_ws.RESTMessageV2('Jira Issue Attachments', 'post');
r.setStringParameter('base_url', gs.getProperty('<your app scope>.base_jira_instance_url'));
r.setStringParameter("issueKey", key);
r.setBasicAuth(gs.getProperty('<your app scope>.jira_api_user'), gs.getProperty('<your app scope>.jira_api_password'));
var restMessage = new sn_ws.RESTMessageV2();
restMessage.setBasicAuth(gs.getProperty('<your app scope>.sn_api_user'), gs.getProperty('<your app scope>.sn_api_password'));
restMessage.setHttpMethod("get");
restMessage.setEndpoint(gs.getProperty('glide.servlet.uri')+"/api/<your app scope>/multipartattachment/"+attachment);
restMessage.saveResponseBodyAsAttachment('sys_attachment', attachment, file_name);
var response = restMessage.execute();
var attachment_sys_id = response.getResponseAttachmentSysid();
this.debug("Temporary attachment_sys_id:"+attachment_sys_id);
r.setRequestHeader('Content-Type', 'multipart/form-data; boundary='+boundary);
r.setRequestBodyFromAttachment(attachment_sys_id);
resBody = this._submitBodyTypeRequest(r, true);
this.debug("Handling the response data from Jira");
if(resBody){
if(this.verbose=="true"){
this.debug("Attach response: " + new global.JSON().encode(resBody));
}
this.debug("Added JIRA attachment id: " + resBody[0].id);
this.createAttachmentSyncRecord(key, number, resBody[0].id, "", true, content_type, file_name); // attachment_id is empty
}
// Delete the temporary attachment. This will create a spurious error in attachment.upload event which fires later
//ga.deleteAttachment(attachment_sys_id);
//this.checkJiraForIssueUpdates(true);
} else {
this.debug("Could not find sys_attachment record for sys_id " + attachment);
}
},
System properties for the various values referenced above including a user which has "Web service access only" permission
A scripted rest resource with API definition:multipartAttachment, Name: Attachment, HTTP method: GET, Relative path /{sys_id}
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var attachment_sys_id = request.pathParams.sys_id;
var gr = new GlideRecord("sys_attachment");
if (gr.get(attachment_sys_id)) {
var content_type = gr.content_type;
var file_name = gr.file_name;
var hdrs = {};
var writer = response.getStreamWriter();
var ga = new GlideSysAttachment();
var attachmentStream = ga.getContentStream(attachment_sys_id);
var digest = new GlideDigest();
boundary = digest.getMD5HexFromInputStream(attachmentStream);
attachmentStream = ga.getContentStream(attachment_sys_id);
hdrs['Content-Type'] = 'multipart/form-data; boundary='+boundary;
response.setStatus(200);
response.setHeaders(hdrs);
var bodyHeader = "--" + boundary + "\r\n" +
'Content-Disposition: form-data; name=\"file\"; filename=\"'+file_name+'\"' + "\r\n" +
"Content-Type: " + content_type + "\r\n" + "\r\n";
var bodyFooter = "\r\n--" + boundary + "--"+"\r\n";
writer.writeString(bodyHeader);
writer.writeStream(attachmentStream);
writer.writeString(bodyFooter);
} else {
response.setStatus(400);
}
})(request, response);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-15-2018 05:23 AM
Hi tmackay,
Sir Thank you so much for the help, I have been using your code, but unfortunately it is not working .. I am not sure what mistake I am making.. I have been trying to do this work from very long time.
If possible could you please share your personal gmail id and shall we connect for screen sharing session.
Actually it is something like I am failing to implement this attachment sending functionality from very long time.
Kindly please help me.
Thank you.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-15-2018 06:22 AM
Hello tmackay, can you please explain a little bit more in details how exactly you manage to send attachments to JIRA without MID server.
I included the base64-js library in my SNOW instance, but the part that I don't get how you made is this one:
"GlideSysAttachment().getContentBase64() and a custom base64decode function (more or less straight from github/beatgammit/base64-js) to decode and concatenate the binary data with the multipart/form-data wrappers into an array. I then re-encode the concatenated body into base64 (base64-js) again"
Can you share this part of your code?
Regards, Tsveto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-15-2018 04:39 PM
Sure (attached), although I've moved away from the custom base64 code in favor of the scripted REST resource streamwriter (see previous reply to myself). It's a less nasty solution and doesn't have the file size limitation of getContentBase64 or run the risk of using the last of the heap memory and crashing the instance.
See in particular the addAttachment function which crafts the body (in binary format) in b64Body_1,b64Body_2,b64Body_3 from system generated base64 produced by getContentBase64 and gs.base64Encode for the small strings and the custom base64ToArr function (uses revLookup array from initialize).
These parts can be concatenated and re-encoded to base64 with arrToBase64 (uses lookup array from initialize) and written to a new temporary attachment with writeBase64 to be then used in our REST request with setRequestBodyFromAttachment.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-16-2018 01:23 AM
Thank you so much tmackay! This really helped me and I was finally able to send attachments to JIRA.