Google drive v3 - unable to retrieve files from particular folder Id - google-drive-api

We are trying to incorporate Google Drive as a document repository for our application. We are using Google Drive API V3 for accessing Google Drive API. In this process, we are facing few challenges for implementing some of the features. The following are the constraints.
We are trying to retrieve the folders and files only inside a particular folder. But Currently we cannot able to achieve them.
When retrieving is there any provision to order files and folders in the exact hierarchy of how it is located in the Google Drive?
When retrieving the files and folders, we could able to see the folders and files which are deleted from drive already.
Could you please help us on how to achieve them.

Simple REST API request to: https://www.googleapis.com/drive/v3/files with q parametr, where you specify the query, what you want to search.
For example:
mimeType = 'application/vnd.google-apps.folder' // list only folders
'root' in parents // only files (or folders) that are in root folder (have root in parents)
Complete guide here:
https://developers.google.com/drive/api/v3/search-files
Here you have playground, on the right side you can try the API:
https://developers.google.com/drive/api/v3/reference/files/list
The biggest issue for me was, how to pass these parameters to the URL, the magic is to encodeURIComponent (in javascript), so your complete URL gets from:
https://www.googleapis.com/drive/v3/files?q=mimeType = 'application/vnd.google-apps.folder' AND 'root' in parents
to
https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20'application%2Fvnd.google-apps.folder'%20AND%20'root'%20in%20parents
And that will Google definitely understand. Don't forget to send your google token in Authorization header, e.g.:
headers: {
Authorization: `Bearer ${user.google_token}`,
'Content-Type': 'application/json',
},

Related

Creating a Google Sheets spreadsheet in the Google Drive app data folder with the client-side API

