Delete scheduled Events

MacSWW
Giga Contributor

All,

 

I've followed this article: Creating a Simple Reminder Email - ServiceNow Wiki and created a new Event called change.reminder so that I can trigger an email to remind people when their Change Request 'Planned End Date' has passed. This is working perfectly, but can't figure out how to delete these Events if the Planned End Date is changed before the email is triggered.

 

For example, if the Planned End Date was originally set on the Change Request for 1pm on 17/07/2014 and the Change is submitted, an Event is logged and sits in the 'Ready' state until that time. If the Planned End Date is then changed to 12:30pm on 17/07/2014, a new Event is created, but the old one stays in the Event queue. Basically, the user will end up getting two emails, one at 12:30pm and one at 1pm.

 

Is there a way I can delete the first Event when the second one is created? I'm not very good at javascript, so any examples of how to add to the Business Rule to delete or re-schedule these Events would be really helpful!

 

Thanks,

 

Mac

1 ACCEPTED SOLUTION

tltoulson
Kilo Sage

Hi Mac,



Deleting scheduled events is just like deleting any other record once you understand how Events work in ServiceNow.   When you queue an event through gs.eventQueue or gs.eventQueueScheduled, it actually creates a record on the sysevent table.   The key fields to note on this table are:



Name: The name of the event


Table: The table from which the event fired


Instance: The sys id of the record from which the event was fired


State: Whether or not the event has processed


Process on: When the event should be processed



The last one is very important.   A scheduled job actually processes the event queue by periodically retrieving all the events whose Process on date/time has already passed and processing the event's actions.   So until the scheduled job processes it, the event record will remain in the Ready state.   Here is how we can leverage this information:



Business Rule


When: After


Update: True


Condition: current.end_date.changes()


Script:



// Self executing anonymous function is not necessary but a good practice in Business Rules


(function() {


        var gr = new GlideRecord('sysevent'); // We need to query the sysevent table


        gr.addQuery('state', 'ready');   // We only want the event in the ready state


        gr.addQuery('name', 'EVENTNAMEHERE'); // Change the event name to the event name you are using


        gr.addQuery('table', 'change_request');


        gr.addQuery('instance', current.sys_id + ''); // Get the event that has been created for this record


        gr.setLimit(1); // Assuming there is only one ready event active for this record at a time, this can improve performance


        gr.deleteMultiple();


       


        /* Schedule your new event here*/


})();



In theory, you could also simply update the Process on field instead of deleting the event but I would do it this way to be on the safe side.   Also, instead of deleting the event, you could update the state to processed.


View solution in original post

11 REPLIES 11

Jim Coyne
Kilo Patron

Just a side note, I would add a "u." prefix to the name of the event to ensure any new ServiceNow event would not conflict with it.



Very similar to how they name custom table and columns.


MacSWW
Giga Contributor

Good point Jim - I'll do that now...



Thanks,



Mac


MacSWW
Giga Contributor

Sorry to dig this up again, but our Change Manager would like the reminder email to be generated 1 hour after the Planned End Date. Does anyone know of an easy way to add this delay to the initial event creation script above?



Thanks,



Mac


Hi Mac,



You will need to change the last parameter of the gs.eventQueueScheduled function (current.end_date).   You will want to use a separate GlideDateTime object instead of current.end_date so as not to accidentally change the end_date.



Example:



var notifyAt = new GlideDateTime();


notifyAt.setNumericValue(current.end_date.getGlideObject().getNumericValue()); // This sets a new GlideDateTime object to the same value as end_date using the numeric value


notifyAt.addSeconds(3600); // 3600 seconds in an hour, their may be a better function but this one is documented


gs.eventQueueScheduled('name', current, param1, param2, notifyAt);



I hope this helps.



Edit:   Added getGlideObject function call to line 02


MacSWW
Giga Contributor

Thanks again for replying Travis - unfortunately when I tried your script I got a "Can't find method com.glide.glideobject.GlideDateTime.setNumericValue(undefined)" error. I'm hoping it's just something stupid I'm doing wrong:



var notifyAt = new GlideDateTime();


notifyAt.setNumericValue(current.end_date.getNumericValue()); // This sets a new GlideDateTime object to the same value as end_date using the numeric value  


notifyAt.addSeconds(3600); // 3600 seconds in an hour, their may be a better function but this one is documented


gs.eventQueueScheduled('u.change.reminder', current, gs.getUserID(), gs.getUserName(), notifyAt);



I tried changing it slightly to the one below - this doesn't give any errors, but doesn't create an Event either:


var notifyAt = new Packages.com.glide.glideobject.GlideDateTime();


notifyAt.setDisplayValue(current.end_date());


var n = notifyAt.getNumericValue();


n = n + 1000*60*60;


notifyAt.setNumericValue(n);


gs.eventQueueScheduled('u.change.reminder', current, gs.getUserID(), gs.getUserName(), notifyAt);



We're still running Berlin (don't ask!), so I'm not sure if that has anything to do with it.



Any assistance appreciated for this novice scripter!



Thanks,



Mac