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

Fredrik and Rakesh:   Firstly, THANK YOU for your responses. Both responses educated me, although Fredrik's really nailed my requirement. I sure did NOT want to have to re-create my complex report parms using invidual AddQuery statements knowing it should be possible to simply re-use the Report as it is.



My only remaining challenge is this:


I understand why and how the solution above referred to "gr.opened_by" to get the user that opened the record. In my case, again referring to my screenshots earlier, I will simply replace this with gr.Owner (the very first column in my report output).   HOWEVER, on other reports I will eventually need to get the dot-walked email address, as well (ie, the second column called Owner.email). But when I try gr.owner.email it seems to return nothing (although there are guaranteed to be values in that second column). I must not be using the correct column name, despite what I see on the report screenshot as "Owner.email".   How can I determine the exact dot-walking column name from my report for use in the gr. reference?   I don't know if I must use u_owner vs owner, or email vs u_email, etc.   Please note I do not have admin rights and I don't know how to write to the log or other means of tracing my work (at least that I know of).   I have lots of other reports where dot-walking will be required (some even 3-4 levels deep), so please advise on how I can lookup or find the exact column names to use in my script when dot-walking for purposes of a scheduled report script.



Almost there!   Again, any help is much appreciated!   Happy New Year!   You're the best!


Scott


gr.opened_by return the sys_id of the user who opened the record.


When setting users into the user-field on the scheduled report it's the sys_id of the user you should set and not the email-adress.



If you want to set the email adress you could dot-walk and set it like this


current.address_list = users;



In your case you just need to change gr.opened_by with gr.u_owner (I assume u_owner is a reference field to User table, if not it won't work).



When scripting towards a specific field, it's the field name you script against, not the field label. Field names are never in capital letter and that could be an issue if you run scripts if you use a capital letter in the beginning.


As an admin it's easy to get the field name, you just right-click the field label and you'll see show - 'u_owner' and this will be the field name. It might work as a regular user but you'll see watch - 'u_owner' instead.


find_real_file.png



I'm not sure if there is some other way to get the info about the field name, before I became admin I had never looked into this at all. Maybe you could get temporary admin access in a test instance at your company to be able to get the desired info, otherwise an admin might have to look it up.


In most cases if it's an out of the box field the name will be the same as the label (but not always and the "space" is replaced with _). If it's a custom field the name will most likely be the field label but with u_ in front of it.


Chazz
Kilo Contributor

I used this script method to make a dynamic email for change users who had outstanding changes.   This worked perfect I just had to replace :

   users += ',' + gr.opened_by;

With

   users += ',' + gr.assigned_to;

 

Rakesh Mamidi
ServiceNow Employee
ServiceNow Employee

I made modifications to the earlier script which will work for list type reports and which has intended email column




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 fields = scheduleReport.report.field_list.split(',');


var addressList = '';


var emailFields = [];




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


var gr = new GlideRecord(tablename);




for (var i = 0; i < fields.length; i++) {


      var glideElement = gr.getElement(fields[i]);


      var descriptor = glideElement.getED();


      var result = descriptor.getInternalType();


      if (result == 'email') {


              emailFields.push[glideElement];


      }




      gr.addEncodedQuery(query);


      gr.query();


      while (gr.next()) {


            for (var j = 0; j < emailFields.length; j++) {


                      addressList = ',' + gr.emailFields[j];


              }


      }




      current.address_list = addressList;


      current.update();




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


      answer = true;


Thank you again for all your wonderful responses! Unfortunately, no matter what I try, it's still not working for me, even though it apparently works for others in this forum. My scheduled job does seem to 'occur' (proven by emails I do receive at an email address when I hard-code it in the script), but using a GlideRecord or walking thru it and using GET for additional email addresses doesn't appear to work for me.



Maybe I'm simply NOT ALLOWED to execute either the scripts or the GlideRecord from the Scheduled Reports UI (eg, user roles?), either:


A. I don't have a role that allows me to execute my script in the Scheduled Reports UI, or


B. I have a role that specifically denies my execution of my script in the Scheduled Reports UI.


I asked my admin if the above is a possible cause, but no useful response yet.



Related questions:


1. Is my 'conditional' script in my Scheduled Report considered a client-side or server-side script?   I'm guessing server-side because I don't execute it myself locally.


2. Does anyone know if "OOTB" SN automatically prevents users from using scripts in the Scheduled Report space? Is that something that MUST be explicitly enabled with a rule first or is it automatically enabled until explicitly taken away?   Knowing this would be extremely helpful.



Thanks for helping out a stranger!