We're reclaiming inactive PDIs to keep them available for active builders. Learn what's changing, who's affected, and how to protect your work. Read More

How to populate multiple CC email addresses into Watch List from inbound email using flow designer?

pot
Tera Contributor

Hi all,

I am working on an inbound email use case where I need to populate the Watch List field on a Case record using the CC email addresses from the inbound email.

Current behavior:

  • If there is only one email address in CC, mapping it directly to the Watch List works fine.

  • However, when there are multiple email addresses in CC, the Watch List is not getting populated. Any suggestions?

8 REPLIES 8

Tanushree Maiti
Tera Patron

Hi @pot 

 

Update script in your Action tab of inbound email in your flow.

 

https://www.servicenow.com/community/servicenow-ai-platform-forum/script-to-add-cc-d-users-to-watch-...

 

https://www.servicenow.com/community/hrsd-forum/adding-users-sys-to-watchlist-on-inbound-action/m-p/...

 

https://www.servicenow.com/community/servicenow-ai-platform-forum/inbound-action-to-populate-watcher...

Please Accept the solution if it assisted you with your question & Mark this response as Helpful.
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti

Ankur Bawiskar
Tera Patron

@pot 

share your script here

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 10x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

What I am trying to achieve:

  • Parse all CC email addresses from the inbound email.

  • For each email:

    • If it matches an existing Contact → add the Contact to the Watch List.

    • If no match → still include the email in the Watch List.

  • Ensure multiple email addresses are properly appended (not overwritten).

Challenges:

  • Flow Designer seems to overwrite the Watch List when updating inside a loop.

  • Handling multiple values (comma-separated emails) is not working as expected.

  • Not sure what is the best approach to handle this without breaking OOTB behavior.

 

I have created custom action : 

(function execute(inputs, outputs) {

    var emailStr = inputs.email_string + "";  

    var emails = [];

    if (emailStr && emailStr != "null" && emailStr != "undefined") {

        emails = emailStr.split(",");

        for (var i = 0; i < emails.length; i++) {
            emails[i] = emails[i].trim();
        }
    }

    outputs.email_array = emails;

})(inputs, outputs);

Hi @pot ,

 

please find below finding i have found -

  • Trigger: Inbound Email
  • Add step: Run Custom Action
  • Map Input email_string = Inbound Email → CC (the data pill)
var cc = (inputs.email_string || '') + '';

Simple Working Solution (Flow + One Custom Action)

What the custom action should do

Inputs:

  • case_sys_id (string)
  • cc_string (string from inbound email CC)

Outputs:

  • watch_list_sysids (comma-separated sys_user sys_ids)
  • unmatched_emails (comma-separated emails that didn’t match)

Then Flow does:

  • Update Case once:
    • watch_list = output.watch_list_sysids
    • u_external_watch_emails = output.unmatched_emails (optional)
Custom Action Script (Robust)
(function execute(inputs, outputs) {

    var caseId = (inputs.case_sys_id || '') + '';
    var ccStr  = (inputs.cc_string  || '') + '';

    // Normalize delimiter: sometimes CC comes with ; not ,
    ccStr = ccStr.replace(/;/g, ',');

    // Split + clean
    var emails = ccStr.split(',')
        .map(function(e){ return (e || '').trim().toLowerCase(); })
        .filter(function(e){ return e && e.indexOf('@') > -1; });

    // Deduplicate emails
    var emailSet = {};
    var uniqueEmails = [];
    for (var i = 0; i < emails.length; i++) {
        if (!emailSet[emails[i]]) {
            emailSet[emails[i]] = true;
            uniqueEmails.push(emails[i]);
        }
    }

    // Read existing watch list from Case
    var existingUsers = {};
    var existingList = [];

    if (caseId) {
        var c = new GlideRecord('sn_customerservice_case'); // adjust if your Case table differs
        if (c.get(caseId)) {
            var wl = (c.watch_list || '') + '';
            if (wl) {
                var parts = wl.split(',');
                for (var j = 0; j < parts.length; j++) {
                    var id = (parts[j] || '').trim();
                    if (id) {
                        existingUsers[id] = true;
                        existingList.push(id);
                    }
                }
            }
        }
    }

    // Match emails to sys_user
    var addSysIds = [];
    var unmatched = [];

    for (var k = 0; k < uniqueEmails.length; k++) {
        var email = uniqueEmails[k];

        var u = new GlideRecord('sys_user');
        u.addQuery('email', email);
        u.setLimit(1);
        u.query();

        if (u.next()) {
            var sysId = u.getUniqueValue();
            if (!existingUsers[sysId]) {
                existingUsers[sysId] = true;
                addSysIds.push(sysId);
            }
        } else {
            unmatched.push(email);
        }
    }

    // Final watch list = existing + new
    var finalList = existingList.concat(addSysIds);

    outputs.watch_list_sysids = finalList.join(',');
    outputs.unmatched_emails  = unmatched.join(',');

})(inputs, outputs);

Flow Steps (Minimal)

  1. Trigger: Inbound Email
  2. Action: Run custom action
    • case_sys_id = (your created Case sys_id)
    • cc_string = Inbound Email → CC
  3. Update Case (single update)
    • watch_list = outputs.watch_list_sysids
    • u_external_watch_emails = outputs.unmatched_emails (optional)

Please accept the solution and close the tried if this is helpful.

Thanks,

Rithika.ch