How to send attachment to Jira from Servicenow

Mike Patel
Tera Sage

Hi all,

When we create ticket in ServiceNow and assigns it to Jira group it creates ticket in Jira with all the information except the attachment.

Can anyone help on how to send attachment to Jira from Servienow.

Thank you

1 ACCEPTED SOLUTION

Solution:


Add below to business rule;


j.addExistingComments(current.sys_id, current.correlation_id);



Create MID Server Script Include


Name: CopyAttachments


Script:


var CopyAttachments = Class.create();




CopyAttachments.prototype = {


      initialize: function() {


              this.debug = probe.getParameter("debug");


              this.debug = true;


              this.logMsg("Starting MID Server File Transfer");


              this.charset = "UTF-8";


              this.LINE_FEED = "\r\n";




              this.boundary = "-----------------------------" + new Date().getTime();


              this.probeParameters = this._getProbeParameters();


              this.response = this.getRemoteFileAndUploadToInstance();


      },




      getRemoteFileAndUploadToInstance: function() {


              var url = this._getInstanceConnectionURL();


              var conn = this._getURLConnection(url);


              var file = this._getFile();


              var response = this._writeFile(conn, file);


              if (response != 200)


                      throw "HTTP response " + response;


              this.logMsg("HTTP response " + response, "debug");




              ms.log("Completed MID Server File Transfer");


              return response;


      },




      _getProbeParameters: function() {


              var probeObj = {};


              probeObj.encpayload = probe.getParameter("filePayload");


              probeObj.fileName = probe.getParameter("fileName");


              probeObj.username = ms.getConfigParameter("mid.jira.user");


              probeObj.password = this._decryptParam(ms.getConfigParameter("mid.jira.password"));


              probeObj.contentType = probe.getParameter("contentType");


              probeObj.JIRA = probe.getParameter("JIRA");


              probeObj.correlationID = probe.getParameter("correlationID");


              return probeObj;


      },




      _getInstanceConnectionURL: function() {


              var base = this.probeParameters.JIRA;


              var mid = "/rest/api/2/issue/";


              var issue = this.probeParameters.correlationID;


              var end = "/attachments";


              return base + mid + issue + end;


      },




      _encodeParam: function(k, v) {


              return k + "=" + Packages.java.net.URLEncoder.encode(v);


      },




      _joinParams: function(base, arr) {


              return base + '?' + arr.join('&');


      },




      _decryptParam: function(encPass) {


              var e = new Packages.com.glide.util.Encrypter();


              var unEncPass = e.decrypt(encPass);  


              return unEncPass;


      },




      _getURLConnection: function(url) {


              if (ms.getConfigParameter("mid.proxy.use_proxy") == 'true') {


                      Packages.java.lang.System.setProperty("https.proxyHost", ms.getConfigParameter("mid.proxy.host"));


                      Packages.java.lang.System.setProperty("http.proxyHost", ms.getConfigParameter("mid.proxy.host"));


                      Packages.java.lang.System.setProperty("https.proxyPort", ms.getConfigParameter("mid.proxy.port"));


                      Packages.java.lang.System.setProperty("http.proxyPort", ms.getConfigParameter("mid.proxy.port"));


              }


              var conn = new Packages.java.net.URL(url).openConnection();




              this.logMsg("Sending to : " + url, "debug");




              var userpass = new java.lang.String(this.probeParameters.username + ":" + this.probeParameters.password);


              conn.setRequestProperty("X-Atlassian-Token", "nocheck");


              conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + this.boundary);


              var basicAuth = "Basic " + (new Packages.javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes()) + '');


              conn.setRequestProperty("Authorization", basicAuth);


              conn.setDoOutput(true);


              conn.setDoInput(true);


              conn.setRequestMethod("POST");


              conn.setUseCaches(false);


              //conn.setRequestProperty("User-Agent", "ServiceNow MID Server POST");


              return conn;


      },




      _getFile: function() {


              //Get The File as Base64 and convert to ByteArrayInputStream


              return new Packages.com.glide.util.StringUtil.base64DecodeAsBytes(this.probeParameters.encpayload);


      },




      _writeFile: function(conn, uploadFile) {


              var outputStream = conn.getOutputStream();


              var writer = new Packages.java.io.PrintWriter(new Packages.java.io.OutputStreamWriter(outputStream, this.charset), true);


              var fieldName = 'file'; // JIRA Requires this as 'file'


              var fileName = this.probeParameters.fileName;




              this.logMsg("Sending file : " + fileName, "debug");




              writer.append("--" + this.boundary).append(this.LINE_FEED);


              writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(this.LINE_FEED);


              //Sometimes ServiceNow does not have the content type for a file (attempt to get it, otherwise default to octet-stream):


              if (JSUtil.notNil(this.probeParameters.contentType)) {


                      writer.append("Content-Type: " + this.probeParameters.contentType).append(this.LINE_FEED);


              } else if (JSUtil.notNil(Packages.java.net.URLConnection.guessContentTypeFromName(fileName))) {


                      writer.append("Content-Type: " + Packages.java.net.URLConnection.guessContentTypeFromName(fileName)).append(this.LINE_FEED);


              } else {


                      writer.append("Content-Type: application/octet-stream").append(this.LINE_FEED);


              }


              writer.append("Content-Transfer-Encoding: binary").append(this.LINE_FEED);


              writer.append(this.LINE_FEED).flush();




              this._writeFileData(uploadFile, outputStream);




              writer.append(this.LINE_FEED).flush();


              writer.append(this.LINE_FEED).flush();


              writer.append("--" + this.boundary + "--").append(this.LINE_FEED);


              writer.close();


              var readResponse = "";


              if (conn.getResponseCode() == 200) {


                      var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(conn.getInputStream()));


                      var line = reader.readLine();


                      while (line != null) {


                              readResponse += line;


                              line = reader.readLine();


                      }


              }


              return conn.getResponseCode();


      },






      _writeFileData: function(uploadFile, outputStream) {


              var inputStream = new Packages.java.io.ByteArrayInputStream(uploadFile);




              var data = new Packages.java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096);


              var bytesRead = 0;


              while ((bytesRead = inputStream.read(data)) != -1) {


                      outputStream.write(data, 0, bytesRead);


                      outputStream.flush();


              }


              inputStream.close();


      },




      logMsg: function(message, logType) {


              logType = logType || 'info';


              var prefixStr = "*** MID Server Remote File";


              if (logType == 'info' || logType == 'error') {


                      ms.log(prefixStr + " " + logType.toUpperCase() + "*** " + message);


              }


              if (this.debug && logType == 'debug') {


                      ms.log(" DEBUG *** " + message);


              }


      },




      type: "CopyAttachments"


};



