- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 07:13 AM
Hi All,
I need to download files attached to any incident using REST API.
I will be sending incident detail from my postman.
Already Referred to attachment api reference docs but could'nt find a solution.
NOTE: I don't have the option to use ui action
Is this doable?
Thanks in Advance!
Solved! Go to Solution.
- Labels:
-
Scripting and Coding

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2020 02:32 AM
I'm executing python script from the command line.
I may be missing some steps below but the general way to install python is as follows.
1. Install python
https://phoenixnap.com/kb/how-to-install-python-3-windows
2. Create subdirectory
mkdir servicenowapis
3. Move to the subdirectory
cd servicenowapis
4. Create a virtualenv
python-m venv venv
5. Activate venv
venv\Scripts\activate.bat
6. Install request module
pip install requests
7. Copy the script I've provided to the directory
8. Copy and paste content of Constants.py over import statements
9. Edit username, password
9. Edit table_api.py to use Incident number
e.g.
get_file_attachment('INC0000002')
10. Execute command
python test_api.py
import requests
SERVICENOW_URL = 'https://<instance>.service-now.com'
SERVICENOW_USER = '<username>'
SERVICENOW_PWD = '<password>'
DOWNLOAD_DIR = './downloads/'
REQUEST_HEADER = {"json": {"Content-Type": "application/xml", "Accept": "application/json"},
"png": {"Content-Type": "application/xml", "Accept": "application/png"},
"xml": {"Content-Type": "application/xml", "Accept": "application/xml"},
}
ATTACHMENT_API = '/api/now/attachment'
TABLE_API = '/api/now/table'
# TABLE_NAME = 'kb_knowledge'
TABLE_NAME = 'incident'
def get_table_data(table_name, param):
url = SERVICENOW_URL + TABLE_API + '/' + table_name + '?' + param
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
return response.json()
def get_attachment_info(sys_id):
url = SERVICENOW_URL + ATTACHMENT_API + '/' + sys_id
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print(f'Status: {response.status_code}, Headers:{response.headers}')
exit()
return response.json()
def get_attachment(att_sys_id, file_type, download_dir):
url = SERVICENOW_URL + '/' + ATTACHMENT_API + '/' + att_sys_id + '/file'
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get(file_type))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
with open(download_dir, 'wb') as f:
for chunk in response:
f.write(chunk)
def get_file_attachment(record_number):
param = 'sysparm_query=number=' + record_number + '&sysparam_limit=1'
file_info = get_table_data(TABLE_NAME, param).get('result')
if len(file_info) < 1:
print(f'There is no attachment to sys_id:{record_number}')
return
attachment_sys_id = file_info[0].get('sys_id')
param = 'sysparm_query=table_sys_id=' + attachment_sys_id + '&sysparam_limit=1'
kb_attachments = get_table_data('sys_attachment', param)
result = kb_attachments.get('result')
for attach_file in result:
attach_sys_id = attach_file.get('sys_id')
content_type = attach_file.get('content_type').split('/')
file_ext = content_type[1]
file_name = attach_file.get('file_name')
get_attachment(attach_sys_id, file_ext, DOWNLOAD_DIR + file_name)
if __name__ == '__main__':
# get_file_attachment('KB0010062') # knowledge base number
get_file_attachment('INC0000002')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 07:35 AM
Hi,
please find my points below
APIs are only used to retrieve the data from the instance. It will not download the attachment directly, using API you can get the url of the attachment and when you clicked on the URL it will download the file once you give the credentials.
Otherwise use the binary code returned by the API to convert into the attachment file and download into the system from where this API has been called.
Regards
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
09-24-2020 01:18 AM
Hi Ankur,
Thanks for the response.
From where will i get the binary code ? Do i need to encode the attachment file from sys_attachment table in scripted rest api and return the encoded data back?
Also, in first point how can I retrieve the url of the attachment ? Because when i click on any record in sys_attachment table the file gets auto downloaded.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2020 02:01 AM
just checked the docs but didn't find any such API.
I believe it is not possible to get binary data from attachments in ServiceNow directly.
You can only get a string that represents binary, but not actual binary object.
The scripted rest api approach can be considered: Not tested though
1) the scripted REST API will accept example INC number
2) it would then query sys attachment and get the binary data
3) then send the binary data in the API response
Regards
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
09-28-2020 12:12 AM
Hi Ankur,
Tried this way bit it's not working. Can you let me know if anything needs to be added.
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var queryParams = request.queryParams;
var queryRITM = queryParams.number;
var gr = new GlideRecord('sc_req_item');
gr.addQuery('number', queryRITM);
gr.query();
while (gr.next()) {
var ga = new GlideRecord('sys_attachment');
ga.addQuery('table_sys_id', gr.sys_id);
ga.query();
while (ga.next()) {
var attachsysid = ga.sys_id;
var filename = ga.file_name;
var StringUtil = new GlideStringUtil();
var gsais = GlideSysAttachmentInputStream(attachsysid.toString());
var byteArray = new Packages.java.io.ByteArrayOutputStream();
gsais.writeTo(byteArray );
var byteArray1= new Packages.java.io.ByteArrayOutputStream();
var base64EncodedData = StringUtil.base64Encode(byteArray1.toByteArray());
return base64EncodedData;
// writer.writeStream(base64EncodedData);
}
}
})(request, response);