Get the IDs of multiple files - google-drive-api

I'm looking for a way I can list the ID's of multiple files inside a folder on my Google Drive. Can this be done via a script?
I am using a script in Sheets that will format them one by one and it is time consuming to open each file and copy the ID from the URL.

Thanks, got it to output to a spreadsheet with:
function listFilesInFolder(id) {
var folder = DriveApp.getFolderById('folderidgoeshere');
var contents = folder.getFiles();
var file;
var name;
var sheet = SpreadsheetApp.getActiveSheet();
var id;
sheet.clear();
sheet.appendRow(["Name", "ID"]);
while(contents.hasNext()) {
file = contents.next();
name = file.getName();
id = file.getId()
data = [name, id]
sheet.appendRow(data);
}
};

Related

List Google drive folder contents to google sheets with only new files

Looking to learn how to improve my use of loops. Currently I need to list the names and URLS from a google drive Folder to a sheet and this is the code that I have:
Existing Code
function wthFolderContents() {
var folder_id = 'myFolderID';
var folders = DriveApp.getFolderById(folder_id)
var contents = folders.getFiles();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("SheetName");
sheet.clearContents()
sheet.appendRow( ['name', 'link'] );
var file;
var name;
var link;
var row;
while(contents.hasNext()) {
file = contents.next();
name = file.getName();
link = file.getUrl();
sheet.appendRow ( [name, link] );
with this code everytime the script is run the contents are cleared and then relisted. I am looking at a way of doing this dynamically / only update the new files so the script runs more effeciently.
Ive tried the following
New Code
function wthFolderContents2() {
var folder_id = '1vBzucZsb0SMOoHSWGtkUF-5QLQr5Fh1C';
var folders = DriveApp.getFolderById(folder_id)
var contents = folders.getFiles();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("WHTCert");
var lastRow = sheet.getLastRow()
var existing = sheet.getRange(1,1,lastRow,1).getValues()
for(i=1;i<lastRow;i++) {
var existingFilename = existing [i][0]
Logger.log(existingFilename)
while(contents.hasNext()) {
var file;
var name;
var link;
file = contents.next();
name = file.getName();
link = file.getUrl();
if (!name == existingFilename) {
sheet.appendRow ( [name, link] );
}
}
}
I cant get this to work, not sure what exactly where I have gone wrong. Hope someone can point me int he right direction!
Cheers
I believe your goal is as follows.
You want to reduce the process cost of your script.
Modification points:
In your script, appendRow is used. In this case, the process cost will become high. Ref
The search for files is run in a loop. In this case, the process cost will become high.
In your situation, it seems that you want to retrieve the file list just under the specific folder. In this case, I thought that when Drive API is used, the process cost can be reduced. In this answer, I would like to propose using Drive API in your script. When this is reflected in your script, it becomes as follows.
When Drive API is used, all values can be retrieved. So, I thought that your 1st process might be able to be used.
Modified script:
Before you use this script, please enable Drive API at Advanced Google services.
function wthFolderContents2() {
var folder_id = '1vBzucZsb0SMOoHSWGtkUF-5QLQr5Fh1C';
// Retrieve file list.
var q = `'${folder_id}' in parents and trashed = false and mimeType != '${MimeType.FOLDER}'`;
var fileList = [['name', 'link']];
var pageToken = "";
do {
var obj = Drive.Files.list({ q, maxResults: 1000, pageToken, fields: "nextPageToken,items(id,title)", corpora: "allDrives", supportsAllDrives: true, includeItemsFromAllDrives: true });
if (obj.items.length > 0) {
fileList = [...fileList, ...obj.items.map(({ id, title }) => [title, `https://docs.google.com/presentation/d/${id}/edit?usp=drivesdk`])];
}
pageToken = obj.nextPageToken;
} while (pageToken);
// Put the values to Spreadsheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("WHTCert");
sheet.clearContents();
sheet.getRange(1, 1, fileList.length, fileList[0].length).setValues(fileList);
}
When this script is run, the file list (filename and URL) is retrieved from the specific folder. And, the retrieved values to the "WHTCert" sheet.
Reference:
Files: list
Please convert this 2 script for scan folder only one subfolder and file, show folder name and link.
function wthFolderContents()
function wthFolderContents2()

Sort files Google Apps Script

I have this code in Apps Script, it gets all files of a folder (expofd) and print the ID's in the Google Sheet. But each time the code get the files in a different order and I need any kind of sort (Alphabetically by name, not by id) or whatever, but the printing in the Sheet have to be always in the same order. Also, It would be nice a code modification to filter the folder files and get only which have certain suffix.
var list = [];
list.push(['ID']);
var files = expofd.getFiles();
while (files.hasNext()){
file = files.next();
var row = []
row.push(file.getId())
list.push(row)
;
}
sh.getRange(2,2,list.length,list[0].length).setValues(list);
Thanks!
Try this
function myFunction() {
var expofd = DriveApp.getFolderById('#############') // your folder id
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var suffix = '.pdf' // adapt as necessary
var list = [];
var files = expofd.getFiles();
while (files.hasNext()) {
file = files.next();
list.push([file.getName(),file.getId()])
}
var result = [['name','id'], ...list.filter(r => r[0].includes(suffix)).sort()]
sh.getRange(1,1, result.length, result[0].length).setValues(result);
}
You will get the list sorted by name and filtered by suffix
Just in case here is the more fancy (and probably more quick) way to search files with Drive API:
function myFunction() {
var mask = '.jpg';
var folder_id = '###'; // put your folder ID instead of ###
var query = `title contains "${mask}" and trashed = false and "${folder_id}" in parents`;
var findings = Drive.Files.list({ q: query }) || [];
var table = [['name', 'id'], ...findings.items.map(f => [f.title, f.id]).sort()];
SpreadsheetApp.getActiveSheet().clear().getRange(1,1,table.length,2).setValues(table);
}
Make sure you add the Drive API in Script Editor:
Reference:
Search for files and folders with Drive.list() method

Google Script Question: Is there a way to create copies of files into multiple folders at once?

I have a spreadsheet from which I've written code to populate with the names of folders (column 1) and their IDs (column 2).
I would like to populate each of the folders listed in that spreadsheet with a copy of each of the documents contained a separate folder (a Shared Drive folder, if that matters). When I execute the code below, a copy of each document is created in the source folder (the Shared Drive folder) instead of in the destination folder (aka the folders whose IDs are captured in the spreadsheet). If it matters, each copy is labelled with a folderID from the spreadsheet. Can someone please tell me how I can get this code to create the copies inside the appropriate destination folders instead of in the source folder?
function CopiestoFolder() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getDataRange() //Get all non-blank cells
.getValues() //Get array of values
.splice(1); //Remove header line
//Define column numbers for data. Array starts at 0.
var NAME = 0;
var FOLDERID = 1;
//For each folder ID listed in spreadsheet, create a copy of
//each item in the Resume Resources folder.
for (var i = 0; i < data.length; i++) {
var name = data[i][NAME];
var folderId = data[i][FOLDERID];
var srcFolder = DriveApp.getFolderById("folder ID");
var dstFolder = folderId;
var files = srcFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
var f = file.makeCopy(dstFolder);
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
f.getParents().next().removeFile(file);
}
}
}
}
I had this problem with Script Files. Here's how I fixed. Or I should say here's how Tanaike fixed it. You will need to enable Drive API.
var res=file.makeCopy(copyName,subFldr);
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
Drive.Files.update({"parents": [{"id": subFldr.getId()}]}, res.getId(), null, {"supportsTeamDrives":true}); // Added
}
The file.makeCopy() method has 3 overloads:
//Accepts no parameters
file.makeCopy();
//Accepts a name parameter as a string
file.makeCopy(name);
//Accepts a destination parameter as an instance of a Folder class
file.makeCopy(destination);
//Accepts 2 parameters, the first of which is name (String) and the second one is destination (Folder).
file.makeCopy(name, destination);
You are trying to pass folder id instead of the actual folder, which gets interpreted as a folder name (not destination). Also, the following code means that your 'dstFolder' parameter is a string but you try to call the 'addFile()' method on it:
var folderId = data[i][FOLDERID];
var dstFolder = folderId;
dstFolder.addFile(file);
If you want to copy a file to another folder via makeCopy, you should pass a Folder as a parameter, not a folder id (a string). If you provide a string (your id) as a parameter, the script will interpret this id as the name you want the copied file to have. So you should first get the Folder out of its id, via getFolderById(id). So you should change this line:
var dstFolder = folderId;
To this one:
var dstFolder = DriveApp.getFolderById(folderId);
You are making a copy of the file before checking if the file is a Google Apps Script project. I assume you just want GAS projects to be copied, so this should be included inside the if block. Also, inside the if block you are using addFile which can also be used to copy a file to another folder (it adds the file to the desired folder). So you don't need to use both functions, they are doing basically the same (copying your file to the desired folder).
You are using removeFile, which is not necessary if you want to keep the original files in the original folders.
So the while block could be something like:
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
}
}
Finally, your full code could be like:
function CopiestoFolder() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getDataRange() //Get all non-blank cells
.getValues() //Get array of values
.splice(1); //Remove header line
//Define column numbers for data. Array starts at 0.
var NAME = 0;
var FOLDERID = 1;
//For each folder ID listed in spreadsheet, create a copy of
//each item in the Resume Resources folder.
for (var i=0; i<data.length; i++) {
var name = data[i][NAME];
var folderId = data[i][FOLDERID];
var srcFolder = DriveApp.getFolderById("folder ID");
var dstFolder = DriveApp.getFolderById(folderId);
var files = srcFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
}
}
}
}
I hope this is of any help.