Add to Main Script Library (under Jira)


addExistingAttachments: function(taskID, corrID) {


              this.debug("Adding Attachments for : " + taskID);


              var attachment = new GlideRecord('sys_attachment');


              attachment.addQuery('table_sys_id', taskID);


              attachment.query();


              while (attachment.next()) {


                      this._buildAttachmentRequest(attachment, taskID, corrID);


              }


      },




      _buildAttachmentRequest: function(att, taskID, corrID) {


              try {


                      var sa = new GlideSysAttachment();


                      var binData = sa.getBytes(att);


                      var encData = GlideStringUtil.base64Encode(binData);


                      var file_name = att.file_name.toString();


                      var contentType = att.content_type.toString();


                      this._sendAttachmentRequest(encData, file_name, contentType, corrID);


                      this.debug("Adding Attachment : " + file_name + " Content-Type: " + contentType);


              } catch (Exception) {


                      this.debug('Failed sending Attachment to due to Exception: ' + Exception);


              }




      },




      _sendAttachmentRequest: function(encData, file_name, contentType, corrID) {


              //Calls the MID Server Script Include


              this.debug("Calling MID Server Script Include");


              var jp = new JavascriptProbe(this.midServer);


              jp.setName("CopyAttachments");


              jp.setJavascript("var req = new CopyAttachments();");


              jp.addParameter("filePayload", encData);


              jp.addParameter("JIRA", gs.getProperty('com.snc.integration.jira.base_jira_instance_url'));


              jp.addParameter("fileName", file_name);


              jp.addParameter("contentType", contentType);


              jp.addParameter("correlationID", corrID);


              jp.create();


      },



Make sure you have MID Server selected


Untitled.png


View solution in original post

29 REPLIES 29

Hi Mike,


If you can Paste CopyAttachment() Method here ,So then I can Help or it will be good for other people who are looking for the same.


Have a great day.


