googleapis 驱动器无法访问共享驱动器文件

时间:2021-02-04 15:41:20

标签: node.js google-api google-drive-api

我正在编写一个脚本,它应该能够按文件名搜索共享驱动器文件。

对于身份验证,我使用服务帐户。

服务帐户有权访问与我共享的 Google 表格文件和共享驱动器。

我的代码目前是这样的:

  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);

输出为:

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

为什么我可以访问共享驱动器,但是当我尝试访问所有文件时,我只能获取 Sheets 文件(位于共享驱动器之外)?共享驱动器包含多个目录,其中包含许多文件。为什么我看不到他们?服务帐号对共享云端硬盘和表格文件拥有相同的查看者权限。

3 个答案:

答案 0 :(得分:1)

使用带有空请求参数的 Drive API Files.list() 只会为您提供用户驱动器中的文件列表。

如果要列出共享驱动器中的文件,则需要配置以下参数:

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

您还可以使用 Drives.list() 列出用户的共享驱动器。

答案 1 :(得分:1)

请看一下我从 Google Drive 获取文件的实现。在这里,您可以找到通过分页获取文件、通过包含或排除共享文件进行过滤以及搜索功能的实现。

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;
};

答案 2 :(得分:1)

我相信你的目标如下。

  • 您想使用 Drive API 和 googleapis for Node.js 检索文件列表
  • 在您的环境中,您拥有共享云端硬盘,并且您不仅要检索您的 Google 云端硬盘,还要检索共享云端硬盘的文件列表。
  • 您已经能够使用 Drive API 检索文件列表。

修改点:

  • 为了从您自己的驱动器和共享驱动器中检索文件列表,需要为端点的查询参数设置几个特定参数。 Ron M's answer 已经提到了这一点。
  • 从你的问题来看,
    • 我认为您可能有多个共享云端硬盘。
      • 为此,allDrives 用于 corpora。这样,就不需要设置每个驱动器 ID。
    • 您可能拥有超过 1000 个文件的文件。
      • 为此,使用 NextPageToken 检索文件列表。

当以上几点反映到你的脚本中时,它变成如下。

修改后的脚本:

当您想从您的驱动器和共享驱动器中检索文件列表时,您可以使用以下脚本。在这种情况下,即使您有多个共享驱动器,也可以从所有共享驱动器和您的驱动器中检索所有文件列表。

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);
  • 这里,当你只想检索共享驱动器时,你也可以修改上面的脚本如下。

    • 来自:

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

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

注意:

  • 如果您想拆分驱动器和共享驱动器的文件列表,也可以使用以下脚本。

      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);
    

参考: