Urgent Help Needed: ServiceNow to Jira Attachment Issue (Corrupted Files)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-15-2025 02:23 PM
Good afternoon everyone, I hope you're doing well.
I'm reaching out for urgent assistance regarding an issue with a business rule that triggers when an attachment is added to a change request in ServiceNow. The rule is supposed to transfer the attachment to the corresponding issue in Jira, but it's not working correctly.
The main problem is that when the attachment is uploaded to Jira, its size doubles, making the file corrupted. I have attempted the following solutions without success:
- GlideScriptedStream
- Uint8Array
- GlideBufferedInputStream
- Setting Content-Type: application/octet-stream with setRequestBodyFromStream() (throws an error)
- Using FORM DATA results in a 500 error
I urgently need your help in resolving this issue. Below is my current script:
(function executeRule(current, previous /*null when async*/) {
gs.info("La Business Rule se está ejecutando. Adjunto: " + current.file_name);
if (current.table_name.toLowerCase() == "change_request") {
var changeTaskGR = new GlideRecord("change_request");
if (changeTaskGR.get(current.table_sys_id)) {
var jiraIssueId = changeTaskGR.getValue("u_id_hu");
if (jiraIssueId) {
gs.info("Jira Issue ID encontrado: " + jiraIssueId);
// Enviar solo adjuntos nuevos
sendNewAttachmentsToJira(
current.table_sys_id,
jiraIssueId,
"change_request",
current.sys_created_on
);
} else {
gs.warn("El campo u_nreferens no tiene valor en la change_task con sys_id: " + current.table_sys_id);
}
} else {
gs.warn("No se encontró un registro change_task con sys_id: " + current.table_sys_id);
}
}
})(current, previous);
function sendNewAttachmentsToJira(sysId, jiraIssueId, tableName, currentCreatedOn) {
var attachmentGR = new GlideRecord("sys_attachment");
attachmentGR.addQuery("table_name", tableName);
attachmentGR.addQuery("table_sys_id", sysId);
attachmentGR.addQuery("sys_created_on", ">=", currentCreatedOn);
attachmentGR.query();
while (attachmentGR.next()) {
var fileName = attachmentGR.file_name;
var contentType = attachmentGR.content_type;
var attachmentSize = attachmentGR.size_bytes; // Tamaño del archivo
// 🔍 Obtener el contenido del archivo en formato binario
var attachmentContent = new GlideSysAttachment().getBytes(attachmentGR);
if (!attachmentContent || attachmentContent.length === 0) {
gs.warn("El archivo está vacío o no se pudo leer, no se enviará.");
continue;
}
gs.info("📌 Archivo: " + fileName);
gs.info("📏 Tamaño original en ServiceNow (bytes): " + attachmentSize);
gs.info("📏 Tamaño obtenido con getBytes() (bytes): " + attachmentContent.length);
var boundary = "----WebKitFormBoundary" + gs.generateGUID();
var newLine = "\r\n";
// ✅ **Construcción del cuerpo multipart correctamente**
var requestBody = "";
requestBody += "--" + boundary + newLine;
requestBody += 'Content-Disposition: form-data; name="file"; filename="' + fileName + '"' + newLine;
requestBody += "Content-Type: " + contentType + newLine + newLine;
var endBoundary = newLine + "--" + boundary + "--" + newLine;
// 🟢 Crear un flujo de datos binario correctamente
var combinedRequestBody = new GlideScriptedStream();
combinedRequestBody.writeString(requestBody);
combinedRequestBody.writeBytes(attachmentContent);
combinedRequestBody.writeString(endBoundary);
// 🔍 Medir el tamaño del cuerpo de la solicitud
var requestSize = requestBody.length + attachmentContent.length + endBoundary.length;
gs.info("📏 Tamaño final del request en binario (bytes): " + requestSize);
var attachmentRequest = new sn_ws.RESTMessageV2();
attachmentRequest.setHttpMethod("POST");
attachmentRequest.setEndpoint(
"https://{user_instance}.atlassian.net/rest/api/3/issue/" +
jiraIssueId +
"/attachments"
);
var base64Auth = GlideStringUtil.base64Encode(
"user" + ":" + "user_token"
);
attachmentRequest.setRequestHeader("Authorization", "Basic " + base64Auth);
attachmentRequest.setRequestHeader("X-Atlassian-Token", "no-check");
attachmentRequest.setRequestHeader("Accept", "application/json");
attachmentRequest.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
// ✅ **Enviar el archivo en formato binario puro**
attachmentRequest.setBinaryBody(combinedRequestBody, "multipart/form-data");
try {
var attachmentResponse = attachmentRequest.execute();
var status = attachmentResponse.getStatusCode();
var responseBody = attachmentResponse.getBody();
if (status == 200 || status == 201) {
gs.info(
'✅ Attachment "' + fileName + '" subido exitosamente a Jira issue ID: ' + jiraIssueId
);
} else {
gs.warn("⚠️ No se pudo subir el attachment. Status: " + status + ", Respuesta: " + responseBody);
}
} catch (ex) {
gs.error("❌ Error al subir el attachment a Jira: " + ex.message);
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-15-2025 06:20 PM
Si necesito usar script include o otras cosas por favor dime, necesito una solución con urgencia

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-15-2025 07:31 PM
Creo que lo que debes hacer es exactamente lo que tenemos en la comunidad en el enlace a continuación.
Prueba esto y si no puedes hacerlo házmelo saber, podemos programar una sesión para que pueda ayudarte con esto.
Business rule to send attachment to 3rd Party Tool via REST
Unable to send attachment via REST
Si mi respuesta te ayudó a llegar a la solución, ayúdame marcándola como la respuesta correcta.
- Carlos Petrucio

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-17-2025 07:50 AM
¿Lograste resolverlo?
Si mi respuesta te ayudó a llegar a la solución, ayúdame marcándola como la respuesta correcta.
- Carlos Petrucio