Use PDIs? Take our 5-minute survey to help shape the PDI roadmap.

How to copy attachment to another record

Alon Grod
Tera Expert

Hi,

How can I copy an attachment to specific record with two changes:

No need the ZZ_YY
I want to change the file name on the target record

AlonGrod_0-1785937908345.png

 



4 REPLIES 4

Abhishek Pal
Giga Guru

Hi @Alon Grod ,

Do not update sys_attachment.table_name, table_sys_id, or sys_attachment_doc directly.

The ZZ_YY prefix is commonly used for attachment-variable or temporary attachment records. When copying the file, attach it to the actual target GlideRecord using GlideSysAttachment. The new attachment will use the target table name without ZZ_YY.

GlideSysAttachment.copy() is not suitable when you need to rename a specific file because it preserves the original filename and may copy all attachments from the source record.

Use getContentStream() and writeContentStream():

function copyAttachmentWithRename(
sourceAttachmentSysId,
targetTable,
targetRecordSysId,
newFileName
) {
if (!sourceAttachmentSysId || !targetTable ||
!targetRecordSysId || !newFileName) {
throw 'Missing required attachment parameters.';
}

var sourceAttachment = new GlideRecord('sys_attachment');

if (!sourceAttachment.get(sourceAttachmentSysId)) {
throw 'Source attachment was not found: ' +
sourceAttachmentSysId;
}

var targetRecord = new GlideRecord(targetTable);

if (!targetRecord.get(targetRecordSysId)) {
throw 'Target record was not found: ' +
targetTable + ' - ' + targetRecordSysId;
}

// Preserve the original extension when the new name has no extension.
var originalFileName =
sourceAttachment.getValue('file_name') || '';

if (newFileName.indexOf('.') == -1) {
var extensionPosition = originalFileName.lastIndexOf('.');

if (extensionPosition > -1) {
newFileName += originalFileName.substring(
extensionPosition
);
}
}

var attachmentApi = new GlideSysAttachment();
var inputStream = attachmentApi.getContentStream(
sourceAttachmentSysId
);

var newAttachmentSysId =
attachmentApi.writeContentStream(
targetRecord,
newFileName,
sourceAttachment.getValue('content_type'),
inputStream
);

if (!newAttachmentSysId) {
throw 'The attachment could not be copied.';
}

return newAttachmentSysId;
}

Example:

var newAttachmentSysId = copyAttachmentWithRename(
'SOURCE_ATTACHMENT_SYS_ID',
'TARGET_TABLE_NAME',
'TARGET_RECORD_SYS_ID',
'new_file_name.png'
);

gs.info(
'New attachment created: ' + newAttachmentSysId
);

This creates a new attachment with:

- The same file content
- The same content type
- The new filename
- The actual target table and record
- No ZZ_YY prefix on the target attachment

Delete the source attachment only after confirming that the new attachment was created successfully:

new GlideSysAttachment().deleteAttachment(
'SOURCE_ATTACHMENT_SYS_ID'
);

Only perform the deletion when the requirement is to move the attachment rather than copy it.

For a user-triggered implementation, also validate that the user has access to both the source attachment and the target record before executing the copy.

Official reference:

https://www.servicenow.com/docs/r/api-reference/server-api-reference/GlideSysAttachmentGlobalAPI.htm...

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

Tejas Adhalrao
Kilo Sage

hi @Alon Grod  ,

you can create the flow to copy attachemnt and add trigger condtion and select valeues like table and record

TejasAdhalrao_0-1785945864618.png

and once you copy attchemnt you can update rhe attachemnt record using update record floe action

TejasAdhalrao_1-1785946013626.png

 

 

If this helped, please mark it as Helpful. If it resolved your issue, please mark it as the Accepted Solution.

 

 

Ankur Bawiskar
Tera Patron

@Alon Grod 

what's the business requirement?

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader

yashkamde
Giga Sage

Hello @Alon Grod ,

 

Copy the attachment using GlideSysAttachment.copy(), then rename the file on the new attachment record :

var attGr = new GlideRecord('sys_attachment');
if (attGr.get(sourceAttachmentSysId)) {
    var newSysId = new GlideSysAttachment().copy(
        attGr.getValue('table_name'),
        attGr.getValue('table_sys_id'),
        targetTable,      // e.g. 'sn_cd_content_portal' (no ZZ_YY)
        targetSysId
    );

    var newAtt = new GlideRecord('sys_attachment');
    if (newAtt.get(newSysId)) {
        newAtt.setValue('file_name', newAtt.getValue('file_name').replace(/^ZZ_YY/, ''));
        newAtt.update();
    }
}

 

If my response helped mark as helpful and accept the solution.