Email script

tushar_ghadage
Tera Contributor

Hi all , 

I have to sent notification to a group when state on ritm is close complete or cancelled 

with the all the sla defination attached to the ritm as given below 

with has breached , start time , stop time , business left time , business elapsed time , pause duration fields in the notification..

 Screenshot (361).png

I don't have any experience with email script can any please guide here how shall go ahead ??
 
thankss 
3 REPLIES 3

CFrandsen
Tera Guru

Hi @tushar_ghadage  
I would personally prefer doing this within FlowDesigner - but due to limitations, you can't directly initiate flows from create or updates on sc_req_item table. (In case you wanted to do this, you could trigger the flow from a seperate BR) So let's stick to the requested approach for a good old Email Script.

1) Create the Notification
Table: Requested Item [sc_req_item]
When to send: Record updated
Condition:
State changes is true
State is one of Closed Complete, Closed Incomplete, Closed Skipped

Who will receive: your target Group (add a specific group, or use a Scripted Recipient if you need logic).
What it will contain: put ${mail_script:ritm_sla_table} where you want the SLA table.

2) Let's create the Notification Email Script
Go to System Policy → Email → Notification Email Scripts and create ritm_sla_table with this script:

// Name: ritm_sla_table
// Applies to: Global (or your app scope)
// Usage: ${mail_script:ritm_sla_table}

(function() {
    // Guard: ensure we’re on a RITM
    if (!current || current.getTableName() !== 'sc_req_item') {
        template.print('<p><em>No RITM context available.</em></p>');
        return;
    }

    // Query all SLAs linked to this RITM
    var slaGR = new GlideRecord('task_sla');
    slaGR.addQuery('task', current.sys_id);
    slaGR.orderBy('start_time');
    slaGR.query();

    if (!slaGR.hasNext()) {
        template.print('<p><em>No SLAs found for this item.</em></p>');
        return;
    }

    // Helper to format durations safely
    function fmtDur(val) {
        if (!val) return '';
        try { return (new GlideDuration(val)).getDisplayValue(); } catch (e) { return val; }
    }

    // Build a simple HTML table
    var html = [];
    html.push('<table style="border-collapse:collapse;width:100%;">');
    html.push('<thead>');
    html.push('<tr>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">SLA</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Has Breached</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Start Time</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Stop Time</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Business Time Left</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Business Elapsed</th>');
    html.push('<th style="text-align:left;border-bottom:1px solid #ddd;padding:6px;">Pause Duration</th>');
    html.push('</tr>');
    html.push('</thead><tbody>');

    while (slaGR.next()) {
        html.push('<tr>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  slaGR.sla.getDisplayValue() + '</td>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  (slaGR.has_breached ? 'Yes' : 'No') + '</td>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  slaGR.getDisplayValue('start_time') + '</td>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  slaGR.getDisplayValue('end_time') + '</td>'); // "end_time" is stop time
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  fmtDur(slaGR.getValue('business_time_left')) + '</td>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  fmtDur(slaGR.getValue('business_elapsed_time')) + '</td>');
        html.push('<td style="padding:6px;border-bottom:1px solid #f0f0f0;">' +
                  fmtDur(slaGR.getValue('pause_duration')) + '</td>');
        html.push('</tr>');
    }

    html.push('</tbody></table>');
    template.print(html.join(''));
})();


I've quickly tested - and received this 😉 

CRFN1_0-1755021540307.png


So I guess it would work for you as well.

 

 



 If this pointed you in the right direction, hit Helpful to spread the good vibes.
If it cracked the case for you, mark it Correct so the next person doesn’t have to reinvent the wheel.

Bhimashankar H
Mega Sage

Hi @tushar_ghadage ,

 

So need to first create the email script, that will form like table structure format and use that in email notification like

 

${mail_script:nameOfYourMailScript}

ensure the notification is triggered when sc_req_item.state is Closed Complete or Closed Cancelled and is sent to the desired group.

 

below is mail script you can try

 

