AttachmentCreator SOAP 웹 서비스

  • 릴리스 버전: Xanadu
  • 업데이트 날짜 2024년 08월 01일
  • 읽기12분
  • ecc_queue 테이블을 대상으로 하는 SOAP 메시지를 전송하여 ServiceNow의 기록에 문서를 첨부합니다.

    중요사항:
    AttachmentCreator SOAP 웹 서비스는 권장되지 않습니다. 대신 REST 첨부 파일 API 를 사용하여 웹 서비스로 첨부 파일을 관리합니다.
    AttachmentCreator SOAP 웹 서비스를 사용하면 메시지에 최대 5MB의 단일 문서를 첨부할 수 있습니다. 다음은 URL 또는 대상 엔드포인트의 예입니다. https://instance_name.service-now.com/ecc_queue.do? WSDL (영문)
    표 1. 첨부 파일 작성을 위한 필드 ecc_queue
    필드 이름 설명
    에이전트 요청을 전송하는 에이전트의 이름으로, 처리에 사용되지 않으므로 모든 값이 될 수 있습니다. 첨부 파일 작성자
    주제 첨부 파일 생성을 트리거하려면 큐 기록의 주제, 이 값을 "AttachmentCreator"로 설정해야 합니다. 첨부 파일 작성자
    이름 이 필드에는 파일 이름의 ":"로 구분된 값과 해당 컨텐츠 유형이 포함되어야 합니다. file_name.xls:application/vnd.ms-excel
    소스 이 필드에는 대상 테이블과 해당 테이블의 ":"로 구분된 값이 포함되어야 sys_id 사건:dd90c5d70a0a0b39000aac5aee704ae8
    페이로드 이 필드에는 첨부할 객체를 나타내는 Base 64 인코딩 문자열이 포함되어야 합니다. Base 64 인코딩 문자열

    위 테이블에 설명된 값을 전송하면 sys_id dd90c5d70a0a0b39000aac5aee704ae8에 있는 기록의 인시던트 테이블에 Excel 파일이 첨부됩니다.

    보안

    플랫폼에서 사용할 수 있는 다른 모든 HTTP 기반 웹 서비스와 마찬가지로 AttachementCreator SOAP 웹 서비스는 기본적으로 기본 인증을 사용하여 인증해야 합니다. 인증에 사용되는 사용자 ID는 대화형 사용자와 동일한 방식으로 액세스 제어를 받습니다.

    첨부 파일을 만들려면 SOAP 사용자에게 첨부 파일 [sys_attachment] 기록을 만드는 데 필요한 역할과 soap_create 역할, 그리고 인시던트 기록에 첨부 파일을 추가하는 itil 역할과 같이 대상 테이블에서 기록을 읽고 쓰는 데 필요한 모든 역할이 있어야 합니다. 기본적으로 첨부 파일을 추가할 수 있는 단일 역할은 없습니다. 첨부 파일 추가를 명시적으로 허용하는 역할을 만든 다음 이 역할을 SOAP 사용자에게 할당할 수 있습니다.

    파일 형식 보안

    glide.security.file.mime_type.validation 속성을 설정하여 glide.attachment.extensions 사용자가 첨부할 수 있는 파일 형식을 제어할 수 있습니다.

    이러한 속성을 AttachmentCreator 웹 서비스에 적용하려면 속성을 glide.attachment.enforce_security_validation true로 설정해야 합니다. 이 속성은 기본적으로 true입니다.

    예제 SOAP 메시지

    다음은 mime-type: text/plain의 텍스트 파일 "john1.txt"을 가져와서 GUID가 e6eed6950a0a3c59006f32c8e3ff3cf9인 인시던트에 첨부하는 SOAP 메시지의 예입니다. 페이로드는 파일 자체의 base64 인코딩입니다.
    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ecc="http://www.service-now.com/ecc_queue">
        <soapenv:Header />
        <soapenv:Body>
            <ecc:insert>
                <agent>AttachmentCreator</agent>
                <topic>AttachmentCreator</topic>
                <name>john1.txt:text/plain</name>
                <source>incident:e6eed6950a0a3c59006f32c8e3ff3cf9</source>
                <payload>SSB3b25kZXIgaWYgc2hlIGtub3ducyB3aGF0IHNoZSdzIGRvaW5nIG5vdy4K</payload>
            </ecc:insert>
        </soapenv:Body>
    </soapenv:Envelope>

    스크립트 Node.js 예

    다음 예시 Node.js 스크립트는 인시던트 기록에 첨부 파일을 추가합니다. 인스턴스가 아닌 클라이언트 컴퓨터에서 이 스크립트를 실행합니다.
    /**
     * 
     * Node.js to ServiceNow attachment upload via SOAP
     * 
     * Andrew Venables andrew.venables@servicenow.com
     * July 2014
     * 
     * Version 1.0
     * 
     */
    
    var soap = require('soap'), // https://github.com/vpulim/node-soap
    	mime = require('mime'), // https://github.com/broofa/node-mime
    	fs = require("fs");
    
    var WSDL_FILENAME = 'ecc_queue.xml'; // Goto https://instancename.service-now.com/ecc_queue.do?WSDL and save a copy of the WSDL locally for simplicity
    var DIRECTORY_CONTAINING_FILES = '/Users/andrew.venables/Documents/Uploads'; // Local path to the directory containing all the files we want to upload
    var USERNAME = 'andy.venables'; // An admin user account on the instance
    var PASSWORD = 'MY_PASSWORD'; // Password for above account
    var TARGET_TABLE = 'incident'; // Target table to attach the files to
    var TARGET_SYS_ID = '9d385017c611228701d22104cc95c371'; // Target record / sys_id to attach the files to. OOTB INC0000002
    
    var files_to_upload; // Global that will contain our list of files to be uploaded
    var pos = 0; // Global pointer for our position in the files_to_upload list
    
    // Create a SOAP client to use to post to the instance
    soap.createClient(WSDL_FILENAME, function(err, client) { // Node uses callbacks
    	if (err) console.error(err);
    	
    	// Set the username and password
    	client.setSecurity(new soap.BasicAuthSecurity(USERNAME, PASSWORD));
    	
    	// Read all the files in our source directory, will include . and ..
    	files_to_upload = fs.readdirSync(DIRECTORY_CONTAINING_FILES);
    	
    	console.log('Files to upload: ' + files_to_upload.length + '\n');
    	
    	// Start iterating through the list of files to upload
    	next(client);
    		
    });
    
    // Process the next file in the files_to_upload array
    // This is a neat way of dealing with Node and its expectation of callbacks
    function next(client) {
    	
    	// Check we haven't reached the end
    	if (pos >= files_to_upload.length) return;
    	
    	// Get the next file to upload
    	var file_name = files_to_upload[pos];
    	
    	// Increment the pointer to the next file
    	pos++;
    	
    	console.log(pos + '/'+ files_to_upload.length+ ' - Uploading file: ' + file_name);
    
    	// A blank file is the end of the list
    	if (file_name == '') return;
    	
    	// Skip to the next file as this one is invalid
    	if (file_name == '.' || file_name == '..' || file_name.indexOf('.') == 0) 
    		next(client);
    	
    	// Get the file type using an module called mime
    	var file_type = mime.lookup(file_name);
    	console.log('   of type: ' + file_type);
    	
    	var file_payload;
    	// Load the file into a buffer
    	fs.readFile(DIRECTORY_CONTAINING_FILES + '/' + file_name, function(err, the_data) {
    		if (err) console.error(err);
    		
    		// Encode the buffer to base64
    		file_payload = new Buffer(the_data, 'binary').toString('base64');
    		
    		// Set the parameters before we call the Web Service
    		var parameters = {
    			'agent': 	'AttachmentCreator',
    	        'topic': 	'AttachmentCreator',
    	        'name': 	file_name+':'+file_type,
    	        'source': 	TARGET_TABLE+':'+TARGET_SYS_ID,
    	        'payload': 	file_payload
    		};
    		
    		console.log('      sending...')
    		// Make the Web Service call, remember node likes callbacks
    		client.insert(parameters, function(err, result) {
    			if (err) console.error(err);
    			
    			console.log(result);
    			
    			// This file is done, next!
    			next(client);
    		});
    	});
    }

    예제 Perl 스크립트

    다음 예시 Perl 스크립트는 인시던트 기록에 첨부 파일을 생성합니다.
    use MIME::Base64;
    use strict;
    use SOAP::Lite;
     
    # the ServiceNow instance
    my $SNC_HOST = "https://instance_name.service-now.com";
    my $base64;
    my $buf;
     
    # upload and attach a file on the local disk, base 64 encode it into a string first
    open(FILE, "/Users/davidloo/Desktop/test_files/number_test.xls") or die "$!";
    binmode FILE; #preserves file formatting on Windows
    while (read(FILE, $buf, 60*57)) {
      $base64 .= encode_base64($buf);
    }
     
    # call the sub routine to attach
    attach_incident();
     
    sub attach_incident {
      # target the ecc_queue table
      my $soap = SOAP::Lite->proxy("$SNC_HOST/ecc_queue.do?SOAP");
      $soap->{_transport}->{_proxy}->{ssl_opts}->{verify_hostname} = 0;
      my $method = SOAP::Data->name('insert')->attr({xmlns => 'http://www.service-now.com/'});
     
      # set the ecc_queue parameters
      my @params = (SOAP::Data->name(agent => 'AttachmentCreator'));
      push(@params, SOAP::Data->name(topic => 'AttachmentCreator') );
     
      # identify the file name and its mime type
      push(@params, SOAP::Data->name(name => 'number_test.xls:application/vnd.ms-excel') );
     
      # attach to the incident, specifying its sys_id
      push(@params, SOAP::Data->name(source => 'incident:dd90c5d70a0a0b39000aac5aee704ae8') );
     
      # set the payload to be the base 64 encoded string representation of the file
      push(@params, SOAP::Data->name(payload => $base64) );
     
      # invoke the web service
      my $result = $soap->call($method => @params);
     
      print_fault($result);
     
      print_result($result);
    }
     
    sub print_result {
      my ($result) = @_;
     
      if ($result->body && $result->body->{'insertResponse'}) {
        my %keyHash = %{ $result->body->{'insertResponse'} };
        foreach my $k (keys %keyHash) {
            print "name=$k   value=$keyHash{$k}\n";
        }
      }
    }
     
    sub print_fault {
      my ($result) = @_;
     
      if ($result->fault) {
        print "faultcode=" . $result->fault->{'faultcode'} . "\n";
        print "faultstring=" . $result->fault->{'faultstring'} . "\n";
        print "detail=" . $result->fault->{'detail'} . "\n";
      }
    }
     
    # use the itil user for basic auth credentials
    sub SOAP::Transport::HTTP::Client::get_basic_credentials {
       return 'itil' => 'itil';
    }