zilijonas
zilijonas

Reputation: 3785

googleapis drive unable to access shared drive files

I am writing a script that should be able to search through shared drive files by file name.

For authentication, I use a Service Account.

The Service Account has an access to a Google Sheets file, that is shared with me and a shared drive.

My code currently looks like this:

  const drive = google.drive({ version: 'v3', auth });
  const drives = await drive.drives.list();
  console.log(drives.data.drives);
  const files = await drive.files.list();
  console.log(files.data.files);

The output is:

[
  {
    kind: 'drive#drive',
    id: '0AHOBXXXXXXXX',
    name: 'Shared_drive'
  }
]
[
  {
    kind: 'drive#file',
    id: '1LAPXWyRXXXXXXXXXXXXXXXXXXXXXXX',
    name: 'Sheets File',
    mimeType: 'application/vnd.google-apps.spreadsheet'
  }
]

Why am I able to access the shared drive, but when I try to access all the files I only get Sheets File (which is outside the shared drive)? The shared drive contains multiple directories with many files in them. Why can't I see them? The Service Account has the same viewer permissions on both - shared drive and Sheets file.

Upvotes: 1

Views: 967

Answers (3)

Tanaike
Tanaike

Reputation: 201603

I believe your goal as follows.

  • You want to retrieve the file list using Drive API with googleapis for Node.js
  • In your environment, you have the shared Drive, and you want to retrieve the file list not only your Google Drive, but also the shared Drive.
  • You have already been able to retrieve the file list using Drive API.

Modification points:

  • In order to retrieve the file list from both your own drive and the shared drive, it is required to set the several specific parameters for the query parameter of the endpoint. This has already been mentioned by Ron M's answer.
  • From your question,
    • I thought the possibility that you have several shared Drives.
      • For this, allDrives is used for corpora. By this, it is not required to be set each drive ID.
    • You might have the files of more than 1000 files.
      • For this, the file list is retrieved using NextPageToken.

When above points are reflected to your script, it becomes as follows.

Modified script:

When you want to retrieve the file list from both your drive and the shared drive, you can use the following script. In this case, even when you have several shared Drives, all file list can be retrieved from all shared drives and your drive.

const drive = google.drive({ version: "v3", auth });
const fileList = [];
let NextPageToken = "";
do {
  const params = {
    pageToken: NextPageToken || "",
    pageSize: 1000,
    fields: "nextPageToken, files(id, name)",
    corpora: "allDrives",
    includeItemsFromAllDrives: true,
    supportsAllDrives: true,
  };
  const res = await drive.files.list(params);
  Array.prototype.push.apply(fileList, res.data.files);
  NextPageToken = res.data.nextPageToken;
} while (NextPageToken);
console.log(fileList);
  • Here, when you want to retrieve only the shared Drive, you can also modify above script as follows.

    • From:

        Array.prototype.push.apply(fileList, res.data.files);
      
    • To:

        Array.prototype.push.apply(fileList, res.data.files.filter((f) => f.driveId));
      

Note:

  • If you want to split the file list for your drive and shared drives, you can also use the following script.

      const drive = google.drive({ version: "v3", auth });
      const fileList = { myDrive: [], sharedDrives: {} };
      let NextPageToken = "";
      do {
        const params = {
          pageToken: NextPageToken || "",
          pageSize: 1000,
          fields: "nextPageToken, files(id, name, driveId)",
          corpora: "allDrives",
          includeItemsFromAllDrives: true,
          supportsAllDrives: true,
        };
        const res = await drive.files.list(params);
        res.data.files.forEach((f) => {
          if (f.driveId) {
            fileList.sharedDrives[f.driveId] = fileList.sharedDrives[f.driveId]
              ? fileList.sharedDrives[f.driveId].concat(f)
              : [f];
          } else {
            fileList.myDrive = fileList.myDrive.concat(f);
          }
        });
        NextPageToken = res.data.nextPageToken;
      } while (NextPageToken);
      console.log(fileList);
    

Reference:

Upvotes: 1

CyberEternal
CyberEternal

Reputation: 2545

Please take a look at my implementation of getting files from Google drive. Here you can find an implementation for getting files by pagination, filter by including or excluding shared files, and ability to search as well.

import { google } from 'googleapis';


const getOauth2Client = () => new google.auth.OAuth2(
  process.env.GOOGLE_DRIVE_CLIENT_ID,
  process.env.GOOGLE_DRIVE_CLIENT_SECRET,
  process.env.GOOGLE_DRIVE_REDIRECT_URL
);


export const getFiles = async ({
  tokens, pageToken, keyword, notShared
}) => {
  const oauth2Client = getOauth2Client();
  oauth2Client.setCredentials(tokens);
  const drive = google.drive({
    version: 'v3',
    auth: oauth2Client
  });
  const options = {
    pageSize: 20,
    supportsAllDrives: false,
    includeItemsFromAllDrives: false,
    orderBy: 'createdTime desc',
    spaces: 'drive',
    corpora: 'user',
    q: "mimeType contains 'image/' and trashed = false",
    fields: 'nextPageToken, files(id, webContentLink, name, webViewLink, iconLink, thumbnailLink)',
    pageToken
  };
  if (keyword) options.q += ` and name contains '${keyword}'`;
  if (notShared) options.q += " and 'me' in writers and 'me' in owners";
  const res = await drive.files.list(options);
  if (res.status !== 200) throw new Error(res.statusText);
  return res;
};

Upvotes: 1

Kristkun
Kristkun

Reputation: 5963

Using Drive API Files.list() with an empty request parameters will only give you the list of files in the user's drive.

If you want to list the files in your shared drive, You need to configure the following parameters:

corpora = drive
driveId = shared drive id
includeItemsFromAllDrives = true
supportsAllDrives = true

You can also use Drives.list() to list the user's shared drive.

Upvotes: 1

Related Questions