Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Help with scheduled job triggering duplicate emails

dswider
Tera Contributor

Hi everyone, I have a scheduled job script that runs periodically and triggers an eventqueue for a specific record, which sends out an email. I'd like to modify the script so that before the queuing/triggering of the event/email, it checks whether the event has already been triggered for that particular record. If it has, I want to prevent it from being triggered (and emailed) again when the job runs. What's the best way to implement this kind of check?

(function() {
var today = new GlideDate();
var now = new GlideDateTime();

var yesterday = new GlideDate();
yesterday.addDaysLocalTime(-1);

var start = new GlideDateTime();
start.setDisplayValue(yesterday.getByFormat("yyyy-MM-dd") + " 00:00:00");

var inquiryGR = new GlideRecord('x_g_afss_inquiry_inquiries');
inquiryGR.addQuery('sys_created_on', '>=', start);
inquiryGR.addQuery('sys_created_on', '<=', now);
inquiryGR.query();

var count = 0;

while (inquiryGR.next()) {
gs.info('Processing inquiry ' + inquiryGR.getDisplayValue('number'));

// Check if the event has already been triggered by searching in syslog
if (isEventLogged(inquiryGR.getUniqueValue())) {
gs.info('Skipping inquiry ' + inquiryGR.getDisplayValue('number') + ' as event has already been triggered.');
continue;
}

var hasPassbackMatchAttachment = false;

var attachmentGR = new GlideRecord('sys_attachment');
attachmentGR.addQuery('table_name', 'x_g_afss_inquiry_inquiries');
attachmentGR.addQuery('table_sys_id', inquiryGR.getUniqueValue());
attachmentGR.query();

while (attachmentGR.next()) {
var fileName = attachmentGR.getValue('file_name');
if (fileName && fileName.toLowerCase().includes('passback_match')) {
hasPassbackMatchAttachment = true;
break;
}
}

if (hasPassbackMatchAttachment) {
try {
gs.info('Triggering event for inquiry: ' + inquiryGR.getDisplayValue('number'));
gs.eventQueue('x_g_afss_inquiry.bulk_inquiry_attachment', inquiryGR, inquiryGR.getUniqueValue(), '');
gs.info('Event triggered for inquiry: ' + inquiryGR.getDisplayValue('number'));

// Log the event in syslog to mark it as triggered
gs.info('Marking event as triggered for inquiry ' + inquiryGR.getDisplayValue('number'));

// Log a custom entry in the syslog table to track that this event was triggered
var logGR = new GlideRecord('syslog'); // Query syslog table instead of sys_log
logGR.initialize();
logGR.message = 'Event triggered for inquiry: ' + inquiryGR.getDisplayValue('number');
logGR.type = 'info';
logGR.insert();

count++;
} catch (e) {
gs.error('Failed to trigger event for inquiry ' + inquiryGR.getDisplayValue('number') + ': ' + e.message);
}
}
}

gs.info('Finished processing. Total triggered: ' + count);

// Function to check if the event has already been logged in the syslog
function isEventLogged(inquirySysId) {
gs.info('Checking syslog for event for inquiry ' + inquirySysId); // Add debug log to check if we're even reaching here
var logGR = new GlideRecord('syslog'); // Query syslog table
logGR.addQuery('message', 'Event triggered for inquiry: ' + inquirySysId);
logGR.query();

if (logGR.hasNext()) {
gs.info('Event already logged for inquiry ' + inquirySysId); // If log found, log this
return true;
}

return false; // No matching log entry found
}
})();

1 REPLY 1

Community Alums
Not applicable

Instead of checking the syslog table to see if an event was already triggered (which can be unreliable and messy), it’s much cleaner to add a custom field like u_event_triggered on your inquiry table. This field acts as a flag to track whether the scheduled job has already triggered the event for that record. It keeps your data model self-contained, makes the logic easy to understand, and avoids depending on log retention. In your script, simply check this field before sending the event, and after sending, set it to true — this ensures the event runs only once per record, safely and reliably.

If you'd like, I can also draft the update set or field definition for the u_event_triggered field!

 

(function() {
    var today = new GlideDate();
    var now = new GlideDateTime();

    var yesterday = new GlideDate();
    yesterday.addDaysLocalTime(-1);

    var start = new GlideDateTime();
    start.setDisplayValue(yesterday.getByFormat("yyyy-MM-dd") + " 00:00:00");

    var inquiryGR = new GlideRecord('x_g_afss_inquiry_inquiries');
    inquiryGR.addQuery('sys_created_on', '>=', start);
    inquiryGR.addQuery('sys_created_on', '<=', now);
    inquiryGR.query();

    var count = 0;

    while (inquiryGR.next()) {
        gs.info('Processing inquiry ' + inquiryGR.getDisplayValue('number'));

        // Check if event already triggered
        if (inquiryGR.u_event_triggered) {
            gs.info('Skipping inquiry ' + inquiryGR.getDisplayValue('number') + ' - event already triggered.');
            continue;
        }

        var hasPassbackMatchAttachment = false;

        var attachmentGR = new GlideRecord('sys_attachment');
        attachmentGR.addQuery('table_name', 'x_g_afss_inquiry_inquiries');
        attachmentGR.addQuery('table_sys_id', inquiryGR.getUniqueValue());
        attachmentGR.query();

        while (attachmentGR.next()) {
            var fileName = attachmentGR.getValue('file_name');
            if (fileName && fileName.toLowerCase().includes('passback_match')) {
                hasPassbackMatchAttachment = true;
                break;
            }
        }

        if (hasPassbackMatchAttachment) {
            try {
                gs.info('Triggering event for inquiry: ' + inquiryGR.getDisplayValue('number'));
                gs.eventQueue('x_g_afss_inquiry.bulk_inquiry_attachment', inquiryGR, inquiryGR.getUniqueValue(), '');

                // Mark event as triggered
                inquiryGR.u_event_triggered = true;
                inquiryGR.update();

                gs.info('Event triggered and marked as processed for inquiry: ' + inquiryGR.getDisplayValue('number'));
                count++;
            } catch (e) {
                gs.error('Failed to trigger event for inquiry ' + inquiryGR.getDisplayValue('number') + ': ' + e.message);
            }
        }
    }

    gs.info('Finished processing. Total triggered: ' + count);
})();