Business rule for attachments not triggering from email updating the incident

WillZ1880654930
Tera Contributor

I have an async BR that runs when a record gets inserted in the sys_attachment table.  The BR works fine when I add an attachment to the incident ticket manually, but it does not trigger when an email updates the ticket with an attachment.  I did confirm the incident record did get a new attachment and the sys_attachment record table name listed it as "incident".

1 ACCEPTED SOLUTION

Vikram Reddy
Tera Guru

Hey @WillZ1880654930,

 

This isn't your business rule misbehaving, it's documented platform behavior. ServiceNow KB2208821 covers this exact scenario: an After/Insert business rule on sys_attachment does not execute when the attachment record is created through Inbound Action processing, which is the same pipeline that handles files coming in on an inbound email. The row still lands in sys_attachment correctly, that's why you can see table_name = incident on it, but the insert path email processing uses doesn't walk through the scripted business rule engine the same way a manual UI upload does. So your async BR simply never gets invoked for those rows, no matter how the filter condition is written.

// Async "Update" Business Rule on Incident (add a matching one on sc_task)
// When: async, Update

(function executeRule(current, previous) {

    var att = new GlideRecord('sys_attachment');
    att.addQuery('table_name', current.getTableName());
    att.addQuery('table_sys_id', current.getUniqueValue());
    att.orderByDesc('sys_created_on');
    att.setLimit(1);
    att.query();

    if (att.next()) {
        var secondsAgo = gs.dateDiff(att.getValue('sys_created_on'), gs.nowDateTime(), true);
        if (secondsAgo < 30) {
            // attachment landed in this same transaction, run your logic here
        }
    }

})(current, previous);

The idea is to stop listening on sys_attachment and hook into the parent record instead. Inbound email processing still runs an ordinary update on the incident, adding the reply as a comment or work note, after it copies the file over, and that update fires the normal business rule engine without any of the Inbound Action weirdness. Checking for a sys_attachment row created within a few seconds of the transaction is a reliable enough proxy for "an attachment just arrived on this update."

A couple of things worth doing before you rebuild the logic this way:

  • Test a record-triggered Flow on the Attachment [sys_attachment] table first. Flow Designer's record trigger uses a different underlying mechanism than a scripted business rule, and it's a five-minute test to see if it catches what the BR misses. If sys_attachment doesn't show up in the trigger's table picker, add it to the glide.ui.permitted_tables system property (comma-separated list) to expose it.
  • Confirm the incident actually gets updated by the inbound email in your case, not just the attachment copied over silently. If the email only adds the file and nothing else changes on the incident, an Update BR on Incident won't fire either and you'll need the timing-window check above rather than a plain field-change condition.

Since your original filter condition also covers sc_task, don't forget to replicate whichever fix you land on there too, since Inbound Actions for catalog task updates go through the same attachment pipeline.

 

Thank you,
Vikram Karety
Octigo Solutions INC

View solution in original post

5 REPLIES 5

Vikram Reddy
Tera Guru

Hey @WillZ1880654930,

 

This isn't your business rule misbehaving, it's documented platform behavior. ServiceNow KB2208821 covers this exact scenario: an After/Insert business rule on sys_attachment does not execute when the attachment record is created through Inbound Action processing, which is the same pipeline that handles files coming in on an inbound email. The row still lands in sys_attachment correctly, that's why you can see table_name = incident on it, but the insert path email processing uses doesn't walk through the scripted business rule engine the same way a manual UI upload does. So your async BR simply never gets invoked for those rows, no matter how the filter condition is written.

// Async "Update" Business Rule on Incident (add a matching one on sc_task)
// When: async, Update

(function executeRule(current, previous) {

    var att = new GlideRecord('sys_attachment');
    att.addQuery('table_name', current.getTableName());
    att.addQuery('table_sys_id', current.getUniqueValue());
    att.orderByDesc('sys_created_on');
    att.setLimit(1);
    att.query();

    if (att.next()) {
        var secondsAgo = gs.dateDiff(att.getValue('sys_created_on'), gs.nowDateTime(), true);
        if (secondsAgo < 30) {
            // attachment landed in this same transaction, run your logic here
        }
    }

})(current, previous);

The idea is to stop listening on sys_attachment and hook into the parent record instead. Inbound email processing still runs an ordinary update on the incident, adding the reply as a comment or work note, after it copies the file over, and that update fires the normal business rule engine without any of the Inbound Action weirdness. Checking for a sys_attachment row created within a few seconds of the transaction is a reliable enough proxy for "an attachment just arrived on this update."

A couple of things worth doing before you rebuild the logic this way:

  • Test a record-triggered Flow on the Attachment [sys_attachment] table first. Flow Designer's record trigger uses a different underlying mechanism than a scripted business rule, and it's a five-minute test to see if it catches what the BR misses. If sys_attachment doesn't show up in the trigger's table picker, add it to the glide.ui.permitted_tables system property (comma-separated list) to expose it.
  • Confirm the incident actually gets updated by the inbound email in your case, not just the attachment copied over silently. If the email only adds the file and nothing else changes on the incident, an Update BR on Incident won't fire either and you'll need the timing-window check above rather than a plain field-change condition.

Since your original filter condition also covers sc_task, don't forget to replicate whichever fix you land on there too, since Inbound Actions for catalog task updates go through the same attachment pipeline.

 

Thank you,
Vikram Karety
Octigo Solutions INC

Really appreciate the insight here.  I did try flow designer trigger at first but that had the same result and did not pick up the changes in the table.  I ended up with your suggestion on using a gliderecord lookup within the incident BR and I was able to get it to work.  Thanks again!

Tanushree Maiti
Tera Patron

Hi @WillZ1880654930 

 

It might be the case that the Inbound Email Action processing the email or the underlying system processor is using setWorkflow(false) when attaching the file or updating the record. 

 

Following steps - validate once

1.If you are using a custom Inbound Email Action to process the update and attach the file, look closely at the script:

  • Search for any line containing current.setWorkflow(false); or gr.setWorkflow(false);
  • Remove that line or change it to setWorkflow(true) so the system allows downstream Business Rules to execut

2. If the setWorkflow(false) is coming from an OOB  system engine (such as the Email Reader process), async rules can occasionally be skipped during complex background job processing.

  • Change the When to run setting of your Business Rule from async to after.
  • Ensure the operation remains Insert.

3.Using gs.log , try to identify exactly in which line error is throwing inside BR or email action

Please Accept the solution if it assisted you with your question & Mark this response as Helpful.
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti

Alok Gupta5
Tera Guru

Please update the record in your script then it will work. Because record is not getting any trigger like update or insert that's why it is not working