logo

NJP

Export a record attachment to a mid server's export folder

Import · Sep 10, 2020 · article

We found that ServiceNow's scheduled exports are great for table data, but the very first NOTE for export sets- "Export sets do not export attachments to records. To download an attachment, either use the REST Attachment API (HTTP request originates from a third-party HTTP client), or use the outbound REST Message module to send the attachment from the instance (HTTP request originates from the instance)." In many cases a simple REST call would be used but for our use-case we found that our internal systems and schedulers were a bit more locked down and using REST really wasn't an option. They could, however access internal servers - such as a MID server.

We then examined the scheduled export process and found it could actually be used to export attachments. We just couldn't use the OOB process, so instead we created a simple function. It uses all the same core components and methods that scheduled exports uses, but works on demand and exclusively with attachments.

EDIT: This also works for dropping the file(s) into a specific folder path within the mid servers export folder. You can add a new function variable such as export_folder and then modify xmlString variable (ie: '<stream_relay_sink path="\/' + export_folder + '\/' + new_attachment_name + '" type=\"FileSink\"/>' ).

/* exportToMid - Function to export a *specific* attachment to a mid servers
*  export folder. 
*
*  Usage: exportToMid("my_file_to_export.pdf", "incident", "12345678910111213", "MIDSERVER001")
*
*  @param attachment_name {string} - Specific attachment file name
*  @param attached_table {string} - Table the file is attached
*  @param attached_record {sys_id} - SYS_ID of the record the file is attached
*  @param mid_name {string} - MID Server name
*  @return {null}
*/
function exportToMid(attachment_name, attached_table, attached_record, mid_name) {
    /** TODO: Add Error Control and validation **/

    // Create ECC attachment record used to send the file to the mid server
    var ecc_att = new GlideRecord('ecc_agent_attachment');
    ecc_att.initialize();
    ecc_att.name = 'Export Set Attachment';
    ecc_att.short_description = 'exportToMid: ' + attachment_name;
    ecc_att.insert();

    // Copy attachments (OOB Function copies all attachments)
    GlideSysAttachment.copy(attached_table,attached_record,'ecc_agent_attachment',ecc_att.sys_id);

    // Get the SYS_ID of the exact attachment file to be exported and used in ECC Payload
    var at = new GlideRecord('sys_attachment');
    at.addQuery('table_name', 'ecc_agent_attachment');
    at.addQuery('table_sys_id', ecc_att.sys_id);
    at.addQuery('file_name', attachment_name);
    at.query();
    at.next();


    // Create XML for ECC Payload
    var xmlString = '<?xml version="1.0" encoding="UTF-8"?>' + 
                    '<parameters>' +
                    '<parameter name=\"stream_relay_response_topic\" value=\"ExportSetResult\"/>' +
                    '<stream_relay_source attachment_sys_id=\"' + at.sys_id + '\" type=\"AttachmentSource\"/>' +
                    '<stream_relay_transform attachment.table_sys_id=\"' + ecc_att.sys_id + '\" order=\"0\" stream_relay_transfer_progress_interval=\"150\" type=\"AttachmentProgressTransformer\"/>' +
                    '<stream_relay_sink path="\/' + attachment_name + '\" type=\"FileSink\"/>' +
                    '</parameters>';


    // Create ECC Record
    var eccQueue = new GlideRecord('ecc_queue');
    eccQueue.initialize();
    eccQueue.agent = 'mid.server.' + mid_name;
    eccQueue.topic = 'StreamPipeline';
    eccQueue.queue = 'output';
    eccQueue.state = 'ready';
    eccQueue.payload = xmlString;
    eccQueue.insert();
}
View original source

https://www.servicenow.com/community/developer-articles/export-a-record-attachment-to-a-mid-server-s-export-folder/ta-p/2298652