Search code examples
restfileperlpostservicenow

Perl version of this python servicenow script posting a file


So I am going over the Attachment API for ServiceNow, documented here: https://docs.servicenow.com/integrate/inbound_rest/reference/r_AttachmentAPI-POST.html

For an application I'm working on, I need to write up some Perl code to handle attachments. Unfortunately, the ServiceNow Perl API libraries do not handle attachments larger than 5mb, so I need to use the stock Attachment API that comes with the instance.

From the above link, I saw this example on how to post files with this python code.

#Need to install requests package for python
#easy_install requests
import requests

# Set the request parameters
url = 'https://instance.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=d71f7935c0a8016700802b64c67c11c6&file_name=Issue_screenshot.jpg'

# Specify the file To send. When specifying fles to send make sure you specify the path to the file, in
# this example the file was located in the same directory as the python script being executed.
data = open('Issue_screenshot.jpg', 'rb').read()

# Eg. User name="admin", Password="admin" for this code sample.
user = 'admin'
pwd = 'admin'

# Set proper headers
headers = {"Content-Type":"image/jpeg","Accept":"application/json"}

# Do the HTTP request
response = requests.post(url, auth=(user, pwd), headers=headers, data=data)

# Check for HTTP codes other than 201
if response.status_code != 201: 
    print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:',response.json())
    exit()

# Decode the JSON response into a dictionary and use the data
data = response.json()
print(data)

I've used REST::Client a lot for posting, but unfortunately, I can't find a good example on how to handle the above ^^ but in Perl. How does one use REST::Client to post a file like above?

I've done a temp workaround with this by invoking curl in my scripts, but using REST::Client would be more elegant.


Solution

  • You can use LWP::UserAgent Perl module to achieve the same:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use LWP::UserAgent;
    use HTTP::Request;
    use Fcntl;
    use JSON qw[decode_json];
    use Data::Dumper;
    
    my $ua = LWP::UserAgent->new;
    
    my $url = 'https://instance.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=d71f7935c0a8016700802b64c67c11c6&file_name=Issue_screenshot.jpg';
    
    my $user = 'admin';
    my $pwd = 'admin';
    
    $ua->credentials( 'instance.service-now.com', '<REALM>', $user, $pwd);
    
    my $file = 'Issue_screenshot.jpg';
    
    my $request = HTTP::Request->new( POST => $url );
    
    $request->header( 'Content-Type' => 'image/jpeg');
    $request->header( 'Accept' => 'application/json');
    $request->header( 'Content-Length' => -s $file);
    
    sysopen(my $fh,$file,O_RDONLY);
    
    $request->content( sub {
        sysread($fh,my $buf,1024);
    
        return $buf;
    });
    
    my $res = $ua->request($request);
    
    unless($res->code == 201) {
        print 'Status: '.$res->code, 'Headers:',$res->headers_as_string,'Error Response:',$res->content;
        exit;
    }
    
    my $data = decode_json($res->content);
    
    print Dumper($data);