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

googleapis drive unable to access shared drive files

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

我使用服务帐户进行身份验证。

服务帐户可以访问与我共享的 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'
  }
]

为什么我可以访问共享驱动器,但当我尝试访问所有文件时,我只得到表格文件(在共享驱动器之外)?共享驱动器包含多个目录,其中包含许多文件。为什么我看不到它们?服务帐户对共享驱动器和表格文件具有相同的查看权限。

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

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

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

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

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

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

我相信你的目标如下。

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

修改点:

  • 为了从您自己的驱动器和共享驱动器中检索文件列表,需要为端点的查询参数设置几个特定的​​参数。 .
  • 已经提到了这一点
  • 根据你的问题,
    • 我认为您可能有多个共享驱动器。
      • 为此,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);
  • 这里,当你只想取回共享Drive时,也可以修改上面的脚本如下。

    • 发件人:

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

参考: