Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Get contents of attachment record using cURL?

mmcbride1007
Tera Contributor

Does anyone know of a way to get an attachment record from the system using cURL on the command line? We've tried a basic curl "http://myinstance.service-now.com/sys_attachment.do?sys_id=12345" and also adding user authentication, using curl -user "username:password" "https://myinstance.service-now.com/sys_attachment.do?sys_id=12345" with no luck. The REST API is no good in this situation since it returns a JSON object of the database record rather than the actual content of the attachment. We're trying to download a CSS file that we've attached to a UI page, so we need the actual CSS contained in the attachment.

Mark Stanger (Crossfuze) John Andersen hoping you guys may have stumbled across something like this or could point me where to look...

1 ACCEPTED SOLUTION

Hey! Yeah we did solve it. We ended up using a processor, which uses basic auth when they hit that URL. We passed the sys_id of the attachment record in as a parameter in the processor, and were able to get the contents of the attachment based on knowing the sys_id.


View solution in original post

5 REPLIES 5

guiguille
Giga Expert

Hey Mike McBride, where you able to solve this? I'm in a situation where emails are being sent with links to sys_attachment, but can't find a way for users to be able to see them without authentication.


Hey! Yeah we did solve it. We ended up using a processor, which uses basic auth when they hit that URL. We passed the sys_id of the attachment record in as a parameter in the processor, and were able to get the contents of the attachment based on knowing the sys_id.


dmfranko
Kilo Guru

Mike,



Can you share the code for this?


I'm pretty sure I found this somewhere else on the community, but basically this processor will pull all of the attachments for a given record.   Then using your chosen tech you can pull the attachments, decode them and save them as files.   I used ruby below.



var incidentSysID = g_request.getParameter("sys_id");



count = 1;


var StringUtil = Packages.com.glide.util.StringUtil;



var   gr = new GlideRecord("sys_attachment");


gr.addQuery("table_sys_id", incidentSysID);


gr.query();



//Starting to create the XML Document Response


var xmldoc = new XMLDocument("");


var myRootElement = xmldoc.createElement("executeResponse");



while (gr.next()){


    //Getting the file and encoding it with Base 64 encoding


    var sa = new   Packages.com.glide.ui.SysAttachment();


    var binData =   sa.getBytes(gr);


    var encData =   StringUtil.base64Encode(binData);



    //Creating the XML document elements for each attachcment


    xmldoc.setCurrent(myRootElement);


    var myElement = xmldoc.createElement("attachment");


    myElement.setAttribute("number",count);


    xmldoc.setCurrent(myElement);


    xmldoc.createElement("file_name", gr.file_name);


    xmldoc.createElement("encodedAttachment", encData);



    count += 1;


}


//Sending the XML Document as the SOAP response


g_processor.writeOutput(xmldoc);



Ruby script



require 'rest-client'


require 'nokogiri'


require 'base64'


require 'byebug'


require 'csv'




CSV.foreach("list.csv") do |row|


  number = row[0]


  sys_id = row[1].to_s


     


  if !Dir.exists?(number)


      Dir.mkdir(number)


  end



  # Whatever your processor is called


  url = "https://user:password@instance.service-now.com/incidentAttachments.do?sys_id=#password@instance.service-now.com/incidentAttachments.do?sys_id=#{sys_id}"


  xml_doc   = Nokogiri::XML(RestClient::Request.execute(:method => :get, :url => url, :timeout => 3600, :open_timeout => 3600))




  xml_doc.xpath("//attachment").each do |n|


      filename = n.xpath("file_name").first.content


      content = n.xpath("encodedAttachment").first.content



      f = File.new("#{number}//#{filename}", "wb")


      f.write(Base64.decode64(content))


      f.close


  end


end