I am using a Google App Script to automate the creation of some Google Accounts inside our of our domain. I have been having a little trouble with some of the API calls and such, however this question is more related to whether or not the Drive API gives me the ability to do something. I have code below that adds editor permissions to the new user for their needed Shared Drives, however I would like to give them 'Content Manager' access to the Shared Drive. From the documentation I have looked at it, it does not seem like this is possible using the Google Drive API however I wanted to ask here to make sure I am not missing something when proceeding with the rest of my automation.
switch(ssValues[i][9]){
case "Accounting":
AdminDirectory.Members.insert(groupMember, "notourcompany");
DriveApp.getFolderById("TH1SDR!v3").addEditor(email);
break;
Does not matter if I need to use a different method or another API to achieve this functionality, I just want to know if it is possible to do this using their API's or SDK's through an App Scripts project.
Documentation:
Folder Class-https://developers.google.com/apps-script/reference/drive/folder
Drive API - Drives - https://developers.google.com/drive/api/v3/reference/drives
Drive API - Permissions - https://developers.google.com/drive/api/v3/reference/permissions
It should be possible to manage users over a Shared Drive utilizing the Drive API. The important thing is that you would need to give access over the API and make sure the parameter or argument for supportsAllDrives is set to true.
There is a sample Java code over the official documentation that shows how you can add permissions to a Shared Drive that is "orphaned" or you can test it over it in the permission.create documentation:
You can test it yourself over here.
As you can see in the image, the function is very similar to the code that was created on an old thread utilizing the Drive API V2, however it is using the argument supportsTeamDrive. Sample code that could be edited:
Edit:
I have updated the code based on the one suggested from the thread to a more simplify version.
// Using Apps Script with Advance Google Services v2 of the Drive API enable
function insertPermission() {
const sharedid= 'sharedDriveID' //ID of the Shared Drive
var resource = {
// enter email address here
value: 'emailtest#domain.com',
type: 'user',
// choose from: "owner" or "fileOrganizer". File Organizer would basically be the contentManager of a SharedDrive.
role: 'fileOrganizer'
};
var optionalArgs = {
sendNotificationEmails: false,
supportsAllDrives: true
};
Drive.Permissions.insert(resource, sharedid, optionalArgs);
}
You can review the thread and code here.
References
https://developers.google.com/drive/api/v3/reference/permissions/create
https://developers.google.com/drive/api/guides/manage-shareddrives
I agree with Ricardo Jose Velasquez Cruz. I'm a super admin in my org and this solution finally allowed it to work for me. I had to tweak the optionalArgs to include useDomainAdminAccess.
// Using Apps Script with Advance Google Services v2 of the Drive API enable
function insertPermission() {
const sharedid= 'sharedDriveID' //ID of the Shared Drive
var resource = {
// enter email address here
value: 'emailtest#domain.com',
type: 'user',
// choose from: "owner" or "fileOrganizer". File Organizer would basically be the contentManager of a SharedDrive.
role: 'fileOrganizer'
};
var optionalArgs = {
useDomainAdminAccess: true,
sendNotificationEmails: false,
supportsAllDrives: true
};
Drive.Permissions.insert(resource, sharedid, optionalArgs);
}
Related
I recently visited a website which gave me a google drive link to access the content but when I tried to open the link it said permission denied. So I signed up at that website and now the drive link opened fine.
So what I observed is the website shared the drive content with users who had signed up.
So I am curious How do you implement this ? i.e How do you provide read access to
only those users that signed up at your website?
When you are the owner of a shared drive, you can easily manage the members of it - either adding and/or removing them and changing the permissions for each of them.
This can be done using the UI of Google Drive:
But it can also be done programmatically as well by making use of the Drive API and of the following request:
POST https://www.googleapis.com/drive/v3/files/fileId/permissions
Code snippet
var newMember = {
type: 'user',
role: 'reader',
emailAddress: 'user#example.com'
};
driveService.permissions.create({
resource: newOrganizerPermission,
fileId: 'driveId',
useDomainAdminAccess: true,
supportsAllDrives: true,
fields: 'id'
}, callback);
So for example, whenever a new member is being registered, a script with the instructions above is run and the email address is added to the viewers of the shared drive.
Reference
Drive API Permissions:create;
Manage shared drive users and activity.
I am trying to create a new file in a shared drive using google apps script so that other people using the shared drive can also access the file. Is there a method on DriveApp that allows me to do that?
I have tried using DriveApp.getFoldersByName but this is for the root folder in my private drive only.
You need to use the Advanced Drive Service based on the Drive API
The method Drive.Drives.insert allows you to specify the Drive Id.
Keep in mind that for shared drives, you need to specify the
additional parameter supportsAllDrives: true. Also, you need to enable the Advanced Drive Service before using.
Sample:
function myFunction() {
var optionalArgs={supportsAllDrives: true};
var resource = {
title: 'mySharedFile',
mimeType: 'application/pdf',
parents:[{
"id": "ID OF THE SHARED DRIVE"
}]
}
Drive.Files.insert(resource, null, optionalArgs)
}
I'm trying to build up the full path to a document in a team drive using a script. The code looks like this:
var path = [ ]
var folder = id.getParents()
while (folder && folder.hasNext()) {
var f = folder.next()
path.unshift(f.getName())
folder = f.getParents()
}
This script is bound to a document for testing.
But when I get to the root, instead of returning the actual name of the Team Drive, such as "Accounting" or "Marketing" it instead returns "Team Drive". I need to know the actual name of the Team Drive, why am I not getting this info? If I run this in a script bound to a document in My Drive, it instead says "My Drive" at the root - this at least makes sense, because that's the actual name I see in the browser. In Team Drive, the root is actually "Team Drives" not "Team Drive".
Because Team Drives are implemented differently than "regular" Google Drive "folders", the built-in DriveApp is not guaranteed to work properly for all actions that deal with them. It is possible that at some point DriveApp will be updated to fully support Team Drives, but there are a lot of sensible things that Google still has yet to do ;)
Instead, use the "advanced service" Drive, which is a client application that implements version 2 of the Drive REST API, and allows properly handling Team Drive information. As an "advanced service", you must enable this service before you can use it.
To build the full path of a Team Drive item using only the advanced service:
function getTeamDrivePath(fileId) {
// Declare we know how to handle Team Drive items, and that they be included in responses.
var params = {
supportsTeamDrives: true,
includeTeamDriveItems: true
};
// Return only the fields we want, instead of the whole `File` resource.
params.fields = "id,title,parents/id"
// In a Team Drive, a file can have only one parent folder (e.g. "normal" filesystems).
// (parent.isRoot is never true for Team Drive folders so it is not used.)
var path = [], file;
do {
file = Drive.Files.get(fileId, params);
path.unshift(file.title);
fileId = file.parents.length ? file.parents[0].id : null;
} while (fileId);
// Since we also added the file, the last element of the path array is the filename.
path.pop();
// A Team Drive is subject to different permissions than files, and thus its name must be
// obtained via the Team Drives resource. Since `file` points to the Team Drive, use it:
// Requesting incorrect fields will result in an API error, so request the proper ones:
params.fields = "name"
var td = Drive.Teamdrives.get(file.id, params);
path[0] = td.name;
return path;
}
More reading about Team Drives and handling associated with them is available on the Drive REST API reference. I link the v2 versions since they are what is available via Apps Script's "Advanced Service", but the v3 version should be used for 3rd party applications using the client libraries.
Important resources:
About Team Drives
Enabling Team Drives support
Team Drives API Reference
Enabling "Advanced Services" in Apps Script
API Best Practices: Partial Resources & "fields"
My App for Google Drive is by Google Script.
When I select files in Drive and then call my App, an official "state parameter" will be sent into my App for further digestion. However, the official document is not clear enough for its setting. I need to collect its info from different area like Google I/O video and examples. Is there a good site to introduce it?
Official Site: https://developers.google.com/drive/web/integrate-open
Especially, for the process, User select files in a Active folder => Run App => App save back files to Active Folder ... but this is the problem. How can I know which is the active folder through the state parameter? Any suitable command?
N.B. It is meaningless to use MyFile.getFolders() command, since one file can belong to several folders, and I cannot distinguish which one is "Active" folder.
The documentation shows some code that gets the id after the file is picked from a Google Drive:
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
alert('The user selected: ' + fileId);
}
}
I'm testing out the Google Drive API. The test script does the HTTP GET to access the Files->List API but somehow I always get an empty list in items. I have hundreds of files in my google drive so the result is unexpected. The HTTP response is shown below.
{
"kind": "drive#fileList",
"etag": "\"VEU5fga3uYlZRf0pG-N1kS4iWP4/Kxo5eGvPKynWfroe9v5L5T43-n0\"",
"selfLink": "https://www.googleapis.com/drive/v2/files?maxResults=5",
"items": []
}
To allow service account to access the files in my own Google Drive, I have to give permission to the email address of the service account. Once the permissions are setup correctly, the list gets populated with the files that the service account is allowed to access.
Google does not make it clear in their documentation. After half a day of trying to modify everything that might help, I discovered that you need to share the file with the email described in your service account json file.
For example, I have a Google Slide file in my personal Google Drive, and I want it to be readable by Google Drive API, I'll have to share this Slide file with xxx#xxx.iam.gserviceaccount.com listed in the json service account file.
Then the following code snippet should return the shared Slide file:
import {google} from 'googleapis'
const credentials = require("./credentials.json");
async function main() {
const scopes = [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/presentations',
]
const auth = new google.auth.JWT(
credentials.client_email,
null,
credentials.private_key,
scopes,
)
const drive = google.drive({
version: 'v3',
auth
})
const res = await drive.files.list()
console.log(res.data)
}
main()
{
kind: 'drive#fileList',
incompleteSearch: false,
files: [
{
kind: 'drive#file',
id: 'xxxxx',
name: 'xxxxx',
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
},
]
}
This usually means you've authenticated with a scope that doesn't give you permission to see those files.
For example, the scope https://www.googleapis.com/auth/drive.file only provides access to files created or opened by the app. You won't be able to access files created in the Google Drive interface or by other apps.
If you want to access all the files, you'll have to use another scope. https://www.googleapis.com/auth/drive, for example, gives you full, permissive scope to access all of a user's files.
You can find information about the available scopes here. Use it to pick the right scope for your app.
it's enough to include https://www.googleapis.com/auth/drive.readonly.metadata scope to list files