Copying sheets using appscript pulls through forms

I have a script that pulls the ID of a file within a specific folder, then takes a copy and puts that into another folder then deletes it from the original folder.
However when the takes a copy it then copies any attached google forms and places them in the folder also.
Is there a way to only copy the sheet?
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Copies")
var folder = DriveApp.getFolderById('FOLDER_ID'); //Latest Copy ID
var list = [];
list.push(['Name','ID','Size']);
var files = folder.getFiles();
while (files.hasNext()){
file = files.next();
var row = []
row.push(file.getName(),file.getId(),file.getSize())
list.push(row);
}
sh.getRange(1,1,list.length,list[0].length).setValues(list);
var value = SpreadsheetApp.getActiveSheet().getRange(2, 2).getValue();
var archive = DriveApp.getFolderById("ARCHIVE_ID"); // Backup Folder
var file = DriveApp.getFileById(value);
var name = file.getName();
// makes copy of "file" with "name" at the "destination"
file.makeCopy(name, archive);
file.setTrashed(true); // sets the file in the trash of the user's Drive
}
Issue:
All files in your folder are found and processed, you're not checking for a specific file type.
Modifications:
Check the file type before you write to the array.
if (file.getMimeType() === 'application/vnd.google-apps.spreadsheet') {
var row = [];
row.push(file.getName(),file.getId(),file.getSize());
list.push(row);
}
Reference:
getMimeType()

