Attempting to POST attachment to 3rd party endpoint failure
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-12-2019 01:57 PM
Hello,
I am attempting to POST attachments from ServiceNow to OpsGenie.
I have gotten it to work via PostMan but when I try in ServiceNow, it results in the following error message:
Response status: 413, body: {"message":"The current request is not a multipart request","took":0.003,"requestId":"5e54093d-0fa4-4f60-8535-7857b2b7dd73"}
How my code works:
1) Business rule on sys_attachment table that encodes the file in base64 then sends that, along with the attachment sys_id to a script include
2) Script include receives that info and then creates the REST call, which it fires off to OpsGenie
Here is the relevant portion of the BR code:
// 2) Now that we've confirmed it's an OpsGenie inc, fire the REST call
gs.log('OpsGenie Create Attachment Alert: firing REST call from ZG - Send to OpsGenie BR on sys_attachment table','x_86994_opsgenie');
var StringUtil = new GlideStringUtil();
var sa = new GlideSysAttachment();
var binData = sa.getBytes(current);
var encData = StringUtil.base64Encode(binData);
var client = new x_86994_opsgenie.OpsGenie_Client();
client.postAttachmentToOpsGenieAlertAPI(current.sys_id, gr.number,encData,current.content_type);
gs.log("5 step","x_86994_opsgenie");
Script include code:
postAttachmentToOpsGenieAlertAPI: function(attach_sys_id, incNumber,encData,content_type){
try {
gs.info("1 Entering postAttachmentToOpsGenieAlertAPI","OpsGenie_Client");
// build the body, just needs to be the incNumber
var bodyContent = {
"alertIdentifier": "INC1102325",
"file":encData
};
var bodyContentJSON = new global.JSON().encode(bodyContent);
// build out our subEndPoint to fit into: ${endPoint}/v2/alerts${subEndPoint}
// target: https://api.opsgenie.com/v2/alerts/:alertIdentifier/attachments
// so build out: /:alertIdentifier/attachments
var subEndPoint = "/" + incNumber + "/attachments";
gs.info("Body:\n" + bodyContentJSON + "\nincNumber:\n" + incNumber + "\nencData:\n" + encData + "\ncontent_type:\n" + content_type,"OpsGenie_Client");
// create the REST message
var rest = new sn_ws.RESTMessageV2('x_86994_opsgenie.OpsGenie Alert API Endpoint', 'post');
rest.setRequestHeader("Content-Type", content_type);
rest.setRequestHeader("Authorization", "GenieKey " + this.apiKey);
rest.setQueryParameter("alertIdentifierType", "alias");
rest.setQueryParameter('file',encData);
rest.setStringParameter("endPoint", this.endpoint);
rest.setStringParameter("subEndPoint", subEndPoint);
rest.setRequestBody(bodyContentJSON);
// POST it
gs.info("Posting attachment " + attach_sys_id + " from " + incNumber + " to " + rest.getEndpoint(),'OpsGenie_Client');
var response = rest.execute();
// Parse response
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
var responseLogMessage = "Response status: " + httpStatus + ", body: " + responseBody;
if(!httpStatus.toString().startsWith("2")){
gs.error(responseLogMessage,'OpsGenie_Client');
} else{
gs.info(responseLogMessage,'OpsGenie_Client');
}
}
catch(ex) {
var message = ex.getMessage();
gs.error("Exception occured: ", "OpsGenie_Client" + ex);
}
},
I'm not sure why it's returning a 413: current request is not a multi-part request. I verified that the data is being encoded properly and I am able to decode it. From what I found online, that error code occurs either when the content-type is not set correctly, or when the file is missing, but the file is being set in the query param (as the documentation states it should be) and in the body (something I was just testing out).
Thanks!
- Labels:
-
Integrations
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-16-2019 08:02 AM
Hi Surya,
I think the 3rd party system accepts data into multipart form data but you are not sending it in multipart
multipart/form-data is used for large binary data handling
Do you have the sample request shared by the 3rd party team so that you would know how to send the attachment data along with other information?
Best method is ask for sample request body to better know how and where to send the data
Sample multi-part form data request body looks like this; the --AAA is the boundary and says that it is the separating the data into the body
Example: below
pdf -> contentType = 'application/pdf';
doc/docx -> contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
Sample Content Body:
--AAA
Content-Type: application/json
Content-Disposition: form-data
{
"alertIdentifier": "INC1102325"
}
--AAA
Content-Type: application/pdf
Content-Disposition: file; filename="hello.pdf";documentid=1
Content-Transfer-Encoding: base64
${encData{
--AAA--
In the http post method in rest message add this headers
Mark Correct if this solves your issue and also mark Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-16-2019 10:21 AM
Hi Ankur,
Here is the documentation for the request (create alert attachment):
https://docs.opsgenie.com/docs/alert-api-continued#section-create-alert-attachment
You may be right about it being forced into multipart/form-data. I would be surprised though as I thought it would have supported more formats. Any idea how to encode in multipart/form-data request in ServiceNow?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-16-2019 05:09 PM
Here's what I've tried doing so far:
postAttachmentToOpsGenieAlertAPI: function(attach_sys_id, incNumber,encData,content_type,file_name){
try {
// build the body, just needs to be the incNumber
var bodyContent = {
"alertIdentifier": "INC1102325",
"file":encData
};
var bodyContentJSON = new global.JSON().encode(bodyContent);
// build out our subEndPoint to fit into: ${endPoint}/v2/alerts${subEndPoint}
// target: https://api.opsgenie.com/v2/alerts/:alertIdentifier/attachments
// so build out: /:alertIdentifier/attachments
var subEndPoint = "/" + incNumber + "/attachments";
// create the REST message
var rest = new sn_ws.RESTMessageV2('x_86994_opsgenie.OpsGenie Alert API Endpoint', 'post');
rest.setRequestHeader("Content-Disposition","form-data"); // added
rest.setRequestHeader("Content-Type", "multipart/form-data; boundary=-----WebKitFormBoundaryAAA"); // changed from "content_type"
//rest.setRequestHeader("Content-Type", content_type);
rest.setRequestHeader("Authorization", "GenieKey " + this.apiKey);
rest.setQueryParameter("alertIdentifierType", "alias");
rest.setStringParameter("endPoint", this.endpoint);
rest.setStringParameter("subEndPoint", subEndPoint);
// trying to add boundaries here
bodyContentJSON = "-----WebKitFormBoundaryAAA\nContent-Type:application/json\nContent-Disposition:form-data\n" + bodyContentJSON + "\n-----WebKitFormBoundaryAAA\nContent-Type:" + content_type + "\nContent-Disposition:file;filename=" + file_name + ";documentid=1\nContent-Transfer-Encoding:base64\n-----WebKitFormBoundaryAAA--";
rest.setRequestBody(bodyContentJSON);
gs.info("Body:\n" + bodyContentJSON);
// POST it
gs.info("Posting attachment " + attach_sys_id + " from " + incNumber + " to " + rest.getEndpoint(),'OpsGenie_Client');
var response = rest.execute();
// there's more but I took it out of the ServiceNow community post
},
Now, my response from OpsGenie is:
Response status: 404, body: {"message":"No handler found","took":0.0,"requestId":"ac6bdcd7-b6f9-43eb-a1cb-dac3ecf04ec8"}
I'm guessing that's because it's not parsing the boundaries?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-17-2019 02:58 AM
Hi Surya,
At least now you are getting some response and no error for multi-part form data
check what is the request body being sent using
gs.info('Request Body sent is: ' + rest.getRequestBody());
this will help you knowing whether boundary is set properly or not
Mark Correct if this solves your issue and also mark Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader