How can I customize the out of the box email approval notifications?

Todd O
Tera Guru

I have a customer change request table (e.g., change_request_todd) that extends change request. I then have a workflow that has an Approval - User activity.   When this Approval - User activity is called, it is using the out of the box email notification called Approval request, which uses email template called itil.approve.role.   Instead of using this out of the box email template, I would like to make a copy of that and customize it for my own purpose.   I need to know how to do this.

I would also like to understand (and probably need to know) the flow of how things are getting triggered. Here is how I think it's happening.

  1. My workflow Approval - User activity will insert a row into sysapproval_approver.
  2. When a row gets entered into this table, a business rule is triggered.  
  3. I believe the out of box rule that gets triggered is called Approval Events and the table it watches for is Approval [sysapproval_approver].
  4. Within this business rule is an advanced script (which I pasted below for reference).
  5. In looking at the script below, I'm guessing that it ends executing this statement...
    1. gs.eventQueue(event, current, gs.getUserID(), gs.getUserName());
    2. ...Where event = request.approval.inserted
  6. That event then triggers an email notification rule I described in my first paragraph (called Approval request, which uses email template called itil.approve.role).
  7. Then, the email goes out using the current record of sysapproval_approver.

Again, my problem is how to I change this process so that I can make a copy of itil.approve.role email template and have workflow Approver - User activity trigger my custom email template instead of out of the box version? Which if the process steps above need to be modified to accomplish this. Thank you!!!!!!!!!

Todd

Ref: Out of box Advance script in the Approval Events business rule

function checkRequest() {

    var task = current.sysapproval.sys_class_name;

    return (task == 'sc_request');

}

function checkSCTask() {

    var task = current.sysapproval.sys_class_name;

    return (task == 'sc_task');

}

function checkProject() {

    var task = current.sysapproval.sys_class_name;

    return (task == 'pm_project');

}

var isRequest = checkRequest();

var isSCTask = checkSCTask();

var isPMTask = checkPMTask();

if (current.state.changes() && current.state=='cancelled') {

    var event = "approval.cancelled";

    if (isRequest)

          event = "request.approval.cancelled";

    else if (isSCTask)

          event = "sc_task.approval.cancelled";

    else if (isPMTask)

          event = "pm_project.approval.cancelled";

    gs.eventQueue(event, current, gs.getUserID(), gs.getUserName());

}

if (current.state.changes() && current.state=='requested') {

    var event = "approval.inserted";

    if (isRequest)

          event = "request.approval.inserted";

    else if (isSCTask)

          event = "sc_task.approval.inserted";

    else if (isPMTask)

          event = "pm_project.approval.inserted";

    gs.eventQueue(event, current, gs.getUserID(), gs.getUserName());

    updateTask(current, current.approver.getDisplayValue() + " requested to approve task");

}

if (current.state.changes() && current.state=='rejected') {

    var event = "approval.rejected";

    if (isRequest)

          event = "request.approval.rejected";

    else if (isSCTask)

          event = "sc_task.approval.rejected";

    else if (isPMTask)

          event = "pm_project.approval.rejected";

 

    gs.eventQueue(event, current, current.state, previous.state);

    updateTask(current, current.approver.getDisplayValue() + " rejected the task.", current.comments);

    notifyMyFriends(current);

}

if (current.state.changes() && current.state=='approved') {

    updateTask(current, current.approver.getDisplayValue() + " approved the task.", current.comments);

}

function notifyMyFriends(me) {

    var friends = new GlideRecord('sysapproval_approver');

    friends.addQuery('sysapproval', me.sysapproval);

    friends.query();

    while(friends.next()) {

          if (friends.approver.toString() != me.approver.toString()) {

                gs.eventQueue("approval.rejected.by.other", me, friends.approver);

          }

    }

}

function updateTask(me, journal, comments) {

    // if this is for a group approval, don't log this user action since the Group Approval Activity will handle the logging

    if (!current.group.nil())

          return;

   

    // only log the user approval activity for workflows when specifically turned on

    // otherwise, we spam the approval history log when it is almost never desired to track via the approval history journal field

    var isWorkflow = !current.wf_activity.nil();

    if (isWorkflow && (gs.getProperty("glide.workflow.user_approval_history") != "true"))

          return;

   

    if (comments)

          journal += " Comments: " + comments;

    var task = new GlideRecord('task');

    if (task.get(me.sysapproval)) {

          if (isWorkflow)

                task.setWorkflow(false);

               

          task.approval_history.setJournalEntry(journal);

          task.update();

1 ACCEPTED SOLUTION

Pradeep Sharma
ServiceNow Employee
ServiceNow Employee

Hi Todd,



You can modify the "Approval request" OOTB notification condition so that it doesn't trigger for your custom table.


Go to the condition field and click on show related field->Now Click on Approval for->Task fields->Now select the field task type


Hence the condition will be Approval for.task type is not "your table name".


Screen Shot 2016-02-02 at 9.28.36 PM.png



Then you can mimic the same notification and create the one with your own template which will have the condition to trigger only for your custom table only.



I hope this helps


View solution in original post

3 REPLIES 3

Pradeep Sharma
ServiceNow Employee
ServiceNow Employee

Hi Todd,



You can modify the "Approval request" OOTB notification condition so that it doesn't trigger for your custom table.


Go to the condition field and click on show related field->Now Click on Approval for->Task fields->Now select the field task type


Hence the condition will be Approval for.task type is not "your table name".


Screen Shot 2016-02-02 at 9.28.36 PM.png



Then you can mimic the same notification and create the one with your own template which will have the condition to trigger only for your custom table only.



I hope this helps


Pradeep,


This looks like the answer I'm looking for. I will verify this approach tonight and mark as the correct answer. I'm very grateful for your time and expertise.


Todd



reginabautista
Kilo Sage

Hi Pradeep I have the same requirement. The Approval Request which uses sysapproval_approver table is a Global table and I wouldn't want to affect other apps using it. How do I duplicate it and use within my custom app? Thanks