Script to add/remove knowledge owners and managers from a group

cynlink1
Tera Expert

Requirement: When a knowledge base 'owner' or 'kb_managers' field is changed, update a group via business rule. I created an After business rule that runs on the kb_knowledge_base table. I had it working when I was evaluating only the 'owner' field. However once I tried to expand it to include the 'kb_managers' field, it stopped working.

 

I need help with the script. How do I split the list of kb_managers and then include the results in a single array along with the owners.

 

(function executeRule(current, previous /*null when async*/ ) {

    var table = 'kb_knowledge_base';
    var field = 'owner';
    var field2 = "kb_managers"; //list so I believe it needs to be split
	//var field2list= current.kb_managers.toString().split(",");
    var groupId = 'ca791aabdb17201036d8af6d139619e4'; //LIC_USR_SET-Knowledge Users ca791aabdb17201036d8af6d139619e4
    var arrayUtil = new ArrayUtil();

    // Get the list of owners
    var managers = [];
    var gaDupCheck = new GlideAggregate(table);
    gaDupCheck.addEncodedQuery('active=true');
    gaDupCheck.addNotNullQuery(field);
    gaDupCheck.groupBy(field);
    gaDupCheck.query();

    while (gaDupCheck.next()) {
        var ownerSysId = gaDupCheck.getValue(field);
        managers.push(ownerSysId);
    }

    // Get the list of knowledge managers
    var kbmanagers = [];
    var gaDupCheck2 = new GlideAggregate(table);
    gaDupCheck2.addEncodedQuery('active=true');
    gaDupCheck2.addNotNullQuery(field2);
    gaDupCheck2.groupBy(field2);
    gaDupCheck2.query();

    while (gaDupCheck2.next()) {
        var kbmanagerSysId = gaDupCheck.getValue(field2);
        kbmanagers.push(kbmanagerSysId);
    }

    //Concatenate two arrays
    var allmanagers = managers.concat(kbmanagers);
    //example: arr1.concat(arr2, arr3);

    // Control Group Membership for Owners and Knowledge Managers
    var members = [];
    var groupMembers = new GlideRecord('sys_user_grmember');
    groupMembers.addQuery('group.sys_id', groupId);
    groupMembers.query();

    while (groupMembers.next()) {
        var userId = groupMembers.getValue('user');
        members.push(userId);
        if (!arrayUtil.contains(allmanagers, userId)) {
            groupMembers.deleteRecord();
            gs.info('User with sys_id "' + userId + '" removed from group with sys_id "' + groupId + '".');
        }
    }

    //Check the Managers array against the current group members array and insert any NEW managers.
    var difference = arrayUtil.diff(allmanagers, members);
    if (difference) {
        for (var i = 0; i < difference.length; i++) {
            var newManagerSysId = difference[i];

            var newGroupMember = new GlideRecord('sys_user_grmember');
            newGroupMember.initialize();
            newGroupMember.user = newManagerSysId;
            newGroupMember.group = groupId;
            newGroupMember.insert();
            gs.info('Added user with sys_id "' + newManagerSysId + '" to group with sys_id "' + groupId + '".');
        }
    }

})(current, previous);

 

3 REPLIES 3

Community Alums
Not applicable

Hi @cynlink1 ,

 

Create a BR (After - Update), conditions are: Owner changes or Managers changes. The script will be:

 

(function executeRule(current, previous /*null when async*/ ) {
    var groupID = '287ee6fea9fe198100ada7950d0b1b73'; // SYS_ID group
    var arrayUtil = new ArrayUtil();

    // ==== MANAGERS ====
    var removeManagerArr = [];
    var addManagerArr = [];
    var oldManagerList = previous.kb_managers.split(',');
    var newManagerList = current.kb_managers.split(',');
    if (current.kb_managers.changes()) {
        // Remove Manager
        removeManagerArr = arrayUtil.diff(oldManagerList, newManagerList);
        // if Manager to be removed is the current Owner => skip that user
        var index = removeManagerArr.indexOf(current.owner.toString());
        if (index > -1) {
            removeManagerArr.splice(index, 1);
        }
        // Add Manager
        addManagerArr = arrayUtil.diff(newManagerList, oldManagerList);
    }

    // ==== OWNERS ====
    var ownerRemove = [];
    var ownerAdd = [];
    if (current.owner.changes()) {
        // Only remove previous Owner if not found in current Manager list
        if (!previous.owner.nil() && !arrayUtil.contains(newManagerList, previous.owner.toString())) {
            ownerRemove.push(previous.owner.toString());
        }
        // Add Owner
        if (!current.owner.nil()) ownerAdd.push(current.owner.toString());
    }

    // ==== Concat Owner and Manager arrays ====
    var addList = arrayUtil.concat(addManagerArr, ownerAdd);
    if (addList.length > 0) manageMembers('add', addList); // Execute Add

    var removeList = arrayUtil.concat(removeManagerArr, ownerRemove);
    if (removeList.length > 0) manageMembers('remove', removeList); // Execute Remove

    // Function to handle Add or Remove
    function manageMembers(action, list) {
        if (action == 'remove') {
            var removeMemGR = new GlideRecord('sys_user_grmember');
            removeMemGR.addQuery('group', groupID);
            removeMemGR.addQuery('user', 'IN', list.join(','));
            removeMemGR.query();
            while (removeMemGR.next()) {
                removeMemGR.deleteRecord();
            }
        }
        if (action == 'add') {
            for (var z = 0; z < list.length; z++) {
                if (list[z] != '') {
                    var addMemGR = new GlideRecord('sys_user_grmember');
                    addMemGR.addQuery('group', groupID);
                    addMemGR.addQuery('user', list[z]);
                    addMemGR.query();
                    if (!addMemGR.next()) {
                        addMemGR.initialize();
                        addMemGR.group = groupID;
                        addMemGR.user = list[z];
                        addMemGR.insert();
                    }
                }
            }
        }
    }

})(current, previous);

 

