<返回更多

Nodejs读取Google Drive里面的文件

2021-06-09    前端在路上
加入收藏

最近在工作中遇到了一个场景:要做一个静态的网站,里面的内容是由设计编写的.md格式的内容。设计将编好的文档统一放在常用的google Drive里面,如下图

「JS小技巧」Nodejs读取Google Drive里面的文件

 

然后我需要将这些文档下载下来导入到我的项目里面,然后进行解析编译,最后展示在网页上面。最开始,每次下载.md、删除项目里面之前的.md、再导入新的.md, 没什么问题,但是设计时不时更新一下文档,然后我每次我都要痛苦地执行上面的操作,关键是这些.md还不止一个文件夹,文档的数量也有近百个,重复工作不胜其烦。

为了解决这个问题,我想到使用NodeJS编写一个简单的脚本,直接读取Google Drive里面的文件。下面记录了一些过程

Google搜索google drive api

「JS小技巧」Nodejs读取Google Drive里面的文件

 

非常多的API, 直接找我们需要的Download

「JS小技巧」Nodejs读取Google Drive里面的文件

 

然后这里有官方提供的案例

「JS小技巧」Nodejs读取Google Drive里面的文件

 

copy到项目里面,在build文件夹下建一个test.js,将刚刚copy的脚本放在里面。但是这个脚本,我们缺少fileId,拿不到fileId就无法去下载。于是去找get方法

「JS小技巧」Nodejs读取Google Drive里面的文件

 

从list返回集里面可以找到fileId, 且参数里面传入我们的driveId(文件夹的ID)

「JS小技巧」Nodejs读取Google Drive里面的文件

 

所以,我们现在我们依赖两个API: list和get。我们先读取文件夹里面全部的文件

async function list(folderId, limit = 100) {
  let files = [];
  let pageToken = null;
  let listOptions = {
    q: `'${folderId}' in parents`,
    fields: 'files(id,name,mimeType,trashed)'
  };
  while (true) {
    if (pageToken) {
      listOptions['pageToken'] = pageToken;
    }
    let response = await drive.files.list(listOptions);
    if (!response.data.files || !response.data.files.length) {
      break;
    }
    let limitReached = false;
    for (let file of response.data.files) {
      if (file.trashed) {
        continue;
      }
      delete (file.trashed);
      files.push(file);
      if (files.length >= limit) {
        limitReached = true;
        break;
      }
    }
    pageToken = response.data.nextPageToken;
    if (limitReached || !pageToken) {
      break;
    }
  }
  return files;
}

期望返回的files如下:

[
  {
    id: '3434UTHhlvdvpFL4hdHjsxImiLPKYLYh6VpK',
    name: 'Default Page.md',
    mimeType: 'text/markdown'
  },
  {
    id: '134Za--w6fKhGSZGPc7vWAn_ejg88Sx4pqf',
    name: 'Anchor.md',
    mimeType: 'text/markdown'
  },
]

这里的id就是fileId, 然后我们就可以通过

files.forEach(file => {
  drive.files.get({ fileId: file.id, alt: 'media' }).then(res => {
		console.log('res', res.data)
    // writeFile
  });
});

到这里,基本上主要的Google Drive的API已经用完了,但是,我们知道使用Google Drive是需要登录认证,只有授权账户才能访问文件。所以接下来的工作就是获取Google Auth。

 

Get Google Auth

「JS小技巧」Nodejs读取Google Drive里面的文件

 

