i created this Scheduled Script Execution but it seem like its not triggering

Ricardo Sanchez
Tera Contributor
The purpose it needs to send an approval reminder 24, 48 and 72 hours if no respond on the 96 hour it will close the req and RITM. 

(
function () {

  var RITM_STATE_CLOSED_INCOMPLETE = 4;                 // sc_req_item.state
  var RITM_STAGE_VALUE            = 'approval_not_received'; // sc_req_item.stage
  var REQ_REQUEST_STATE_VALUE     = 'closed_incomplete';     // sc_request.request_state
  var REQ_STAGE_VALUE             = 'closed_incomplete';     // sc_request.stage

  function makeBounds(hoursAgo) {
    var now = new GlideDateTime();
    var msNow = now.getNumericValue();

    var upper = new GlideDateTime();
    upper.setNumericValue(msNow - (hoursAgo * 60 * 60 * 1000));

    var lower = new GlideDateTime();
    lower.setNumericValue(upper.getNumericValue() - (60 * 60 * 1000));

    return { lower: lower, upper: upper };
  }

  // Send approval reminders to approvers on RITMs at a given age
  function queueRitmReminders(hoursAgo, eventName) {
    var w = makeBounds(hoursAgo);

    var gr = new GlideRecord('sysapproval_approver');
    gr.addQuery('state', 'requested');
    gr.addQuery('sysapproval.sys_class_name', 'sc_req_item'); // RITM only
    gr.addQuery('sys_created_on', '>=', w.lower);
    gr.addQuery('sys_created_on', '<',  w.upper);
    gr.query();

    while (gr.next()) {
      gs.eventQueue(eventName, gr, '', '');
    }
  }

  // At 96 hours, close RITM and REQ as incomplete, cancel remaining approvals, fire cancellation event
  function cancelRitmsAt96Hours() {
    var w = makeBounds(96);

    var appr = new GlideRecord('sysapproval_approver');
    appr.addQuery('state', 'requested');
    appr.addQuery('sysapproval.sys_class_name', 'sc_req_item');
    appr.addQuery('sys_created_on', '>=', w.lower);
    appr.addQuery('sys_created_on', '<',  w.upper);
    appr.query();

    // Prevent double handling when multiple approvals exist on the same RITM in this window
    var processed = {};

    while (appr.next()) {
      var ritmId = String(appr.getValue('sysapproval') || '');
      if (!ritmId || processed[ritmId]) continue;
      processed[ritmId] = true;

      var ritm = new GlideRecord('sc_req_item');
      if (!ritm.get(ritmId)) continue;

      // Skip if already closed incomplete
      if (String(ritm.getValue('state')) === String(RITM_STATE_CLOSED_INCOMPLETE)) continue;

      // Set RITM stage
      if (ritm.isValidField('stage')) {
        ritm.setValue('stage', RITM_STAGE_VALUE);
      }

      // Close RITM as incomplete
      ritm.setValue('state', RITM_STATE_CLOSED_INCOMPLETE);
      ritm.update();

      // Cancel any still requested approvals on this RITM
      var ap2 = new GlideRecord('sysapproval_approver');
      ap2.addQuery('sysapproval', ritm.getUniqueValue());
      ap2.addQuery('state', 'requested');
      ap2.query();
      while (ap2.next()) {
        ap2.setValue('state', 'cancelled');
        ap2.update();
      }

      // Close parent REQ request_state and stage
      if (ritm.request) {
        var req = new GlideRecord('sc_request');
        if (req.get(ritm.request.toString())) {
          if (req.isValidField('request_state')) {
            req.setValue('request_state', REQ_REQUEST_STATE_VALUE);
          }
          if (req.isValidField('stage')) {
            req.setValue('stage', REQ_STAGE_VALUE);
          }
          req.update();
        }
      }

      // Firing cancellation event on the RITM table
       gs.eventQueue('ritm.approval.cancelled.96h', ritm, '', '');
    }
  }

  // Reminders
  queueRitmReminders(24, 'ritm.approval.reminder.24h');
  queueRitmReminders(48, 'ritm.approval.reminder.48h');
  queueRitmReminders(72, 'ritm.approval.reminder.72h');

  // Auto cancel at 96 hours
  cancelRitmsAt96Hours();
})();
6 REPLIES 6

