is there any way to write onBefore insert business rule that convert the attachment to base64

Alon Grod
Tera Expert

Hi,

 

is there any way to write onBefore insert business rule on the sys_attachment table that convert the attachment to base64 ? i was able to achieve it if its onAfter but not onBefore

2 REPLIES 2

Abhishek Pal
Mega Guru

Hi @Alon Grod ,

No, I would not use a Before Insert Business Rule for this requirement.

The reason your code works in After but not in Before is expected.

When an attachment is uploaded, ServiceNow stores:

sys_attachment
-> Attachment metadata

sys_attachment_doc
-> Actual file content stored in chunks

A Before Insert Business Rule on sys_attachment runs before the attachment record has completed its database operation. At that point, there is no supported guarantee that the actual attachment content is available for GlideSysAttachment to read.

Therefore:

Before Insert
-> Attachment content may not yet be available
-> Base64 conversion is not reliable

After / Async Insert
-> Attachment has been created
-> Content can be retrieved
-> Base64 conversion can be performed

Recommended approach:

Use an Async Business Rule.

Configuration:

Table:
Attachment [sys_attachment]

When:
Async

Insert:
True

Add a condition so that it runs only for the required table or attachment type.

Example:

(function executeRule(current, previous) {

var attachment = new GlideRecord('sys_attachment');

if (!attachment.get(current.getUniqueValue())) {
gs.error(
'Attachment not found: ' +
current.getUniqueValue()
);
return;
}

try {

var gsa = new GlideSysAttachment();

var base64 =
gsa.getContentBase64(attachment);

if (!base64) {
gs.error(
'Unable to retrieve attachment content: ' +
attachment.getUniqueValue()
);
return;
}

// Pass the Base64 value to your reusable
// Script Include / integration logic here.

// Example:
// new x_your_scope.AttachmentIntegration()
// .sendAttachment(
// attachment.getUniqueValue(),
// base64
// );

} catch (ex) {

gs.error(
'Attachment Base64 conversion failed: ' +
ex.message
);
}

})(current, previous);

Important:

getContentBase64() is available in scoped applications and returns up to 5 MB of attachment data.

If this is being implemented in Global scope, getContentBase64() is not supported there.

Also, if your actual requirement is to send the attachment to an external REST API, I would avoid converting it to Base64 unless the receiving API specifically requires Base64.

For a binary REST upload, ServiceNow provides:

request.setRequestBodyFromAttachment(
attachmentSysId
);

This avoids the additional memory and payload overhead caused by Base64 encoding.

Recommended architecture:

Attachment uploaded
-> sys_attachment created
-> Async Business Rule
-> GlideSysAttachment
-> Base64 conversion if required
-> Script Include / Integration

Do not use:

Before Insert
-> Base64 conversion

Also avoid:

- Reading sys_attachment_doc directly
- Concatenating attachment chunks manually
- Logging the Base64 content
- Storing large Base64 strings permanently in a field
- Running an external integration synchronously during attachment upload

So your After solution is behaving correctly. For production, I would move the processing to Async rather than trying to make Before Insert work.

Official references:

GlideSysAttachment:
https://www.servicenow.com/docs/r/api-reference/server-api-reference/c_GlideSysAttachmentScopedAPI.h...

Attachment architecture:
https://www.servicenow.com/docs/r/platform-administration/attachments.html

Business Rule execution timing:
https://www.servicenow.com/docs/r/application-development/business-rules-and-script-includes.html

Hope this helps!

If this response helped, please mark it as Helpful.
If it resolves your issue, please Accept it as Solution.

Kind Regards,
Abhishek Pal

Me Being Mustaq
Kilo Sage

Hi @Alon Grod ,

 

No, not reliably.

The reason is that an onBefore Insert Business Rule on sys_attachment executes before the attachment content has been fully written to sys_attachment_doc. At that point, you have the attachment metadata (file name, table, content type, etc.), but the actual binary data chunks are not yet available.

 

An onBefore Insert BR on sys_attachment cannot consistently convert the attachment to Base64 because the file contents have not been stored yet. If you need the actual file bytes, use:

  • onAfter Insert on sys_attachment (best option), or
  • a process on sys_attachment_doc once the attachment chunks exist.

That's why you're seeing it work in onAfter but not in onBefore.

 

Warm Regards,

Shaik Mustaq.