从Google API Console[
https://console.cloud.google.com/apis/dashboard]进入Google Developer Console。新建一个project

「JS小技巧」Nodejs读取Google Drive里面的文件

 

填写project信息

「JS小技巧」Nodejs读取Google Drive里面的文件

 

这样,project就创建好了,我们还需要给它配置api

「JS小技巧」Nodejs读取Google Drive里面的文件

 

选择google drive

「JS小技巧」Nodejs读取Google Drive里面的文件

 

启用google drive

「JS小技巧」Nodejs读取Google Drive里面的文件

 

为了使用API, 我们创建凭据

「JS小技巧」Nodejs读取Google Drive里面的文件

 

继续

「JS小技巧」Nodejs读取Google Drive里面的文件

 

继续

「JS小技巧」Nodejs读取Google Drive里面的文件

 

继续

「JS小技巧」Nodejs读取Google Drive里面的文件

 

继续

「JS小技巧」Nodejs读取Google Drive里面的文件

 

完成后就看到生成的服务账号了,点击编辑

「JS小技巧」Nodejs读取Google Drive里面的文件

 

生成秘钥

「JS小技巧」Nodejs读取Google Drive里面的文件

 

导出为json格式,并保存到项目中credentials.json

「JS小技巧」Nodejs读取Google Drive里面的文件

 

接下来,我们就可以使用生成的凭据来获得Google Auth了

const { google } = require("googleapis");
const credentials = require("./credentials.json");
const scopes = ["https://www.googleapis.com/auth/drive"];
const auth = new google.auth.JWT(
  credentials.client_email,
  null,
  credentials.private_key,
  scopes
);
const drive = google.drive({ version: "v3", auth });

至此,我们的读取Google Drive的功能全部介绍到了。但是想要使用,还需要给对象文件(夹)share with service account email id.

「JS小技巧」Nodejs读取Google Drive里面的文件

 

这里的email来源于上面credentials.json里面的的client_email。

「JS小技巧」Nodejs读取Google Drive里面的文件

 

至此,我们就能真正访问到Google Drive里面的文件了。下面是全部的脚本

const { google } = require("googleapis");
const writeFile = require('write');
const { resolve } = require('path');

const folders = [
  {
    name: '组件文档',
    folderId: '1sfsCs5ojo4g-RJU-GamENaetNpJlpVYiNQ',
    dest: 'pages/components'
  },
  {
    name: '组件日志',
    folderId: '1MsdVAyt7_c1qsXM8ZxyVV_lxXG2_VhD6fW',
    dest: 'pages/record'
  },
  {
    name: '设计文档',
    folderId: '12IkZBRsdNjW_D0C3pKOseoehkGv0uZO3',
    dest: 'pages/design'
  },
]

const credentials = require("./credentials.json");
const scopes = ["https://www.googleapis.com/auth/drive"];
const auth = new google.auth.JWT(
  credentials.client_email,
  null,
  credentials.private_key,
  scopes
);
const drive = google.drive({ version: "v3", auth });

// 读取文件夹里面的文件,返回的数据格式如下:
// {
//   id: '1me2MPIehUw9LeP7sj4Px-V45G_m6mIGFZ',
//   name: 'Button.md',
//   mimeType: 'text/markdown'
// }
async function list(folderId, limit = 100) {
  let files = [];
  let pageToken = null;
  let listOptions = {
    q: `'${folderId}' in parents`,
    fields: 'files(id,name,mimeType, trashed)'
  };
  while (true) {
    if (pageToken) {
      listOptions['pageToken'] = pageToken;
    }
    let response = await drive.files.list(listOptions);
    if (!response.data.files || !response.data.files.length) {
      break;
    }
    let limitReached = false;
    for (let file of response.data.files) {
      if (file.trashed) {
        continue;
      }
      delete (file.trashed);
      files.push(file);
      if (files.length >= limit) {
        limitReached = true;
        break;
      }
    }
    pageToken = response.data.nextPageToken;
    if (limitReached || !pageToken) {
      break;
    }
  }
  return files;
}

folders.forEach(folder => {
  const { folderId, dest } = folder;
  list(folderId).then(files => {
    // console.log('files', files);
    files.forEach(file => {
      drive.files.get({ fileId: file.id, alt: 'media' }).then(res => {
        writeFile(`${resolve(dest)}/${file.name}`, res.data, {encoding: 'utf-8'});
        console.log(`Download ${resolve(dest)}/${file.name} success`);
      });
    });
  });
});

最终,完成需求,解放双手

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>