These are the sample scripts of the batch requests for Drive API using Google Apps Script.
When we want to manage the files and folders on Google Drive, we have 2 ways. One is the use of Drive service. Another is the use of Drive API. In the case of them, when we want to manage a lot of files and folders, unfortunately, both ways have no batch requests. Namely, for example, the metadata of a lot of files are changed, the methods in Class File and Files: update are required to be used in the loop. In this case, the process cost will be high. On the other hand, Drive API can use the batch requests. But in this case, in order to use this batch requests with Google Apps Script, it is required to create the request body of multipart/mixed
by each user. Because there are no methods for automatically requests the batch requests. From this situation, here, I would like to introduce the simple sample scripts for creating, updating and deleting the files and folders on Google Drive using the batch requests with Google Apps Script.
The sample scripts use BatchRequest of the Google Apps Script library.
You can see how to install BatchRequest at here.
In this sample script, the files are deleted. So when you use this, please be careful. I recommend to use a sample file.
function deleteFiles() {
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const requests = fileIds.map((id) => ({
method: "DELETE",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}`,
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
In this sample script, the files are moved to the specific folder by changing the filename. So when you use this, please be careful. I recommend to use a sample file.
function moveFilesAndChangeFileNames() {
const fileIds = [
{ id: "### fileId 1###", newName: "sample1" },
{ id: "### fileId 2###", newName: "sample2" },
{ id: "### fileId 3###", newName: "sample3" },
,
,
,
];
const sourceFolderId = "###"; // Ser source folder ID.
const destinationFolderId = "###"; // Set destination folder ID.
const requests = fileIds.map(({ id, newName }) => ({
method: "PATCH",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}?removeParents=${sourceFolderId}&addParents=${destinationFolderId}`,
requestBody: { name: newName },
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
In this sample script, the Excel files are copied to the specific folder as the Google Spreadsheet.
function copyAndConvertFiles() {
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const destinationFolderId = "###"; // Set destination folder ID.
const requests = fileIds.map((id) => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/copy`,
requestBody: {
mimeType: MimeType.GOOGLE_SHEETS,
parents: [destinationFolderId],
},
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
In this sample script, the permission is created for an user to the multiple files.
function createPermissions1() {
const fileIds = [
{
id: "### fileId 1###",
role: "reader",
type: "user",
email: "###",
},
{
id: "### fileId 2###",
role: "reader",
type: "user",
email: "###",
},
{
id: "### fileId 3###",
role: "writer",
type: "user",
email: "###",
},
,
,
,
];
const requests = fileIds.map(({ id, role, type, email }) => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions`,
requestBody: {
role: role,
type: type,
emailAddress: email,
},
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
In this sample script, the permissions are created for multiple users to a file.
function createPermissions2() {
const sourceFileId = "###"; // Set source file ID.
const fileIds = [
{ role: "reader", type: "user", email: "### email 1 ###" },
{ role: "writer", type: "user", email: "### email 2 ###" },
{ role: "writer", type: "user", email: "### email 3 ###" },
,
,
,
];
const requests = fileIds.map(({ role, type, email }) => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files/${sourceFileId}/permissions`,
requestBody: {
role: role,
type: type,
emailAddress: email,
},
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
In this sample script, the permission list is retrieved from multiple files.
function getPermissionList() {
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const requests = fileIds.map((id) => ({
method: "GET",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions`,
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(JSON.stringify(res));
}
In this sample script, all permissions are deleted from multiple files. So when you use this, please be careful. I recommend to use a sample file.
function deleteAllPermissionsFromFiles() {
// Retrieve the permission list.
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const requests1 = fileIds.map((id) => ({
method: "GET",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions?fields=*`,
}));
const data = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests1,
});
const ownerEmail = Session.getActiveUser().getEmail();
const list = data.reduce((ar, { permissions }, i) => {
permissions.forEach(({ id, emailAddress }) => {
if (emailAddress != ownerEmail)
ar.push({ id: fileIds[i], permissionId: id });
});
return ar;
}, []);
// Delete all permissions from all files.
const requests2 = list.map(({ id, permissionId }) => ({
method: "DELETE",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions/${permissionId}`,
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests2,
});
console.log(res);
}
In this sample script, the permissions of multiple files are updated. The permissions of user of "### email address ###"
are modified. So when you use this, please be careful. I recommend to use a sample file.
function changePermissionsOfFiles() {
// In this case, the role of the usef of email is changed from 'reader' to 'writer' for all files of fileIds.
const change = { role: "writer", email: "### email address ###" };
// Retrieve the permission list.
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const requests1 = fileIds.map((id) => ({
method: "GET",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions?fields=*`,
}));
const data = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests1,
});
const list = data.reduce((ar, { permissions }, i) => {
permissions.forEach(({ id, emailAddress }) => {
if (emailAddress == change.email)
ar.push({ id: fileIds[i], permissionId: id });
});
return ar;
}, []);
// Delete all permissions from all files.
const requests2 = list.map(({ id, permissionId }) => ({
method: "PATCH",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions/${permissionId}`,
requestBody: { role: change.role },
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests2,
});
console.log(res);
}
In this sample script, the owner of files are transferred to the user of "### email address ###"
. So when you use this, please be careful. I recommend to use a sample file.
When I tested this at January 31, 2020, an error like there is no function to change the owner of this item yet (currently under development)
occurred. But now, I could confirm that this got to be able to be used. By this, the owner of a lot of files can be transferred by reducing both the process cost and the quota cost.
function changeOwnerOfFiles() {
const email = "### email address ###"; // Please set the email you want to give the owner permission.
const fileIds = [
"### fileId 1###",
"### fileId 2###",
"### fileId 2###",
,
,
,
];
const requests = fileIds.map((id) => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions?transferOwnership=true`,
requestBody: {
role: "owner",
type: "user",
emailAddress: email,
},
}));
const res = BatchRequest.EDo({
batchPath: "batch/drive/v3",
requests: requests,
});
console.log(res);
}
- When
sendNotificationEmail=false
is used, an error ofThe sendNotificationEmail parameter is only applicable for permissions of type 'user' or 'group', and must not be disabled for ownership transfers.
occurs. So please be careful this.
-
At the batch requests, 100 API requests can be run with the asynchronous process as one API call.
- When the library of BatchRequest is used, all requests can be processed in the library, even when the number of your requests is more than 100.
-
When you manage a lot of files using Drive API, please be careful of Quotas for Google Services. Ref
- Files: delete
- Files: update
- Files: copy
- Permissions: create
- Permissions: list
- Permissions: delete
- Permissions: update
If you have any questions or comments, feel free to contact me.
-
v1.0.0 (June 15, 2020)
- Initial release.