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

Rohit Kumar
Giga Expert

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

15 REPLIES 15

antin_s
ServiceNow Employee
ServiceNow Employee

Hi Rohit,



"I am still searching for ways to insert files in JIRA from SN without MID-Server" - MID server is used when JIRA or any external systems are behind the firewall. If your JIRA instance is not under firewall, you should be able to use their REST/SOAP APIs (assuming they have) directly to send attachments to JIRA. Am I missing something here?



Hope this helps. Mark the answer as correct/helpful based on impact.



Thanks


Antin


tmackay
Giga Contributor

I've been reworking the John Anderson PoC into a scoped app for our own ServiceNow/JIRA integration. Still in early stages, but was able to upload attachments to JIRA without a MID-Server. My current solution is to use 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, add a new attachment with GlideSysAttachment().writeBase64(), then set the request body with RESTMessageV2().setRequestBodyFromAttachment(). Kind of nasty but it got there. What I wouldn't give for a streamWriter object that could do the concatenation on the fly.

tmackay
Giga Contributor

To follow up on the streamWriter idea, the only thing I've found so far is the response.getStreamWriter() in a Scripted REST API. Still a bit of a detour, but less hacky than the first attempt and probably less prone to causing out of memory issues.

// from Script Include, addAttachment function in class
addAttachment : function( attachment, key ){
  var gr = new GlideRecord("sys_attachment");
  if (gr.get(attachment)) {
    var ga = new GlideSysAttachment();
    
    var r = new sn_ws.RESTMessageV2('Jira Issue Attachments', 'post');
    r.setStringParameter('base_url', gs.getProperty('x_scope.base_jira_instance_url'));
    r.setStringParameter("issueKey", key);
    r.setBasicAuth(gs.getProperty('x_scope.jira_api_user'), gs.getProperty('x_scope.jira_api_password'));
    
    var file_name = gr.file_name;
    var content_type = gr.content_type;
    var boundary = '<some random number>';
      
    // alternative using Scripted REST Resource
    var restMessage = new sn_ws.RESTMessageV2();
    restMessage.setBasicAuth("admin", "admin"); // TODO: make property or auth profile
    restMessage.setHttpMethod("get");
    restMessage.setEndpoint("https://<instance>.service-now.com/api/x_scope/multipartattachment/"+attachment); // TODO: make property
    restMessage.saveResponseBodyAsAttachment('sys_attachment', attachment, file_name);
    
    var response = restMessage.execute();
    var attachment_sys_id = response.getResponseAttachmentSysid();
    this.debug("Temporary attachment_sys_id:"+tmpAttachment);
    
    r.setRequestHeader('Content-Type', 'multipart/form-data; boundary='+boundary);
    r.setRequestBodyFromAttachment(attachment_sys_id);
    r.execute();
  }
},
            
//Scripted REST Resource
(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 boundary = '<some random number>';

		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";
		
		var hdrs = {};

		hdrs['Content-Type'] = 'multipart/form-data';
		response.setStatus(200);
		response.setHeaders(hdrs);

		var writer = response.getStreamWriter();
		var ga = new GlideSysAttachment();
		var attachmentStream = ga.getContentStream(attachment_sys_id);
		
		writer.writeString(bodyHeader);
		writer.writeStream(attachmentStream);
		writer.writeString(bodyFooter);
		
	} else {
		response.setStatus(400);
	}
})(request, response);

note: still pretty rough and has minimal error handling

Hi tmackay, actually we have implemented JIRA-SNOW integration in our own custom development, Not used the James Anderson POC. Just took it as reference but not used it. Could you please send me actual code how to send attachment from servicenow to jira using REST api. kindly please share the code and steps to achieve it. Thank you.