I got it to work. MID Server field was empty that's why it was not working. Once I added the MID Server the attachments shows up in Jira.



Untitled.png


Solution:


Add below to business rule;


j.addExistingComments(current.sys_id, current.correlation_id);



Create MID Server Script Include


Name: CopyAttachments


Script:


var CopyAttachments = Class.create();




CopyAttachments.prototype = {


      initialize: function() {


              this.debug = probe.getParameter("debug");


              this.debug = true;


              this.logMsg("Starting MID Server File Transfer");


              this.charset = "UTF-8";


              this.LINE_FEED = "\r\n";




              this.boundary = "-----------------------------" + new Date().getTime();


              this.probeParameters = this._getProbeParameters();


              this.response = this.getRemoteFileAndUploadToInstance();


      },




      getRemoteFileAndUploadToInstance: function() {


              var url = this._getInstanceConnectionURL();


              var conn = this._getURLConnection(url);


              var file = this._getFile();


              var response = this._writeFile(conn, file);


              if (response != 200)


                      throw "HTTP response " + response;


              this.logMsg("HTTP response " + response, "debug");




              ms.log("Completed MID Server File Transfer");


              return response;


      },




      _getProbeParameters: function() {


              var probeObj = {};


              probeObj.encpayload = probe.getParameter("filePayload");


              probeObj.fileName = probe.getParameter("fileName");


              probeObj.username = ms.getConfigParameter("mid.jira.user");


              probeObj.password = this._decryptParam(ms.getConfigParameter("mid.jira.password"));


              probeObj.contentType = probe.getParameter("contentType");


              probeObj.JIRA = probe.getParameter("JIRA");


              probeObj.correlationID = probe.getParameter("correlationID");


              return probeObj;


      },




      _getInstanceConnectionURL: function() {


              var base = this.probeParameters.JIRA;


              var mid = "/rest/api/2/issue/";


              var issue = this.probeParameters.correlationID;


              var end = "/attachments";


              return base + mid + issue + end;


      },




      _encodeParam: function(k, v) {


              return k + "=" + Packages.java.net.URLEncoder.encode(v);


      },




      _joinParams: function(base, arr) {


              return base + '?' + arr.join('&');


      },




      _decryptParam: function(encPass) {


              var e = new Packages.com.glide.util.Encrypter();


              var unEncPass = e.decrypt(encPass);  


              return unEncPass;


      },




      _getURLConnection: function(url) {


              if (ms.getConfigParameter("mid.proxy.use_proxy") == 'true') {


                      Packages.java.lang.System.setProperty("https.proxyHost", ms.getConfigParameter("mid.proxy.host"));


                      Packages.java.lang.System.setProperty("http.proxyHost", ms.getConfigParameter("mid.proxy.host"));


                      Packages.java.lang.System.setProperty("https.proxyPort", ms.getConfigParameter("mid.proxy.port"));


                      Packages.java.lang.System.setProperty("http.proxyPort", ms.getConfigParameter("mid.proxy.port"));


              }


              var conn = new Packages.java.net.URL(url).openConnection();




              this.logMsg("Sending to : " + url, "debug");




              var userpass = new java.lang.String(this.probeParameters.username + ":" + this.probeParameters.password);


              conn.setRequestProperty("X-Atlassian-Token", "nocheck");


              conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + this.boundary);


              var basicAuth = "Basic " + (new Packages.javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes()) + '');


              conn.setRequestProperty("Authorization", basicAuth);


              conn.setDoOutput(true);


              conn.setDoInput(true);


              conn.setRequestMethod("POST");


              conn.setUseCaches(false);


              //conn.setRequestProperty("User-Agent", "ServiceNow MID Server POST");


              return conn;


      },




      _getFile: function() {


              //Get The File as Base64 and convert to ByteArrayInputStream


              return new Packages.com.glide.util.StringUtil.base64DecodeAsBytes(this.probeParameters.encpayload);


      },




      _writeFile: function(conn, uploadFile) {


              var outputStream = conn.getOutputStream();


              var writer = new Packages.java.io.PrintWriter(new Packages.java.io.OutputStreamWriter(outputStream, this.charset), true);


              var fieldName = 'file'; // JIRA Requires this as 'file'


              var fileName = this.probeParameters.fileName;




              this.logMsg("Sending file : " + fileName, "debug");




              writer.append("--" + this.boundary).append(this.LINE_FEED);


              writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(this.LINE_FEED);


              //Sometimes ServiceNow does not have the content type for a file (attempt to get it, otherwise default to octet-stream):


              if (JSUtil.notNil(this.probeParameters.contentType)) {


                      writer.append("Content-Type: " + this.probeParameters.contentType).append(this.LINE_FEED);


              } else if (JSUtil.notNil(Packages.java.net.URLConnection.guessContentTypeFromName(fileName))) {


                      writer.append("Content-Type: " + Packages.java.net.URLConnection.guessContentTypeFromName(fileName)).append(this.LINE_FEED);


              } else {


                      writer.append("Content-Type: application/octet-stream").append(this.LINE_FEED);


              }


              writer.append("Content-Transfer-Encoding: binary").append(this.LINE_FEED);


              writer.append(this.LINE_FEED).flush();




              this._writeFileData(uploadFile, outputStream);




              writer.append(this.LINE_FEED).flush();


              writer.append(this.LINE_FEED).flush();


              writer.append("--" + this.boundary + "--").append(this.LINE_FEED);


              writer.close();


              var readResponse = "";


              if (conn.getResponseCode() == 200) {


                      var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(conn.getInputStream()));


                      var line = reader.readLine();


                      while (line != null) {


                              readResponse += line;


                              line = reader.readLine();


                      }


              }


              return conn.getResponseCode();


      },






      _writeFileData: function(uploadFile, outputStream) {


              var inputStream = new Packages.java.io.ByteArrayInputStream(uploadFile);




              var data = new Packages.java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096);


              var bytesRead = 0;


              while ((bytesRead = inputStream.read(data)) != -1) {


                      outputStream.write(data, 0, bytesRead);


                      outputStream.flush();


              }


              inputStream.close();


      },




      logMsg: function(message, logType) {


              logType = logType || 'info';


              var prefixStr = "*** MID Server Remote File";


              if (logType == 'info' || logType == 'error') {


                      ms.log(prefixStr + " " + logType.toUpperCase() + "*** " + message);


              }


              if (this.debug && logType == 'debug') {


                      ms.log(" DEBUG *** " + message);


              }


      },




      type: "CopyAttachments"


};



