The CreatorCon Call for Content is officially open! Get started here.

Need assistance with decoding a file with StringUtil.base64DecodeAsBytes

rita_m
Tera Guru

Hi - 

I need to submit an attachment from a ServiceNow instance to a ServiceNow instance via rest.

In the following code snippet, the following widget server side code works perfectly: 

 var attachment = new Attachment();
 var wr = attachment.write(dataTable, data.incSysID, file.filename, '', StringUtil.base64DecodeAsBytes(file.file));

 

...Except I can't use it, as it doesn't work when run as guest.  For my purposes, I need to send the attachment via rest with a hardcoded basic auth so that guests can do it too.

However, I can't get the following rest code to work.  It kind of works: it uploads a "file" to the right table with the right name and data type, but the file is only a couple bytes long.

StringUtil.base64DecodeAsBytes(file.file), for some reason, is NOT giving me the entire data string.  I can't find any info on StringUtil.base64DecodeAsBytes, and I'm not sure what I'm doing wrong.  

function addFiles() {
  var dataTable = "incident";


  //Attach files to ticket
  input.nsf_files.forEach(function(file) {
    var StringUtil = new GlideStringUtil();

    if (file.filename) { 
     //this works, but runs as whoever is logged in on the portal, so if guest it won't work.
     // var attachment = new Attachment();
     // var wr = attachment.write(dataTable, data.incSysID, file.filename, '', StringUtil.base64DecodeAsBytes(file.file));

gs.log(StringUtil.base64DecodeAsBytes(file.file));//This is returning [B@1f34781
                                                  //this should be a 4kb file

     //since the data is way too small, of course this isn't working
     var restMessage = new sn_ws.RESTMessageV2();
     restMessage.setBasicAuth(user, passwd);
     restMessage.setHttpMethod("POST");
     restMessage.setEndpoint(instanceURL + 'api/now/attachment/file?table_name=' + 
          dataTable + '&table_sys_id=' + data.incSysID + '&file_name=' + file.filename); 
     restMessage.setRequestHeader("Accept", "application/json");
     restMessage.setRequestHeader('Content-Type', file.filetype); 
     restMessage.setRequestBody(StringUtil.base64DecodeAsBytes(file.file)); 
     restMessage.setRequestBody(requestBody);
     var response = restMessage.execute();
     var responseBody = response.getBody();
     var httpStatus = response.getStatusCode();
     gs.addInfoMessage("file uploaded response statuscode: "+httpStatus);
    }
  });

}

Please help!  How can I get access to the entire "file.file" attachment data here?

5 REPLIES 5

MrMuhammad
Giga Sage

For decoding, use 

GlideStringUtil.base64Decode('encoded_string');

For encoding, use

GlideStringUtil.base64Encode('my_string');

Try below-updated code. (untested)

function addFiles() {
  var dataTable = "incident";


  //Attach files to ticket
  input.nsf_files.forEach(function(file) {
    var StringUtil = new GlideStringUtil();

    if (file.filename) { 
     //this works, but runs as whoever is logged in on the portal, so if guest it won't work.
     // var attachment = new Attachment();
     // var wr = attachment.write(dataTable, data.incSysID, file.filename, '', StringUtil.base64DecodeAsBytes(file.file));
      
     var sa = new GlideSysAttachment();
     var binData = sa.getBytes(file);
     var decData = StringUtil.base64Decode(binData);
      
     gs.log(decData));//This is returning [B@1f34781
                                                  //this should be a 4kb file

     //since the data is way too small, of course this isn't working
     var restMessage = new sn_ws.RESTMessageV2();
     restMessage.setBasicAuth(user, passwd);
     restMessage.setHttpMethod("POST");
     restMessage.setEndpoint(instanceURL + 'api/now/attachment/file?table_name=' + 
          dataTable + '&table_sys_id=' + data.incSysID + '&file_name=' + file.filename); 
     restMessage.setRequestHeader("Accept", "application/json");
     restMessage.setRequestHeader('Content-Type', file.filetype); 
     restMessage.setRequestBody(decData); 
     restMessage.setRequestBody(requestBody);
     var response = restMessage.execute();
     var responseBody = response.getBody();
     var httpStatus = response.getStatusCode();
     gs.addInfoMessage("file uploaded response statuscode: "+httpStatus);
    }
  });

}

Reference - https://community.servicenow.com/community?id=community_question&sys_id=6404c7e5dbd8dbc01dcaf3231f96...

 

Regards,
Muhammad

Thanks for responding!

Unfortunately, that didn't work.  That gives the same output as before.

     gs.log(decData));//This is STILL returning [B@1f34781

Hi Muhammad - 

Thanks for responding!

 

Unfortunately, it looks like the function GlideSysAttachment sa.getBytes expects file to be a glide record to an entry in the sys_attachment table.  And mine... is not.  

var sa = new GlideSysAttachment();
var binData = sa.getBytes(file);

This sa.getBytes code stops my script without even an error... it just never makes it past it.

 

 

However, researching your response (and why it wasn't working) made me get farther in my research, so thanks!

Hello - you are right. It takes GlideRecordObject of Attachments. What exactly this file is? What is the format?
Regards,
Muhammad