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
Kilo 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 mark this response as Helpful & Accept it as solution if it assisted you with your question.
Regards
Tanushree Maiti
ServiceNow Technical Architect
Linkedin:

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