Once the architecture files have been defined through the etc/skel
structure in your service account, you can now use the following script to copy
anything under the skel directly to the new user's root directory.
'use strict'const box =require('box-node-sdk');const fs =require('fs');const skelFolderId ="45117847998";const userID ="275111793";let configFile = fs.readFileSync('config.json');
configFile =JSON.parse(configFile);let session = box.getPreconfiguredInstance(configFile);let serviceAccountClient = session.getAppAuthClient("enterprise");(async()=>{// The userID can be obtained when creating the user via the// API or by using the search users feature.// The skel folder ID shouldn't ever change unless it's deleted and recreated.awaitcopySkelDirectoryForUser(userID, skelFolderId, serviceAccountClient);})();asyncfunctioncopySkelDirectoryForUser(userID, skelFolderId, boxClient){// Enable iterators in case there are more than the// default limit of items under the skel directory.
boxClient._useIterators =true;// You collaborate the user temporarily on the skel directory// to copy all items into that user's root folder.let collabSkelFolder;try{
collabSkelFolder =await boxClient.collaborations.createWithUserID(userID,
skelFolderId, boxClient.collaborationRoles.EDITOR);}catch(e){// Handle that the collaboration on the skel folder could already exist.if(e.response.body.code ==='user_already_collaborator'){let collaborationsIterator =await boxClient.folders.getCollaborations(skelFolderId);let collaborations =awaitautoPage(collaborationsIterator);let results = collaborations.filter((collaboration)=>{return collaboration.accessible_by.id === userID;});
console.log(results);if(results.length >0){
collabSkelFolder = results[0];}else{thrownewError("Couldn't create newcollaboration
or located existing collaboration.");}}else{throw e;}}
console.log(collabSkelFolder);// Switching context to make calls on behalf of the user.// To access this user's root folder, the boxClient needs// to be scoped to make API calls as the user.
boxClient.asUser(userID);// Iterate over all the items under the skel directory.let skelFolderItemsIterator =await boxClient.folders.getItems(skelFolderId);let skelFolderCollection =awaitautoPage(skelFolderItemsIterator);
console.log(skelFolderCollection);// Now, as the user, copy the folders and files into// the user's root folder -- folder ID '0'.let copyTasks =[];
skelFolderCollection.forEach((item)=>{if(item.type ==='folder'){
copyTasks.push(boxClient.folders.copy(item.id,'0').catch((e)=>{let itemId =handleConflictError(e);if(itemId){
console.log(itemId);return boxClient.folders.get(itemId);}else{throw e;}}));}elseif(item.type ==='file'){
copyTasks.push(boxClient.files.copy(item.id,'0').catch((e)=>{let itemId =handleConflictError(e);if(itemId){
console.log(itemId);return boxClient.files.get(itemId);}else{throw e;}}));}else{
console.log("Unable to resolve item type to known types...");}});let copiedItems =await Promise.all(copyTasks);
console.log(copiedItems);// Switching the boxClient context back to that of the service account.
boxClient.asSelf();/*
Since the service account owns the skel directory,
boxClient needs to make API calls as the service account
to remove the temporary collaboration on the skel directory.
*/try{await boxClient.collaborations.delete(collabSkelFolder.id);
console.log("Removed collaboration on skel...");}catch(e){
console.log("Couldn't remove skel collaboration...");
console.log(e.respose.body);}functionhandleConflictError(e){if(e && e.response && e.response.body){let errorBody = e.response.body;if(errorBody.status ===409){if(errorBody.context_info
&& errorBody.context_info.conflicts
&& errorBody.context_info.conflicts){let conflict = errorBody.context_info.conflicts;if(conflict && conflict.id){return conflict.id;}}}}}functionautoPage(iterator, collection =[]){letmoveToNextItem=async()=>{let item =await iterator.next();if(item.value){
collection.push(item.value);}if(item.done !==true){returnmoveToNextItem();}else{return collection;}}returnmoveToNextItem();}}