Attachment API - POST /now/attachment/file

sreeju
Kilo Explorer

Hello,

I am trying to build an application that collect a report from another application,create an incident and attach to it. I wrote this application in Python. When ever i tried to to attach a file using ecc_queue i am getting an error as below.

Response Status Code: 200

Response JSON Content: {u'reason': None, u'error': u'Insufficient rights to insert records from the table: ecc_queue'}

when i contacted the servicenow administrator he said that ecc_queue is not secure plus he wants me to provide the exact acl in the ecc_queue,we are using geneva implementation. Later he told me to try Attachment API - POST /now/attachment/file.

I have tried this as per the documentation and i get below error.

Response Status Code: 400

Response JSON Content: {u'status': u'failure', u'error': {u'message': u'Attachment is empty', u'detail': None}}

I also tried Attachment API - GET /now/attachment/{sys_id}/file to check if i can retrive an exsisting attachment ,but i dint work as well. i get below error message.

Response Status Code: 404

Response JSON Content: {u'status': u'failure', u'error': {u'message': u'No Record found', u'detail': u"Record doesn't exist or ACL restricts the record retrieval"}}

Please help me.

Thanks

Sree

1 ACCEPTED SOLUTION

santo544
Mega Contributor

Hi Sreejith,



Below code works perfectly fine in Fuji and Geneva, but there is a whole new Attachment API in Geneva as you mentioned,



POST Body


{


"agent":"AttachmentCreator",


"topic":"AttachmentCreator",


"name": "Issue_screenshot.jpg:application/jpg",


"source":"incident:Sys_ID",



"payload":"Base64_string_of_the_attachment"


}



I am currently exploring the Geneva API's


View solution in original post

24 REPLIES 24

could you please show me what do you mean?


Hello Guys,
Issue resolved, no need to do the base64 encoding instead juts pass the data in the post body. I can successfully attach in the incident. £



Thanks a lot for your help.



Documentation is not correct, they have to make it much more user friendly.



Attachment API - POST /now/attachment/file



Thanks


Sree


Hi Sree,



Do you mind to share a little bit of your experience on using the attachment API? We have a requirement to capture the signature of a user and attach it to a record as an attachment. Here is my code, the file attached to the record successfully, but just like you, it is in base64 format. How can I upload the file itself in the body?



  var signatureZone = document.getElementById("cvsSignature"); //my canvas


  var imgSignature = signatureZone.toDataURL("image/png");



  var imageBase64 = imgSignature.replace(/^data:image\/(png|jpeg);base64,/, "");



  var client=new XMLHttpRequest();


  client.open("POST","/api/now/attachment/file?table_name=sc_task&table_sys_id=[sys_id]&file_name=signature.png");


  client.setRequestHeader('Accept','application/json');


  client.setRequestHeader('Content-Type','image/png');


  client.onreadystatechange = function(){


  if(this.readyState == this.DONE){


  document.getElementById("response").innerHTML=this.status + this.response;


  }};



  client.send(imageBase64);



Thanks,



Sam


I guess I found the answer for my own question. It is actually quite simple to upload file if you already have <input tyoe="file" /> on your form. You can simply do this:



var client=new XMLHttpRequest();


 


  client.open("POST","/api/now/attachment/file?table_name=[TABLE_NAME]&table_sys_id=[SYS_ID]&file_name=[FILE_NAME]");


  client.setRequestHeader('Accept','application/json');


  client.setRequestHeader('Content-Type','image/png');


  client.onreadystatechange = function(){


  if(this.readyState == this.DONE){


  document.getElementById("response").innerHTML=this.status + this.response;


  }};



  client.send(document.getElementById('ID_OF_THE_INPUT_FILE').files[0]);




Alternative: In my case, I need to upload a file created from canvas. The code is very similar from above, I just need to convert my image file into a blob object then post it to the server:



var signatureZone = document.getElementById("cvsSignature");


var imgSignature = signatureZone.toDataURL("image/png");




var blob = dataURItoBlob(imgSignature); //see dataURItoBlob() function below




var client=new XMLHttpRequest();




client.open("POST","/api/now/attachment/file?table_name=[TABLE_NAME]&table_sys_id=SYS_ID]&file_name=FILE_NAME]");


client.setRequestHeader('Accept','application/json');


client.setRequestHeader('Content-Type','image/png'); //change the file type if needed.


client.onreadystatechange = function(){


  if(this.readyState == this.DONE){


  document.getElementById("response").innerHTML=this.status + this.response;


  }};



client.send(blob);










The dataURItoBlob() function is here:


function dataURItoBlob(dataURI)


{


  // convert base64/URLEncoded data component to raw binary data held in a string


      var byteString;


      if (dataURI.split(',')[0].indexOf('base64') >= 0)


              byteString = atob(dataURI.split(',')[1]);


      else


              byteString = unescape(dataURI.split(',')[1]);




      // separate out the mime component


      var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];




      // write the bytes of the string to a typed array


      var ia = new Uint8Array(byteString.length);


      for (var i = 0; i < byteString.length; i++) {


              ia[i] = byteString.charCodeAt(i);


      }




      return new Blob([ia], {type:mimeString});


}











This works for me and I hope it will help someone who runs into the same situation as me. It is pretty cool and simple to use the new Attachment API. However, the documentation is simply lacking some details.



I hope it helps



Sam


Hi Sree,



When you say that send the data in the body, how can we send this in the rest api explorer window/postman/soapui?