Google Apps Script ➡️ Utils. Create folders and copy files fast⚡

Max Makhrov
5 min readSep 8, 2023

This article is a try to adopt the library written by Tanaike:

🌟 Please Star ↑ Repository 🌟. It also helps in making the project more visible to others who might benefit from it.

You may also benefit from reading the original report by Tanaike with more example use cases.

Bonus

See the “More examples” section at the end.

Usage

Enable Drive API to use the code:

↑ Apps Script Editor. Click “+” and select Drive API

The full code includes the library, you may copy it from my repo.

I have created a new streamlined code that makes the process of using Batch Updates much easier — particularly when creating folders. Code to run:

/**
* @typedef {Object} BatchFolderInfo
* @property {String} id
* @property {String} name
* @property {String} mimeType
* @property {String} teamDriveId
* @property {String} driveId
*/

/**
* Also works with Shared Drives!
*
* @param {String} folderId
* @param {Array<String>} folderNames
*
* @returns{Array<BatchFolderInfo>}
*/
function batchCreateFolders_(folderId, folderNames) {
var batchReqs = []
for (var i = 0; i < folderNames.length; i++) {
batchReqs.push({
method: "POST",
endpoint: "https://www.googleapis.com/drive/v3/files?supportsAllDrives=true",
requestBody: { name: folderNames[i], mimeType: MimeType.FOLDER, parents: [folderId] }
});
}
var result = EDo({ batchPath: "batch/drive/v3", requests: batchReqs });
return result;
}

Test usage:

function test_batchFolderCreation() {
var folderNames = [
'boo',
'foo',
'poo',
'baz',
];
var folderId = 'FOLDER_ID';
var res = batchCreateFolders_(folderId, folderNames);
console.log(res);
}

The speed is really shocking fast!

Speed up!

When interacting with Google’s APIs, each call to an API normally consumes one quota. However, by using a technique called batch requests, we can call multiple APIs using just one quota. This results in faster execution of tasks as more API calls can be made within the same quota limit. Essentially, it reduces the amount that the system has to communicate back and forth between the server and the API, improving the speed of the overall operation.

For instance, suppose we want to update several files stored on Google Drive. Without batch updates, each file would require a separate API call, each consuming one quota. If you had to update a hundred files, that would mean a hundred API calls!

But with batch updates, we send all the update requests together in one single API call. This means regardless of whether you’re updating two files or twenty, it only counts as one call against your quota. Thus, tasks are done quicker and more efficiently.

However, batch requests do have limitations. For instance, they can only include requests to a single kind of API (so you can’t mix calls to the Drive API and Gmail API in the same batch), and the order of processing is not guaranteed because the requests are processed asynchronously (meaning they’re all processed at the same time, rather than one after another).

In summary, using batch updates when making API calls can significantly increase the speed of tasks by allowing multiple requests to be processed in a single quota. This is especially advantageous when dealing with large tasks that involve multiple API calls.

Photo by Sarda Bamberg on Unsplash

About the Code

Let’s delve deeper into the functionality and facets of this code.

With this code and the function batchCreateFolders_, developers can send an array of names in the ‘folderNames’ parameter. Simultaneously, ‘folderId’ serves to identify the parent directory where these new folders should reside.

The process is simple; for each name in the folderNames array, a request is created and pushed into the batchReqs array. Each request is preconfigured to use the POST method and sent to the Google Drive V3 files endpoint.

In this request, the supportsAllDrives query parameter is set to true, which means our process will also function for Google Shared Drives in addition to the standard Google Drive. The request body consists of the folder’s name, the ‘mimeType’ set as FOLDER to identify it as such, and the parents array consists of the folderId that we specified at the beginning.

Once all requests are set up, they are used as parameters for the EDo function, which executes all requests in a batch. This is a key aspect because it allows multiple tasks to be manipulated and committed simultaneously through one HTTP request, instead of doing so individually for each instruction.

Finally, the batchCreateFolders_ function returns the result, which includes the ID, name, mimeType, teamDriveId, and driveId for each newly created folder. Hence, it’s a versatile tool that aids in manually sifting through the information post folder creation.

With just an array of folders and a desired location, one can easily create multiple desired folders in one fell swoop, providing you with the results and necessary information in one single output.

This code intends to ease developers’ lives by handling batch updates more intuitively, without compromising on efficiency, speed, or accuracy.

More examples

This code is not a batch request, it uses a single request to retrieve files from a given folder:

/**
* @typedef {FolderInfo}
* @property {String} id
* @property {String} title
*/
/**
* https://developers.google.com/drive/api/reference/rest/v3/files/list
*
* @param {String} folderId
*
* @returns {Array<FolderInfo>} info
*/
function driveAppListFiles_(folderId) {
var request = {
q: `'${folderId}' in parents and trashed=false and mimeType!='application/vnd.google-apps.folder'`,
fields: "items(id,title)",
supportsAllDrives: true,
includeItemsFromAllDrives: true
};
var list = Drive.Files.list(request).items;

Drive.Files.list()
return list;
}

Use the function above to copy files from 1 folder to another:

/**
* @param {String} folderIdFrom
* @param {String} folderIdTo
*
* @returns {Array<BatchFileInfo>} copied files
*/
function batchCopyFiles_(folderIdFrom, folderIdTo) {

var files = driveAppListFiles_(folderIdFrom);

var requests = files.map(({id, title}) => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/copy?supportsAllDrives=true`,
requestBody: {parents: [folderIdTo], name: title},
}));
var result = EDo({batchPath: "batch/drive/v3", requests});
return result;
}

***

This article is part of ➡️Apps Script Utils Project.
All the code from this article is here.

--

--

Max Makhrov

Google Sheets Developer, master of Online Accounting