Add to Main Script Library (under Jira)


addExistingAttachments: function(taskID, corrID) {


              this.debug("Adding Attachments for : " + taskID);


              var attachment = new GlideRecord('sys_attachment');


              attachment.addQuery('table_sys_id', taskID);


              attachment.query();


              while (attachment.next()) {


                      this._buildAttachmentRequest(attachment, taskID, corrID);


              }


      },




      _buildAttachmentRequest: function(att, taskID, corrID) {


              try {


                      var sa = new GlideSysAttachment();


                      var binData = sa.getBytes(att);


                      var encData = GlideStringUtil.base64Encode(binData);


                      var file_name = att.file_name.toString();


                      var contentType = att.content_type.toString();


                      this._sendAttachmentRequest(encData, file_name, contentType, corrID);


                      this.debug("Adding Attachment : " + file_name + " Content-Type: " + contentType);


              } catch (Exception) {


                      this.debug('Failed sending Attachment to due to Exception: ' + Exception);


              }




      },




      _sendAttachmentRequest: function(encData, file_name, contentType, corrID) {


              //Calls the MID Server Script Include


              this.debug("Calling MID Server Script Include");


              var jp = new JavascriptProbe(this.midServer);


              jp.setName("CopyAttachments");


              jp.setJavascript("var req = new CopyAttachments();");


              jp.addParameter("filePayload", encData);


              jp.addParameter("JIRA", gs.getProperty('com.snc.integration.jira.base_jira_instance_url'));


              jp.addParameter("fileName", file_name);


              jp.addParameter("contentType", contentType);


              jp.addParameter("correlationID", corrID);


              jp.create();


      },



Make sure you have MID Server selected


Untitled.png


Hi Mike,



Thanks for posting this. It was very much helpful.



And, did u try getting attachments from JIRA? As the JIRA REST API gives us only the URL, do u have any code to download it and attach it to incidents in ServiceNow?



Thanks in advance,


Sreeja


No, It was not in requirements so I haven't done that.



Refer to Generate Attachments in ServiceNow via REST-John Andersen to do that.