Adding attachment script in Business Rule

SW7
Giga Guru

Hi Community,

I have a business rule attached that work for updating and creating incident tickets over API to external 3rd party, but I am now trying to add to the business rule the capture and sending of attachments, whenever there is an attachment. 

I successful created a test update and get and post of the attachments from Postman (with help of the document that Muhammad had previously sent through "HackLab") however was unsure of how to fit the script and which bits of script to add from the document

, however I am not sure of the JSON script i should be writing to be able get and send the attachments over externally from the business rule.

Just need to add to the business rule (not take away anything because it works fine for creating / updating of incidents) 

Any help much appreciated

Thanks

Steve

 

1 ACCEPTED SOLUTION

I am glad that you got it working. 

 

Just for your information, In case if you need to hit different endpoints based on Insert or update then you can create a script include reusable utility and from BR you can use

current.insert() & current.update() methods to check the operation and based on that you can call your script include passing in dynamic data. I hope this will help you in the future. 

Have a nice day 🙂 

Thanks & Regards,

Sharjeel

Regards,
Muhammad

View solution in original post

40 REPLIES 40

MrMuhammad
Giga Sage

Hi SW,

Attachments are stored in sys_attachment table with following details.

  • FileName
  • Content-Type
  • Table Name (name of table on which attachment is attached)
  • Table Sys_id (store the sys_id of record on which attachment is attached)

In order to send attachment to anther instance we first need to get the sys_id of target record on the target instance. In my case when I make post call to send incident data I receive back sys_id that I stored in Correlation ID. Right after that I checked for any attachments and using that sys_id I make another call to send attachment. To avoid duplicate attachments being send I created true/false field on attachment table and I flipped the value of field to true for each attachment successfully sent.

Below is the utility that will do send the attachment for you. If you are using script include and BR then place below function in your script include and call it from BR. This call only be made once you have sys_id of target record.

it takes three parameters. 

  • SourceTable - Name of table in the source instance.
  • SourceID - Sys ID of Source Record on which attachment is attached
  • targetID - sys_id of target record that we must already stored. (I already explain above how I stored this). 

sample call - sendAttachments('incident', current.sys_id, current.correlation_id);

The script will return you an array of total count of successful and rejected attachments on the index 0 & 1 respectively. You can leverage that to keep a check of success and failure. 

	// Send Attachment method
		sendAttachments : function(sourceTable, sourceID, targetID) {
			var answer = [0, 0]; //successful attachments, failed attachments
			
			// Query for any attachments on the current record.
			var attachmentRec = new GlideRecord("sys_attachment");
			attachmentRec.addEncodedQuery('u_attached=false^table_name=incident^table_sys_id='+sourceID);
			attachmentRec.query();
			gs.log("--> "+attachmentRec.getRowCount());
			if (attachmentRec.hasNext()) {
				while (attachmentRec.next()) {
					var attachmentMessage = new sn_ws.RESTMessageV2();
					attachmentMessage.setHttpMethod("post");
					attachmentMessage.setAuthenticationProfile('basic', '<sys_id_of_basic_auth_credentials>');
					attachmentMessage.setEndpoint("instance_url.com/api/now/attachment/file");
					attachmentMessage.setQueryParameter("table_name", attachmentRec.table_name);
					attachmentMessage.setQueryParameter("table_sys_id", targetID);
					attachmentMessage.setQueryParameter("file_name", attachmentRec.file_name);
					attachmentMessage.setRequestHeader("Content-Type", attachmentRec.content_type);
					attachmentMessage.setRequestHeader("Accept", "application/json");
					attachmentMessage.setRequestBodyFromAttachment(attachmentRec.sys_id);
					
					var response = attachmentMessage.execute();
					var responseBody = response.getBody();
					
					var httpStatus = response.getStatusCode();
					gs.log("=== "+ httpStatus);
					if (httpStatus.toString() == "201") {
						
						answer[0] += 1;
						attachmentRec.u_attached = 'true';
						attachmentRec.update();
						
					} else {
						answer[1] += 1;
					}
				}
			} else {
				answer = "none";
			}
			return answer;
		},
		

 

Note: please make sure to add instance URL, credentials in the above script and create a u_attached (true/false) field on the attachment table for successful result. 

 

Please mark my response as Correct & helpful if it answered your question.

 

Thanks & Regards,
Sharjeel

 

Regards,
Muhammad

Sharjeel,

Thank you for your information, can you please explain how you store the sys id in the correlation ID? 

Trying to understand step by step how i can use this to complete the sending of attachments for incident record.

Any further help is much appreciated (its giving me a headache this challenge)!

Many thanks

Steve

Hi Steve,

 

Sorry for delayed responses. Its super busy week. 

 

Lets do this step by step. we will handle attachments at the end. As of now we should be focused on storing sys_id of the target record.

There are couple of ways you can store sys_id of target record.

  • When you make rest call to send over incident data to target instance, you will receive response back in JSON format. In the JSON you will find sys_id that you need to store in Co-orelation field of the incident record.

    In your script JSON will return in responseBody object in the below line. you will need to parse JSON and extract sys_id.
    var responseBody = response.getBody();​
  • If you are using Web service(staging table and Transform map) then the approach will be little different. When you make a call and create incident on other side then from the target incident After Insert/update BR will execute and send back the sys_id of the record created into the Source incident on the source instance. 

Once you are done we will move onto next step of pushing attachments. Let me know if you face any issues. 

 

Thanks & Regards,

Sharjeel

Regards,
Muhammad

Sharjeel,

Thank you so much for your email and for following up. Thank you for the breakdown.

Can I get the sys_id you mentioned if the external party populates the correlation id field within our servicenow instance with their ticket number?  If yes then how would I then be able to use this in my business rule i.e. use it to reference the correlation Id's (incident Ticket number)?

The only response being sent back when we log a ticket in their system will be the correlation ID number of the external organisations incident ticket number.

I am using a business rule to currently trigger the posting of the ticket in their system. 

Thanks

Steve