Hi Andrew
I had a look at the Code Studio Signal Action for “Group Sync - Send All” and it had 95% of the coding I needed to get it to work. Thanks
I’ll run through quickly what I did in case anyone else wants to do something similar.
See attachment
I copied the code studio signal action for “Group Sync - Send All” and created a new code studo signal action named “Netcall User Privilege Sync - Send All” with the details shown, basing it on the original code - This was on Central.
/*-------------------------------------------------------
Script to sync user privileges by sending batches of
internal users' details to remote applications.
-------------------------------------------------------*/
// Fetch all remote applications and their last sync date
// This list will be used to update user privileges
var applicationList = cs.search({
'base_object_id': cs.ref('obj_remote_applications'), // Reference to remote applications
'selects': [
':id', // ID of the remote application
'remote_application_name', // Name of the remote application
'remote_application_api_endpoint', // API endpoint for communication
'remote_application_api_token', // API token for authentication
'remote_application_last_group_and_membership_sync_datetime' // Last sync date
],
'return': 'data'
});
cs.log('***** Netcall User Privilege Sync - Send All *****');
cs.log('Applications to Update: ' + applicationList.length); // Log the number of applications to update
// Fetch all internal users that need to be synced
var internalUserList = cs.search({
'base_object_id': cs.ref('obj_users'), // Reference to internal users object
'selects': [
':id', // User ID
'internal_user_username', // Username
'internal_user_forename', // First name
'internal_user_surname', // Last name
'internal_user_email_address', // Email address
'internal_user_mobile_number', // Mobile number
'internal_user_timezone' // Timezone of the user
],
'order': [{'field_path': ':id', 'direction': 'ASC'}], // Order by user ID in ascending order
'return': 'data'
});
// Set batch size to control the number of users processed in each batch
const batchSize = 50; // Max number of users in a single batch
var batchCount = Math.floor(internalUserList.length / batchSize); // Total number of batches
cs.log('Internal user batch count: ' + (batchCount + 1)); // Log the number of batches (1-indexed)
// Initialize empty arrays for each batch
// This creates an array of arrays, where each sub-array will hold a group of users
var batches = Array.from({ length: batchCount + 1 }, () => []); // Create (batchCount + 1) empty arrays
cs.log('There are ' + internalUserList.length + ' internal users in ' + (batchCount + 1) + ' batches');
// Define the structure of the payload to be sent in the API request
var internalUserData = {
"payload": {
"function": "", // Will be set to the action to perform
"data": [] // Will contain the actual batch of user data
}
};
// Loop through all internal users and assign them to batches
internalUserList.forEach((user, index) => {
// Retrieve the user's role from the user record
var userRole = cs.record(user[':id']).get(cs.ref('internal_user_userrole'), 'displayable');
// Prepare the current user's data in a structured format
var currentUser = {
'central_user_id': user[':id'], // Central user ID
'username': user[cs.ref('internal_user_username')], // Username
'user_role': userRole, // User's role
'forename': user[cs.ref('internal_user_forename')], // First name
'surname': user[cs.ref('internal_user_surname')], // Last name
'email_address': user[cs.ref('internal_user_email_address')], // Email address
'mobile_number': user[cs.ref('internal_user_mobile_number')], // Mobile number
'timezone': user[cs.ref('internal_user_timezone')] // Timezone
};
// Determine which batch the current user belongs to
var currentBatch = Math.floor(index / batchSize);
// Add the user to the appropriate batch
batches[currentBatch].push(currentUser);
});
// Loop through each remote application and send the batch data
applicationList.forEach(app => {
// Extract application details (name, endpoint, and API token)
var appName = app[mats.ref('remote_application_name')]; // Application name
var endpoint = app[mats.ref('remote_application_api_endpoint')]; // API endpoint for sending requests
var token = app[mats.ref('remote_application_api_token')]; // API token for authentication
// Log details of the current application being processed
cs.log(`\nApp Name: ${appName}`);
cs.log(`Endpoint: ${endpoint}`);
cs.log(`Token: ${token}`);
cs.log('----------------------------------------------------------------------------------');
// Loop through each batch and send it to the current application
batches.forEach((batch, batchIndex) => {
// Set the function to execute within the remote application
internalUserData['payload']['function'] = 'set_netcall_user_privilege';
// Assign the current batch of user data to the payload
internalUserData['payload']['data'] = batch;
// Log the details of the payload being sent
cs.log(`Payload function: ${internalUserData['payload']['function']}`);
cs.log('Sending payload: ' + JSON.stringify(internalUserData));
// Send the batch data to the application using a POST request
var response = cs.curl(endpoint, JSON.stringify(internalUserData), {
verb: 'POST', // HTTP method
headers: {
'API-Authentication': token, // Use the API token for authentication
'Content-Type': 'application/json', // Specify that the payload is in JSON format
'Accept': 'application/json, multipart/form-data' // Accept responses in JSON or form-data
}
});
// Log the response from the API
cs.log('Response: ' + JSON.stringify(response));
});
});
This code above (code studio signal action) is called from a button the Admin > Groups page named Netcall User Privilege Sync - Send All.
The button event triggers the rule “Netcall User Privilege Sync - Send All.”
The event response fires the rule “Netcall User Privilege Sync - Send All.”
The rule triggers the Code studio signal action “Netcall User Privilege Sync - Send All”.
Which in turn triggers the API Function “set_netcall_user_privilege” for each user that matches, for each host.
This checks if the user is a match, it then triggers the event which fires the Rule I want to run against a User object.
So on Central we have a
- Code Studio Signal Action - Netcall User Privilege Sync - Send All
- Rule & Event & Button to trigger (with the same name)
On each host we have a
- API Function named - set_netcall_user_privilege
- Event that is triggered by a match in the User API function search
Note I haven’t copied the “Netcall User” privilege setting for a user, I merely run the same rule on each host that I run on Central that sets this privilege. I may update this to copy the value in Central.
Here is API Function - set_netcall_user_privilege that we need on each host.
Basics Tab
I didnt need all these fields, but helped to see the users details when developing
Request Data
Response Data
I hope this explains enough to help someone.
Thanks for pointing me in the right direction Andrew, the code above is not completed but it is a good start.
JonathanFS