HELP! How to dynamically set recipients of an existing Scheduled Report to email addresses that are in the report's output?

scottbjorke
Tera Contributor

I have a lot of Scheduled Reports that run a given Report whose output includes email addresses. Presently, my Scheduled Reports get emailed only to whoever I have pre-defined as the STATIC list of email addresses, per the Scheduled Reports UI (in this case, 'bob@mycomany.com'). From there, those recipients have to open the attached report, spot the email address on each row, and FW the report attachment directly to those email addresses from the report output. This seems unnecessary -- I'd rather "cut out the middle man" and have SN set the recipients equal to the email addresses I find within the report.

I assume this means:

- I can simply 'utilize' the same Report that is already defined in my Scheduled Report

- set Conditional = TRUE then insert my scripting logic into the Scheduled Report definition

- walk through some kind of GlideRecord that essentially IS my predefined Report

- get each record's email address (which is one of its report columns) -- but be aware I don't know exactly how to get its exact name because I'm dot-walking and don't have admin rights to utlize the SN log

- appending it to something like "current.address_list" (with a trailing comma to separate each email address)

- that current.address_list can hold a long comma-delimited list of emails as a string value and is not an array[] instead

- retuning TRUE to indeed trigger the report.

Of course, any or all the above assumptions may be really lousy     And of course, there's probably a much easier, simpler way to do what I want to do.

Please note I do not have admin privileges. I'm just a Change Manager trying to reduce operational waste and learn more about leveraging SN's capabilities myself.

Here's header and the script of my latest attempt.   Would really appreciate it if someone could take a look and reply with ideas/comments that are indeed helpful.   That also includes giving me code examples that essentially replace mine (ie, starts over).

Please note I have confirmed the below approach does successfully send my report output to the STATIC recipient from the script AND to the email address predefined in the UI below.   I just can't figure out how to glean additional email recipients from the addresses found in the report output.

find_real_file.png

---

// REMINDER: THE BELOW SCRIPT EXECUTES ONLY IF "CONDITIONAL" IS CHECKED ABOVE

// Include the Script Include
gs.include('ReportEmailList');

// Set the STATIC recipients first
var email_recipients = 'john.doe@mycompany.com';
var next_email = ' ';

//Execute the scheduled report within a local GlideRecord
var rec = new GlideRecord('sysauto_report');
rec.get('name', 'Scott some rows to return various Release Owners'); // this is same as what's in the header
rec.query();

// cycle through each report row (if any), get the DYNAMIC recipient value, and append it to the recipients string with a leading comma
if (rec.getRowCount() > 0) {
      while (rec.next()) {
                next_email = rec.GetValue('u_owner.email');    
                email_recipients += ',' + next_email;
      }
}

current.address_list = email_recipients;       // FYI - I have verified this line works to affect email recipients manually -- just need help setting 'email_recipients' variable using report output
// Need to set this true for condition script to run
answer = true;

---

PS   Here's how my Report is defined:

find_real_file.png

1 ACCEPTED SOLUTION

I modified your solution a bit and came up with the following to fit the requirement.


I'm not sure why you set a static recipient in the code, this could be written in the Email addresses field directly.


Instead of adding the users to the Email addresses field I added them to the Users field instead (see below script)



var scheduleReport = new GlideRecord('sysauto_report');


scheduleReport.get(current.sys_id); //Sys ID of your schedule Report



var tablename = scheduleReport.report.table;


var query = scheduleReport.report.filter;


var users = '';



//Execute the report as a GlideRecord with the set table and condition


var gr = new GlideRecord(tablename);


gr.addEncodedQuery(query);


gr.query();


while (gr.next()) {


  users += ',' + gr.opened_by;


}



current.user_list = users;


current.update();



// Need to set this true for condition script to run


answer = true;



This script works fine for me when testing in my developer instance.


View solution in original post

21 REPLIES 21

1.Conditional Script is Server side code


2. In conditional script you can't use current.update operation.



You need to create a new Schedule job(script execution) and then fill scheduled report with email id's and execute it via the same script (Refer my first script for synopsis )


Does anyone know if "OOTB" SN automatically prevents users from utilizing scripts in the Scheduled Report space?   I can write the scripts with no problem, but is ability for them (or more perhaps specifically use of GlideRecords within them) to be run something that MUST be explicitly enabled with a rule first, or (alternatively) is it automatically enabled until explicitly taken away?   Knowing this would be extremely helpful.


Pavan Kumar1
Tera Contributor

Hi, I am trying to do the similar thing but I am only able to hold maximum of 10 recipients in the Email Address (address_list) as this field has limit. How did you tackle this issue? I have over 100 recipients in the report to whom I need to schedule the report to.

Pavan Kumar1
Tera Contributor

Hi, I am trying to do the similar thing but I am only able to hold maximum of 10 recipients in the Email Address (address_list) as this field has a limit. How do i resolve this issue? I have over 100 email address in my first report and I need to dynamically schedule report to all those recipients. 

Hello! Wish I could help you with your maximum number of email addresses issue. I never had that issue because I utilize the 'user_list' attribute of 'current' instead. Even when utilizing the 'address_list' attribute, I never included more than 3 email addresses, so never ran across that problem.

The code below leverages the email addresses already in ServiceNow for those users who should receive the report. If your solution involves hard-coded email addresses or anything outside of what's already directly available in ServiceNow, I'm sure you would encounter max length issues with the 'address_list' attribute.

Give the below concept a try (utilized 'user_list' instead of 'address_list'.  Hope you find this helpful.

 

var GroupManager = '';        // to hold Group's Manager for each looped row

// get pre-existing User recipients from definition above and append separator (works with or without existing Users)
var UserList = current.user_list + ',';    // save the original User list (TO:)

// SEND EMAIL TO EACH 'USER' IN THE REPORT OUTPUT (agnostic of their email address, which is nice)
var scheduleReport = new GlideRecord('sysauto_report');   // get details directly from this Scheduled Report
scheduleReport.get(current.sys_id);              // gets the Sys ID of THIS particular Scheduled Report  
var tablename = scheduleReport.report.table;     // gets the table that the above Report points at

var query = scheduleReport.report.filter;      // gets all the Report's predefined clauses and other criteria
var gr = new GlideRecord(tablename);   // set up a LOCAL GlideRecord object using the Report's table
gr.addEncodedQuery(query);             // apply to it all the Report definitions found above
gr.query();                            // execute the Report query into the LOCAL GlideRecord object

// ---------------------------- 

while (gr.next()) {                    // loop through each LOCAL record until done
   // get the applicable recipients (field names are Report-specific!) and append each to the existing list
   GroupManager = gr.assignment_group.manager;
   UserList += (GroupManager + ',');
}
current.user_list = UserList;       // override the user_list

true;