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

arijitwarm32
Kilo Contributor

Hi Mike ,

 

We are in a similar situation to do this very urgently and I just wonder what is not working at all . I have used your code above but besides creating a Javascript Probe nothing seems to work . And I do not have access to the Mid Server as well so that I can check the logs .

 

Can you help me on this please ? I am using exactly the same code you have used above and made some changes where required .

Can you share what do you have so far and what's error you get.

The Javascript probe gets generated in the ECC queue but I don’t know what happened after that As I do not have the access to the Mid Server Logs . Obviously due to some error the files are not getting attached in the ticket. Is there a possibility that the Mid Server is not able to execute the probe because of the one of the many reasons which includes the fact it doesn’t have ports open to access the jira rest api ( as the jira service is running on a different server ) . Also just tell me if I am wrong , the mid.jira.username and mid.jira.password are the userid and password for the service account to access jira from snow .

Yes,  mid.jira.username and pass are Jira Service account info.

In order this to work you need to make sure your mid server can connect to jira using 443 port.

Also if you can share ECC quque screenshot I can check if I see any issue in it.