Unclear how to access "shared folders" from "shared drives" vs. shared
Encountering issues where googledrive is unable to usefully access anything inside a shared FOLDER that comes from a shared drive. Permissions as Content Manager. Limited to these specific shared folders--full shared drives work fine using the usual techniques, as do shared folders that do not come from a shared drive.
This appears similar to #402, but the ultimate guidance there does not seem to work. Example below:
require(googledrive)
#> Loading required package: googledrive
drive_find(type = "folders")
# (not run for brevity)
# drive_find() output doesn't include any of several folders shared from shared drive(s)
# (Does list other shared folders from non-shared-drive accounts, as well as usual folders):
# ID of a shared folder from a shared drive (obtained from webpage, masked here and below):
folder_id <-
"[[folderID]]"
# Get dribble for folder using ID (this DOES work fine):
folder_dribble <-
as_id(folder_id) |>
drive_get()
# Dribble seems to contain the ID of a Shared Drive (masked again)
(drive_id <-
folder_dribble$drive_resource[[1]]$driveId)
#> [1] "[[driveID]]"
# But, trying to search using the dribble, per guidance in #402, doesn't work:
drive_ls(folder_dribble)
#> Error in `map()`:
#> ℹ In index: 1.
#> Caused by error in `.f()`:
#> ! Client error: (404) Not Found
#> Shared drive not found: [[driveID]]
#> • message: Shared drive not found: [[driveID]]
#> • domain: global
#> • reason: notFound
#> • location: driveId
#> • locationType: parameter
#> Backtrace:
#> ▆
#> 1. └─googledrive::drive_ls(folder_dribble)
#> 2. ├─rlang::exec(drive_find, !!!params)
#> 3. └─googledrive (local) `<fn>`(shared_drive = `<drv_id>`, q = "('[[folderID]]' in parents)")
#> 4. ├─base::append(params, handle_shared_drives(shared_drive, corpus))
#> 5. └─googledrive:::handle_shared_drives(shared_drive, corpus)
#> 6. ├─googledrive::as_shared_drive(shared_drive)
#> 7. └─googledrive:::as_shared_drive.drive_id(shared_drive)
#> 8. └─googledrive::shared_drive_get(id = x)
#> 9. ├─googledrive::as_dribble(map(as_id(id), get_one_shared_drive_id))
#> 10. └─purrr::map(as_id(id), get_one_shared_drive_id)
#> 11. └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
#> 12. ├─purrr:::with_indexed_errors(...)
#> 13. │ └─base::withCallingHandlers(...)
#> 14. ├─purrr:::call_with_cleanup(...)
#> 15. └─googledrive (local) .f(.x[[i]], ...)
#> 16. └─gargle::response_process(response)
#> 17. └─gargle:::gargle_abort_request_failed(...)
#> 18. └─gargle:::gargle_abort(...)
#> 19. └─cli::cli_abort(...)
#> 20. └─rlang::abort(...)
# Permissions on the shared folder in question, in case it's relevant:
folder_dribble$drive_resource[[1]]$capabilities |>
unlist() |> tibble::enframe() |> print(n = Inf)
#> # A tibble: 35 × 2
#> name value
#> <chr> <lgl>
#> 1 canAddChildren TRUE
#> 2 canAddFolderFromAnotherDrive FALSE
#> 3 canChangeCopyRequiresWriterPermission FALSE
#> 4 canChangeSecurityUpdateEnabled FALSE
#> 5 canChangeViewersCanCopyContent FALSE
#> 6 canComment TRUE
#> 7 canCopy TRUE
#> 8 canDelete FALSE
#> 9 canDeleteChildren FALSE
#> 10 canDownload TRUE
#> 11 canEdit TRUE
#> 12 canListChildren TRUE
#> 13 canModifyContent TRUE
#> 14 canModifyContentRestriction FALSE
#> 15 canModifyLabels FALSE
#> 16 canMoveChildrenOutOfTeamDrive FALSE
#> 17 canMoveChildrenOutOfDrive FALSE
#> 18 canMoveChildrenWithinTeamDrive TRUE
#> 19 canMoveChildrenWithinDrive TRUE
#> 20 canMoveItemIntoTeamDrive FALSE
#> 21 canMoveItemOutOfTeamDrive FALSE
#> 22 canMoveItemOutOfDrive FALSE
#> 23 canMoveItemWithinTeamDrive TRUE
#> 24 canMoveItemWithinDrive TRUE
#> 25 canMoveTeamDriveItem FALSE
#> 26 canReadLabels FALSE
#> 27 canReadRevisions TRUE
#> 28 canReadTeamDrive FALSE
#> 29 canReadDrive FALSE
#> 30 canRemoveChildren FALSE
#> 31 canRename TRUE
#> 32 canShare FALSE
#> 33 canTrash TRUE
#> 34 canTrashChildren TRUE
#> 35 canUntrash FALSE
Created on 2023-07-18 with reprex v2.0.2
Tunneling down, the failed API request looks like this:
$method
[1] "GET"
$url
[1] "https://www.googleapis.com/drive/v3/drives/[[driveID]]?fields=%2A"
$body
named list()
$token
<request>
Auth token: Gargle2.0
(above was passed to request_make() from within get_one_shared_drive_id())
Likely relatedly, it's not possible to directly reference anything about the shared drive the shared folders come from:
# Not run--this will include full shared drives, but not individual folders from shared drives:
# shared_drive_find()
# Using the drive_id gets a not found:
shared_drive_get(
id = drive_id
)
#> Error in `map()`:
#> ℹ In index: 1.
#> Caused by error in `.f()`:
#> ! Client error: (404) Not Found
#> Shared drive not found: [[driveID]]
#> • message: Shared drive not found: [[driveID]]
#> • domain: global
#> • reason: notFound
#> • location: driveId
#> • locationType: parameter
#> Backtrace:
#> ▆
#> 1. └─googledrive::shared_drive_get(id = "[[driveID]]")
#> 2. ├─googledrive::as_dribble(map(as_id(id), get_one_shared_drive_id))
#> 3. └─purrr::map(as_id(id), get_one_shared_drive_id)
#> 4. └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
#> 5. ├─purrr:::with_indexed_errors(...)
#> 6. │ └─base::withCallingHandlers(...)
#> 7. ├─purrr:::call_with_cleanup(...)
#> 8. └─googledrive (local) .f(.x[[i]], ...)
#> 9. └─gargle::response_process(response)
#> 10. └─gargle:::gargle_abort_request_failed(...)
#> 11. └─gargle:::gargle_abort(...)
#> 12. └─cli::cli_abort(...)
#> 13. └─rlang::abort(...)
# Trying to search anything within it does the same:
drive_find(
shared_drive = drive_id
)
#> Error in `handle_shared_drives()`:
#> ! Can't find the requested `shared_drive`.
#> Backtrace:
#> ▆
#> 1. └─googledrive::drive_find(shared_drive = "[[driveID]]")
#> 2. ├─base::append(params, handle_shared_drives(shared_drive, corpus))
#> 3. └─googledrive:::handle_shared_drives(shared_drive, corpus)
#> 4. └─googledrive:::drive_abort("Can't find the requested {.arg shared_drive}.")
#> 5. └─cli::cli_abort(message = message, ..., .envir = .envir)
#> 6. └─rlang::abort(...)
Created on 2023-07-18 with reprex v2.0.2
Ideas? I can't tell whether this is an API limitation, a sharing configuration issue, me missing something, or what.
I haven't fully processed all of the above, but in the name of giving you some ideas, I would look very hard at the corpus argument of drive_find() and other functions that ultimately call drive_find(). If you haven't already, I would also read the docs on shared drives:
https://googledrive.tidyverse.org/reference/shared_drives.html
Just want to chime in here that I am having similar problems that I cannot get to the bottom of.
In my case, I have access to a shared folder that is not part of a shared drive, i.e. the folder's parent is not shared, and this folder appears under "Shared with me" but cannot be accessed via "Shared drives" on the browser GUI.
Now
dd <- googledrive::drive_get(path = "https://drive.google.com/drive/folders/<ID>")
returns a valid dribble with one row. But
googledrive::drive_ls(path = dd, corpus = "allDrives")
and
googledrive::drive_ls(path = dd, corpus = "domain")
both error with:
> rlang::last_trace()
<error/purrr_error_indexed>
Error in `map()`:
ℹ In index: 1.
Caused by error in `.f()`:
! Client error: (404) Not Found
Shared drive not found: 0AEmDcn0Ku6o9Uk9PVA
• message: Shared drive not found: 0AEmDcn0Ku6o9Uk9PVA
• domain: global
• reason: notFound
• location: driveId
• locationType: parameter
---
Backtrace:
▆
1. └─googledrive::drive_ls(path = dd, corpus = "allDrives")
2. ├─rlang::exec(drive_find, !!!params)
3. └─googledrive (local) `<fn>`(corpus = "allDrives", shared_drive = `<drv_id>`, q = "('1BFePA5dltXqdwY1X7Ng_Xal4e7zaZLUM' in parents)")
4. ├─base::append(params, handle_shared_drives(shared_drive, corpus))
5. └─googledrive:::handle_shared_drives(shared_drive, corpus)
6. ├─googledrive::as_shared_drive(shared_drive)
7. └─googledrive:::as_shared_drive.drive_id(shared_drive)
8. └─googledrive::shared_drive_get(id = x)
9. ├─googledrive::as_dribble(map(as_id(id), get_one_shared_drive_id))
10. └─purrr::map(as_id(id), get_one_shared_drive_id)
11. └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
12. ├─purrr:::with_indexed_errors(...)
13. │ └─base::withCallingHandlers(...)
14. ├─purrr:::call_with_cleanup(...)
15. └─googledrive (local) .f(.x[[i]], ...)
The ID 0AEmDcn0Ku6o9Uk9PVA is not the same as the folder <ID> that I am passing to drive_get. If I'm understanding correctly, I think it's the ID of the drive in which the shared folder sits, but to which I do not have access.
I'll add my experience to this. The University of a colleague that hosted a Shared Drive for a project required them to consolidate all Shared Drives under a single Shared Drive and convert them to essentially shared folders.
My goal is to use drive_ls() to query the contents of a shared folder that I have "content manager" permissions for, that is itself a subfolder of a Shared Drive that I don't have any access to.
What I've tried:
- Allowing permissions to the overall shared drive isn't possible so this solution and this solution are not options.
- I've also tried the "make it a dribble as early as possible" approach by successfully converting the folder I want to access to a dribble using
drive_get()and the URL. There appears to be an attribute associated with that dribble calledteamDriveIdwhich is the same id that is flagged as being "not found" when I try to usedrive_ls()on the subfolder (i.e., not referencing the parent Shared Folder at all). - Using each possible input for the
corpusargument as suggested here doesn't seem to help either, as I'm still just getting the same "can't find the Shared Drive" error with each iteration