(function runMailScript(/* GlideRecord */ current, /* TemplatePrinter */ template,
          /* Optional EmailOutbound */ email, /* Optional GlideRecord */ email_action,
          /* Optional GlideRecord */ event) {

 function disp(gr, field) {
    if (!gr || !field) return '';
    try {
      return gr.getDisplayValue(field) || '';
    } catch (e) {
      return '';
    }
  }

  function boolToYesNo(v) {
    // task_sla.has_breached is a boolean; display Yes/No
    return ('' + v) === 'true' ? 'Yes' : (('' + v) === 'false' ? 'No' : (v ? 'Yes' : 'No'));
  }

  // Query task_sla where task is this RITM
  var slaGR = new GlideRecord('task_sla');
  slaGR.addQuery('task', current.sys_id);
  slaGR.orderBy('sla.name'); // stable order
  slaGR.query();

  // If no SLAs found, render a short note
  if (!slaGR.hasNext()) {
    template.print('<p>No SLAs are attached to this Requested Item.</p>');
    return;
  }

  // Table header
  template.print(
    '<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;">' +
      '<thead>' +
        '<tr style="background:#f2f2f2;">' +
          '<th align="left">SLA Definition</th>' +
          '<th align="left">Has Breached</th>' +
          '<th align="left">Start Time</th>' +
          '<th align="left">Stop Time</th>' +
          '<th align="left">Business Time Left</th>' +
          '<th align="left">Business Elapsed</th>' +
          '<th align="left">Pause Duration</th>' +
          '<th align="left">Stage</th>' +
        '</tr>' +
      '</thead><tbody>'
  );

  while (slaGR.next()) {
    // Fields: Add your fields
    // - sla.name (definition)
    // - has_breached (boolean)
    // - start_time, end_time (a.k.a. stop time)
    // - business_time_left, business_elapsed_time (durations)
    // - pause_duration (duration)
    // - stage (in_progress, paused, completed, cancelled, breached)
    var slaName = disp(slaGR, 'sla');
    var breached = boolToYesNo(slaGR.has_breached);
    var startTime = disp(slaGR, 'start_time');
    var stopTime = disp(slaGR, 'end_time'); // stop time stored in end_time
    var bizLeft = disp(slaGR, 'business_time_left');
    var bizElapsed = disp(slaGR, 'business_elapsed_time');
    var pauseDur = disp(slaGR, 'pause_duration');
    var stage = disp(slaGR, 'stage');

    template.print(
      '<tr>' +
        '<td>' + gs.escapeHTML(slaName) + '</td>' +
        '<td>' + gs.escapeHTML(breached) + '</td>' +
        '<td>' + gs.escapeHTML(startTime) + '</td>' +
        '<td>' + gs.escapeHTML(stopTime) + '</td>' +
        '<td>' + gs.escapeHTML(bizLeft) + '</td>' +
        '<td>' + gs.escapeHTML(bizElapsed) + '</td>' +
        '<td>' + gs.escapeHTML(pauseDur) + '</td>' +
        '<td>' + gs.escapeHTML(stage) + '</td>' +
      '</tr>'
    );
  }

  template.print('</tbody></table>');

})(current, template, email, email_action, event);

 

Once done then, try sending notification and check the final mail. You may not able view this when 'preview notication'.

Thanks,
Bhimashankar H

 

-------------------------------------------------------------------------------------------------
If my response points you in the right directions, please consider marking it as 'Helpful' & 'Correct'. Thanks!

Rafael Batistot
Tera Sage

Hi @tushar_ghadage,

This is the complete guide for your solicitation:

1 - Create an event

You define event names in the Event Registry.

  • Go to System Policy > Events > Event Registry.

  • Click New.

  • Fill in:

    • Name: a unique event name (e.g., custom.task.completed)

    • Table (optional): the table related to the event (e.g., task)

    • Save it.

2 - Create a notification 

  • Create a new notification triggered when:

    • Table: sc_req_item

    • When to send: Record updated

    • Condition: state is Closed Complete OR Cancelled.

  • In the Who will receive section, choose your target group.

  • In the What it will contain section, add:

    • The normal message body.

    • Under Advanced view, add the above mail script.

  • In the body, reference it like:

${mail_script:sla_details}


3 - Create the mail script

// Mail script for notification
(function() {
    var result = [];
    var slaGR = new GlideRecord('task_sla');
    slaGR.addQuery('task', current.sys_id);
    slaGR.query();

    while (slaGR.next()) {
        result.push(
            'SLA Name: ' + slaGR.sla.name + '\n' +
            'Has Breached: ' + slaGR.has_breached + '\n' +
            'Start Time: ' + slaGR.start_time.getDisplayValue() + '\n' +
            'Stop Time: ' + slaGR.end_time.getDisplayValue() + '\n' +
            'Business Time Left: ' + slaGR.business_time_left + '\n' +
            'Business Elapsed Time: ' + slaGR.business_elapsed_time + '\n' +
            'Pause Duration: ' + slaGR.pause_duration + '\n' +
            '-------------------------\n'
        );
    }

    template.print(result.join('\n'));
})();
​