Copy the body of all documents found in a specific folder into a Google Spreadsheet

I am trying to create a script that obtains all (Google Doc) document IDs within a Google Drive folder, grabs the body from each of those documents, and returns this into rows in this spreadsheet.
The following syntax gets me the file IDs and Names, but doesn't grab the body:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi().createAddonMenu();
ui.addItem('List all body components of files inside a folder without including subfolders', 'list_all_body_components_of_files_inside_one_folder_without_subfolders')
.addToUi();
}
function list_all_body_components_of_files_inside_one_folder_without_subfolders() {
var sh = SpreadsheetApp.getActiveSheet();
// Prompt the user for a google drive folder ID
var folderID = Browser.inputBox("Enter the folder ID to search in - It's the bit in the URL after /folders/:");
// return the folder identified by that ID number for further manipulation
var folder = DriveApp.getFolderById(folderID);
// print the list to columns A through C
var list = [];
list.push(['Body','Name','ID']);
var files = folder.getFiles();
while (files.hasNext()){
file = files.next();
var row = []
row.push(file.getBlob(),file.getName(),file.getId())
list.push(row);
}
sh.getRange(1,1,list.length,list[0].length).setValues(list);
}
I think that the problem is with file.getBlob I've tried
file.getBlob.getDataAsString(), but that returns:
TypeError: Cannot find function getDataAsString in object function getBlob() {/* */}.
How do I retrieve the text of each document body?
Since it's Google Docs that we're interested in, focus the file scan on those:
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
Then when working through the file iterator, use the file ID with DocumentApp to open the file as a Google Document - that way, the body will be readily accessible.
Updated code:
function list_all_body_components_of_files_inside_one_folder_without_subfolders() {
var sh = SpreadsheetApp.getActiveSheet();
// Prompt the user for a google drive folder ID
var folderID = Browser.inputBox("Enter the folder ID to search in - It's the bit in the URL after /folders/:");
// return the folder identified by that ID number for further manipulation
var folder = DriveApp.getFolderById(folderID);
// print the list to columns A through C
var list = [];
list.push(['Body','Name','ID']);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
while (files.hasNext()){
var fileId = files.next().getId();
var doc = DocumentApp.openById(fileId);
var row = []
row.push(doc.getBody().editAsText().getText(),
doc.getName(),
fileId)
list.push(row);
}
sh.getRange(1,1,list.length,list[0].length).setValues(list);
}