Box Developer Documentation
 

    Create Architecture Skeleton

    Guides Users Provision Users Create Architecture Skeleton
    Edit this page

    Create Architecture Skeleton

    Our first requirement is to copy general files and folders into each individual user's root folder on account creation. This problem has been solved within standard Linux distributions through a directory called /etc/skel, which we'll emulate with a Box specific solution here. When adding a new user in Linux, the files and folders within /etc/skel are copied to the new user's home directory.

    When creating a JWT-based Box application, a Service Account is created within the Box Enterprise. A Service Account is similar in functionality to a co-admin within a Box Enterprise, and most useful to this use case, can own, copy, and collaborate other users on files and folders. More importantly, you don't have to use a Service Account strictly for developing custom applications for users, and instead, can use a Service Account in more of an automation capacity.

    Box Platform Application Requirements

    When creating your JWT-based custom Box application for this recipe, you'll need to enable the following scopes: Manage users, Manage groups, Perform Actions as Users, and Generate User Access Tokens.

    See JWT Application Setup for more information on creating a JWT-based Box application and the scopes in a Box application.

    We'll start by creating the etc and skel folders and granting ownership of the folders to the Service Account.

    etc_skel.json
    {
      "name": "etc",
      "parent": {
        "id": "0"
      },
      "children": [
        {
          "name": "skel",
          "children": []
        }
      ]
    }
    

    The code here can optionally be reused to build any folder structure formatted as the JSON objects above demonstrate.

    Node
    "use strict";
    const fs = require("fs");
    const box = require("box-node-sdk");
    
    class BoxFolderTreeCreator {
        constructor(boxClient, options) {
            options = options || {};
            if (options.boxClient) {
                throw new Error("Must include a boxClient field.");
            }
    
            options.boxFolderTreeName = options.boxFolderTreeName || "tree.json";
    
            this.boxClient = boxClient;
            this.boxFolderTree = JSON.parse(fs.readFileSync(options.boxFolderTreeName));
            this.createdBoxFolders = [];
        }
    
        async createFolderTree(branch = null, parentFolderId = "0") {
            this.createdBoxFolders = [];
            if (Array.isArray(this.boxFolderTree)) {
                let folderTasks = [];
                this.boxFolderTree.forEach(folder => {
                    folderTasks.push(this._createFolder(folder, ""));
                });
                await Promise.all(folderTasks);
                return this.createdBoxFolders;
            } else if (typeof this.boxFolderTree === "object") {
                console.log("Is object");
                await this._createFolders(this.boxFolderTree, "");
                return this.createdBoxFolders;
            } else {
                throw new Error("Incorrectly formatted JSON folder tree.");
            }
        }
    
        async _createFolders(branch, parentFolderId = "0") {
            if (branch.parent != null && branch.parent.id != null) {
                parentFolderId = branch.parent.id;
            }
            let folder;
            try {
                folder = await this.boxClient.folders.create(parentFolderId, branch.name);
            } catch (e) {
                let existingFolderId = BoxFolderTreeCreator.handleFolderConflictError(e);
                folder = await this.boxClient.folders.get(existingFolderId);
            }
            this.createdBoxFolders.push(folder);
            if (branch.children.length <= 0) {
                console.log("No more folders to create...");
                return;
            } else {
                let createFolderTasks = [];
                branch.children.forEach(child => {
                    console.log("Creating folder...");
                    console.log(child.name);
                    createFolderTasks.push(this._createFolders(child, folder.id));
                });
                return await Promise.all(createFolderTasks);
            }
        }
    
        static handleFolderConflictError(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.length > 0
                    ) {
                        let conflict = errorBody.context_info.conflicts[0];
                        if (conflict && conflict.id) {
                            return conflict.id;
                        }
                    }
                }
            }
        }
    }
    
    let configFile = fs.readFileSync("config.json");
    configFile = JSON.parse(configFile);
    
    let session = box.getPreconfiguredInstance(configFile);
    let serviceAccountClient = session.getAppAuthClient("enterprise");
    
    let treeCreator = new BoxFolderTreeCreator(serviceAccountClient);
    
    (async () => {
        let createdFolders = await treeCreator.createFolderTree();
        console.log(createdFolders);
    })();