I would like to create a Google Sheet in the Google Drive App Data folder (API docs at https://developers.google.com/drive/api/v3/appdata) using client side JS.
I can create non-Sheet files like this (after handling all the authentication stuff, as per the browser quickstart for the Sheets API):
gapi.client.drive.files.create({
resource: {
name: 'myfile.txt',
parents: ['appDataFolder'],
mimeType: 'text/plain'
},
fields: 'id'
}).then(res => {
console.log("Created OK: response was ", res);
}).catch(e => {
console.log("Creation failed: error was ", e)
})
However, if I use mimeType: 'application/vnd.google-apps.spreadsheet' then I get this error back:
reason: "notSupportedForAppDataFolderFiles",
message: "Method not supported for files within the Application Data folder."
This error message seems to be entirely undocumented. My suspicion is that this is just not allowed: you can't store Google Sheets in the App Data folder, probably because Sheets aren't really stored as files in Drive at all and they appear so through some sort of UI fakeout by the Drive team. But I have no confirmation of this.
The reason I'd like to do this is that an app which requests access to the App Data folder does not need to request access to all other files. If I can't put a Sheet in the App Data folder, then as far as I'm aware, in order to create a spreadsheet my app will need to request complete access to all the user's spreadsheets, which it completely does not need; it will use its own one and that's it. I don't want to ask for that access because users will (correctly) see that as massive overreach.
The documentation specifies:
The application data folder is automatically created when you attempt to create a file in it.
Use this folder to store any files that the user shouldn't directly interact with.
This folder is only accessible by your application and its contents are hidden from the user and from other Drive apps.
So while there is no direct information about Google sheets not being allowed in the application data folder, one can assume that a Google Sheets file does not meet the mentioned criteria.
As for scopes:
You can use the scope https://www.googleapis.com/auth/drive.file.
This is a narrow scope that gives the application only access to files that have been created by this application, see here
By using this scope, you avoid asking for access to all users files, and thus the users do not need to worry about providing this scopes to the application.

Google Docs API see Docs without knowing id

I'm creating a Chrome extension which when highlighting text anywhere will offer the user to save the highlighted text to any Doc in Google Docs. So the idea is to show a list of last 10 Google Docs and the user could save it to any of them or could search for another Doc.
I've been reading documentation on Chrome identity API, Docs API and Drive API, and they all mention that we need to know the Doc's id (which is inside the url of the Doc).
So it's not possible to display a list of Docs without knowing their actual ids? I guess it would be a security violation if an extension or an app could do this? Or I'm mistaken and it's actually possible?
P.S. This link seems to be what I was looking for (so it's possible): https://developers.google.com/drive/api/v3/reference/files/list
Answer:
Yes, you can get a list of the last 10 modified files in Google Drive using the modifiedDate, pageSize and mimeType parameters.
More Information:
You can make a Files: list query to the Drive API with parameters narrowing down your search. As you do not know the file IDs, you can search for files which have the application/vnd.google-apps.document MIME Type, and then narrow the search down by ordering by the modifiedDate and only requesting 10 results.
Code:
As I'm not 100% sure on which language you are using, I've provided a simple Apps Script example below. The relevant references can be seen below though so you can modify this to suit your coding requirements.
function myFunction() {
var searchTerms = {
orderBy: "modifiedDate",
pageSize: 10,
q: "mimeType='application/vnd.google-apps.document'"
};
for (var i = 0; i < 10; i++) {
Logger.log(Drive.Files.list(searchTerms).items[i].title);
}
}
Don't forget to enable the Advanced Drive Service for this! Also remember that the Advanced Drive service uses Drive v2, though this can be done in both Drive API v2 and Drive API v3.
References:
Google Drive API v3 - Files: list
Advanced Drive Service - Listing folders
G Suite and Drive MIME Types

How does listing files/folders inside of google drive work?

I have been reading the reference and also used the API explorer, but I cannot for the life of me manage to get a full list of what's inside a specific folder of my google drive.
As far as I understand, the following code should list all files inside the folder that has the given folderID. That does work; but only on files that I created from my app. Folders/files created with or uploaded through the web UI will not show up in the response.
const folders = await drive.files.list({
q: "'<folderID>' in parents",
trashed: false,
spaces: ['drive']
});
In a different post I found that the scope might be the issue, but as far as I know I have already given my app the highest available scope:
const SCOPES = ['https://www.googleapis.com/auth/drive'];
I appreciate any help on this matter. :)
Your symptoms are consistent with using drive.file scope instead of drive. Is it possible that you granted access using drive.file and haven't yet repeated the grant procedure with drive?
The other possible explanation is that you are in two different Drive Accounts. Many people use a Service Account because the Google docs refer to this as server-to-server, without realising that the Service Account is a totally different account to their User Account, ie. the one with the Drive UI. So your app will be uploading and reading files in the Service Account, your UI-created files are in your User Account.

Google Drive API - share(copy) my file automatically to user drive account

the scenario is like this. I have a file in Google Drive, then share it to public, but not the direct link to my file. see sample here https://ganool.ag/steve-jobs-2015-bluray-720p-ganool-ag/ | scroll down and find link https://file.rocks/file/jBH0tM97Ne (ignore the pirate movie in the link, it's just sample). When you click the link, the file will be copied to your drive account, save in a folder called File.rocks, than a subfolder with random name.
my question is, what API command used in that script? just the concept, not the complete script.
sorry for my english.
The behavior shown in that website is similar to the Save to Drive button which allows the user to save files to their Drive account from an arbitrary URL via their browser.
The technology used to upload files is similar to that used by the Google Drive web user interface. The file is downloaded to the user's browser in parts and uploaded to Google Drive as data is received.
Authorize your app to get code
exchange code for token
create client-folder-id if not exist
then use copy
for example:
POST https://www.googleapis.com/drive/v3/files/<your-file-id>/copy
Authorization: Bearer token...xxxxxx
{
"parents": [
"<client-folder-id>"
]
}

Get JSON of container-bound Google Apps-Script through Apps-Script or download

If you create a non-container bound g-apps script (i.e. not as part of a gDoc or a gSheet), you can download it (however not view as a .json directly in the browser from the link) from gDrive as a .json. If you download a gDoc or gSheet, it converts to xlsx or docx and opening these with a zip viewer shows a number of files (many of type xml) however none contain the Google version's attached scripts.
Is there a way to read script files as a .json from within another Google Apps
Script? perhaps using the Drive-API or with g-a-s. DriveApp class?
Is there a way to download or read through DriveApp, the .jsons of
container bound scripts (which are usually invisible from all but within the original gFile)?
Update
Based on Kriggs, added a Logger.log(link) and this works great for stand-alone scripts.
How about for container-bound?
for stand alone script files:
exportLinks={
application/vnd.google-apps.script+json=
script.google.com/feeds/download/export?id=[scriptId]&format=json
}
for container-bound script files, there are links to csv, sheet and pdf, but no script json.
exportLinks= {
text/csv=docs.google.com/spreadsheets/export?id=[sheetId]&exportFormat=csv,
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=
docs.google.com/spreadsheets/export?id=[sheetId]exportFormat=xlsx,
application/pdf=
docs.google.com/spreadsheets/export?id=[sheetId]&exportFormat=pdf
}
Update
In Google sheet, go to Tools->script Editor->
URL in address bar looks like:
https://script.google.com/macros/d/
[ProjectKey]/edit?uiv=2&mid=[aVeryLongAlphaNum]
this is the download json:
https://script.google.com/feeds/download/export?id=[ProjectKey]
Question is, can we use the Drive API to find [ProjectKey]
Have there been any feature requests for DriveApp/Drive-API methods to seek Project Keys in your account?
Would there be a way to test if a file has a container bound script? Then the question is, is the script included in the file size (this can be easily tested, however it is unknown to the asker at this point).
Something like this may work although it looks computationally costly:
var SizeOfFile = yourFile.getSize();//
var charsInFile = yourFile.getAsString();
var unicodeSizeReference = [];//get bytes per character array
charsInFile.sort()
//find frequency of characters then multiply from unicoseSizeReference.
//there could be other gotchas as well, however this is just testing for feasibility
var SizeOfTextInFile = [/*#of chars in file name and sheetname*/]+[/*#of chars in all sheets*/];
SizeOfTextInFile *= unicodeBytesPerCharacter;//ranges from 1 to 4
var someThreshold = 10;//bytes
var hasScript=0;
if ([SizeOfFile - SizeOfTextInFile] > someThreshold) hasScript=1
Yes you have to get it trough the Drive API with OAuth2, I used the DriveApp to get the fileId, but you can modify to use Drive api aswell. To enable the Drive API go to Resources -> Advanced Google Services, find the Drive API and turn on.
When you send a get with Drive you get back an object of the file which contains the property exportLinks, using it you fetch the URL with OAuth2 authentication (the ScriptApp.getOAuthToken()), the fetched string will be a JSON, which has the Array fileswith the colection of scripts.
function getAppsScriptAsJson( fileName ) {
var fileDrive = Drive.Files.get( DriveApp.getFilesByName( fileName ).next().getId() );
var link = JSON.parse(fileDrive)[ 'exportLinks' ][ 'application/vnd.google-apps.script+json' ];
var fetched = UrlFetchApp.fetch(link, {headers:{'Accept':'application/vnd.google-apps.script+json', "Authorization":'Bearer '+ScriptApp.getOAuthToken()}, method:'get'});
return JSON.parse(fetched.getContentText());
}
As for container bound:
DriveApp can't get it by name
It doesn't display an ID anywhere, just the project key
Drive API can't lookup by the project id, nor DriveApp
Drive API can't find by the name
There's no reference of the script from the returned object from Drive API nor the DriveApp
I guess it is pretty much incognito, doubt there's any way ATM.
You can always make a Standalone app and set it as a library for the Spreadsheet...