Synchronize attachment deletions

Hi, I’m trying to update the attachments from one side to another, this is done, but now what I need is that if an user remove something from serviceNow, it will removed from Jira and viceversa. The Support team is telling me that it is not a native function from exalate and that I need a custom script I’ve trying some but no luck, could you help me with this?

hey @Juan_Manuel_Alarcon !
@Tomas_Lalanne here, we do have a native function that supports your use case

MergeAttachments works for Jira Cloud, Azure DevOps, Jira on-premise, Zendesk and ServiceNow, and will add or remove attachments depending on the replica

So on both ends incoming script, you should have

issue.attachments = attachmentHelper.mergeAttachments(issue, replica)

And leave the outgoing as default

replica.attachments = issue.attachments

BR
Tomas

Hi Tomas, I’ve used this and doesn’t work

Hi @Juan_Manuel_Alarcon

is it giving you any error ? or is it something just not working ?

one quick question:

the connection is between servicenow and jira cloud or jira on-prime ?

Thanks,

Sonal

Hi @Sonal_Otwani no error, just when I delete the file on Jira cloud it keeps it on ServiceNow

Mi connection is between Jira cloud and ServiceNow

Hi @Juan_Manuel_Alarcon !

We have already raised a BUG about this matter as the script should work as intended

// 1. Add any new attachments from the source.
if (replica.addedAttachments) {
    entity.attachments += replica.addedAttachments
}

// 2. Get the list of attachments that were removed on the source.
def attachmentsToDelete = replica.getRemovedAttachments()

// 3. If there are attachments to delete, loop through and delete each one.
if (attachmentsToDelete) {
    attachmentsToDelete.each { attachment ->
        // Use .idStr to get the sys_id as a String, as suggested by the error log.
        def attachmentSysIdToDelete = attachment.idStr

        if (!attachmentSysIdToDelete) {
            // This case should be rare, but it's here for safety.
            return
        }
        
        try {
            // Construct the DELETE request path.
            def deleteApiPath = "/api/now/attachment/${attachmentSysIdToDelete}"
            
            // Prepare headers for the DELETE request.
            def requestHeadersForDelete = [ "Accept": ["application/json"] ]

            // Perform the DELETE request.
            httpClient.http(
                "DELETE",
                deleteApiPath,
                null,
                [:],
                requestHeadersForDelete
            ) { request, response ->
                if (response.code == 204) {
                    log.info("Successfully deleted attachment (sys_id: ${attachmentSysIdToDelete}).")
                } else {
                    log.error("Failed to delete attachment with sys_id ${attachmentSysIdToDelete}. Status: ${response.code}, Response: ${response.body}")
                }
            }

        } catch (e) {
            log.error("An exception occurred during the deletion of attachment sys_id ${attachmentSysIdToDelete}: ${e.message}", e)
        }
    }
}

BR

Tomas