I have couple test records but so far no events have trigger which they should already, i ran a couple of background script to see timestamps. Scripting is not my biggest thing.

 

@Ricardo Sanchez 

try this and see, ensure you set Recipient in Who will receive tab in notification

(function() {
    var RITM_STATE_CLOSED_INCOMPLETE = 4; // sc_req_item.state
    var RITM_STAGE_VALUE = 'approval_not_received'; // sc_req_item.stage
    var REQ_REQUEST_STATE_VALUE = 'closed_incomplete'; // sc_request.request_state
    var REQ_STAGE_VALUE = 'closed_incomplete'; // sc_request.stage

    // Returns lower and upper bounds for hour window X hours ago
    function makeBounds(hoursAgo) {
        var now = new GlideDateTime();
        var upper = new GlideDateTime(now.getValue());
        upper.addSeconds(-hoursAgo * 60 * 60); // Subtract N hours (in seconds)
        var lower = new GlideDateTime(upper.getValue());
        lower.addSeconds(-60 * 60); // Subtract 1 hour (in seconds)
        return {
            lower: lower,
            upper: upper
        };
    }

    // Send approval reminders to approvers for RITMs at a given age
    function queueRitmReminders(hoursAgo, eventName) {
        var w = makeBounds(hoursAgo);
        var gr = new GlideRecord('sysapproval_approver');
        gr.addQuery('state', 'requested');
        gr.addQuery('sysapproval.sys_class_name', 'sc_req_item');
        gr.addQuery('sys_created_on', '>=', w.lower);
        gr.addQuery('sys_created_on', '<', w.upper);
        gr.query();

        while (gr.next()) {
            gs.eventQueue(eventName, gr, '', '');
        }
    }

    // At 96 hours, close RITM and REQ as incomplete, cancel approvals, fire cancellation event
    function cancelRitmsAt96Hours() {
        var w = makeBounds(96);
        var appr = new GlideRecord('sysapproval_approver');
        appr.addQuery('state', 'requested');
        appr.addQuery('sysapproval.sys_class_name', 'sc_req_item');
        appr.addQuery('sys_created_on', '>=', w.lower);
        appr.addQuery('sys_created_on', '<', w.upper);
        appr.query();

        var processed = {};
        while (appr.next()) {
            var ritmId = String(appr.getValue('sysapproval') || '');
            if (!ritmId || processed[ritmId]) continue;
            processed[ritmId] = true;

            var ritm = new GlideRecord('sc_req_item');
            if (!ritm.get(ritmId)) continue;
            if (String(ritm.getValue('state')) === String(RITM_STATE_CLOSED_INCOMPLETE)) continue;

            if (ritm.isValidField('stage')) ritm.setValue('stage', RITM_STAGE_VALUE);
            ritm.setValue('state', RITM_STATE_CLOSED_INCOMPLETE);
            ritm.update();

            var ap2 = new GlideRecord('sysapproval_approver');
            ap2.addQuery('sysapproval', ritm.getUniqueValue());
            ap2.addQuery('state', 'requested');
            ap2.query();
            while (ap2.next()) {
                ap2.setValue('state', 'cancelled');
                ap2.update();
            }

            if (ritm.request) {
                var req = new GlideRecord('sc_request');
                if (req.get(ritm.request.toString())) {
                    if (req.isValidField('request_state')) req.setValue('request_state', REQ_REQUEST_STATE_VALUE);
                    if (req.isValidField('stage')) req.setValue('stage', REQ_STAGE_VALUE);
                    req.update();
                }
            }

            gs.eventQueue('ritm.approval.cancelled.96h', ritm, '', '');
        }
    }

    // Reminders
    queueRitmReminders(24, 'ritm.approval.reminder.24h');
    queueRitmReminders(48, 'ritm.approval.reminder.48h');
    queueRitmReminders(72, 'ritm.approval.reminder.72h');

    // Auto cancel at 96 hours
    cancelRitmsAt96Hours();
})();

If my response helped please mark it correct and close the thread so that it benefits future readers.

 

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