Hope this helps!

Amit Gujarathi
Giga Sage
Giga Sage

HI @cynlink1 ,
I trust you are doing great.
Here's an adjusted version of your script with modifications to handle the kb_managers field correctly:

(function executeRule(current, previous /*null when async*/) {

    var table = 'kb_knowledge_base';
    var field = 'owner';
    var field2 = "kb_managers"; // This is a list field
    var groupId = 'ca791aabdb17201036d8af6d139619e4';
    var arrayUtil = new ArrayUtil();

    // Function to split and process kb_managers field
    function getKbManagersSysIds() {
        var sysIds = [];
        var ga = new GlideAggregate(table);
        ga.addEncodedQuery('active=true');
        ga.addNotNullQuery(field2);
        ga.groupBy(field2);
        ga.query();

        while (ga.next()) {
            var kbManagersList = ga.getValue(field2);
            if (kbManagersList) {
                var kbManagersArray = kbManagersList.split(',');
                sysIds = sysIds.concat(kbManagersArray);
            }
        }
        return sysIds;
    }

    // Get the list of owners
    var owners = [];
    var gaOwners = new GlideAggregate(table);
    gaOwners.addEncodedQuery('active=true');
    gaOwners.addNotNullQuery(field);
    gaOwners.groupBy(field);
    gaOwners.query();

    while (gaOwners.next()) {
        var ownerSysId = gaOwners.getValue(field);
        owners.push(ownerSysId);
    }

    // Get the list of knowledge managers
    var kbmanagers = getKbManagersSysIds();

    // Concatenate two arrays
    var allmanagers = owners.concat(kbmanagers);

    // Control Group Membership for Owners and Knowledge Managers
    var members = [];
    var groupMembers = new GlideRecord('sys_user_grmember');
    groupMembers.addQuery('group.sys_id', groupId);
    groupMembers.query();

    while (groupMembers.next()) {
        var userId = groupMembers.getValue('user');
        members.push(userId);
        if (!arrayUtil.contains(allmanagers, userId)) {
            groupMembers.deleteRecord();
            gs.info('User with sys_id "' + userId + '" removed from group with sys_id "' + groupId + '".');
        }
    }

    // Check the Managers array against the current group members array and insert any NEW managers
    var difference = arrayUtil.diff(allmanagers, members);
    if (difference) {
        for (var i = 0; i < difference.length; i++) {
            var newManagerSysId = difference[i];

            var newGroupMember = new GlideRecord('sys_user_grmember');
            newGroupMember.initialize();
            newGroupMember.user = newManagerSysId;
            newGroupMember.group = groupId;
            newGroupMember.insert();
            gs.info('Added user with sys_id "' + newManagerSysId + '" to group with sys_id "' + groupId + '".');
        }
    }

})(current, previous);

Was this answer helpful?


Please consider marking it correct or helpful.


Your feedback helps us improve!


Thank you!


Regards,


Amit Gujrathi



Hello Amit,

 

I apologize for my delayed response. The script is working! Yay!

 

I have a few follow-up questions for you:

1.) Should I run the business rule before or after insert and update?

cynlink1_1-1702364845307.png

 

2.) How do I prevent inactive users from being added to the group?

3.) Whenever I remove a manager from a knowledge base, I receive confirmation that the role is being removed from the user, which is expected for the named users. However, I am also seeing a message without a user's name. Should I be concerned?

 

Example: Info MessageRemoving Role from

cynlink1_0-1702364453691.png

 

Thank you in advance for your continued support!

Cyn