隨着谷歌表格API升級到第四個版本之後,雖然提供了更快的表格數據讀取API,可是還有就是須要受權才能讀取到數據,即便是發佈到網絡的表格。因此咱們在作這一升級的時候,嘗試了不少的方法,也走過了不少的坑,下面我就簡單總結一下。javascript
首先我找到了讀取表格數據的API 接口:java
developers.google.com/sheets/api/…ios
該接口須要的參數以下(必傳的參數):git
{
"spreadsheetId": "",
"range": "",
"access_token": ""
}
複製代碼
使用過的朋友都知道,spreadsheetId和range是表格的id和表格的tab範圍。可是access_token
並非一個固定的東西,因此我研究了google獲取access_token
的兩種方式(都是基於OAuth 2.0的):github
access_token
讀取該用戶擁有讀取權限的表格數據。access_token
讀取表格數據。剛開始的時候我使用了第一種方式,可是出現了下面的缺點:ajax
access_token
的有效期很短(通常是兩個小時),隔一段時間須要手動受權,須要人工的干預。後來看到谷歌在服務器受權的時候,建議使用服務帳號(雖然API KEY也能夠),就實現了服務端無用戶參與的受權。redis
在開發者控制檯建立一個項目npm
link:console.developers.google.com/projectcrea…json
填寫完必要的信息後,直接點擊建立便可(注意項目的id不能修改)。axios
在建立完帳號之後就會跳轉到該項目的dashboard,以下面的視圖,直接在搜索框搜索Google Sheet API,若是不開啓建立的服務帳號是沒有權限讀取表格數據的。
在API頁面直接點擊啓用便可開啓該項目的Sheet API功能。
開啓Sheet API之後會跳轉到Sheet API的配置頁面,咱們如今爲這個項目建立一個服務帳號。
首先按照標記點擊"憑據",而後點擊"API與服務中的憑據"來建立服務帳號。
咱們在這裏選擇建立"服務帳號密鑰";
點擊上面的"服務帳號密鑰"跳轉到了密鑰建立頁面,咱們選擇新的服務帳號,根據本身的要求進行填寫,以下所示。
這裏我選擇了JSON格式,方便Node.js(本次以Node.js做爲實踐)讀取;
點擊建立之後咱們會獲得一個json文件,注意改json文件必定要保存好了,後面的受權全靠它了。
接下來就開始編碼實現讀取的功能了;
下面是Node.js做爲實現,首先須要安裝googleapis,下面代碼是受權部分。
npm install googleapis --save
複製代碼
const {google} = require('googleapis');
// 後面的json文件就是咱們在上面第四步下載的json文件。
const {client_email: email, private_key: key} = require('./service-account.json');
// 指定權限,這裏僅須要讀取權限就能夠了
const scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
// 全局存儲受權後的token信息,後面也能夠存儲到redis等緩存中,如今爲了測試,我就存儲在本地的變量中
let token = null;
module.exports = {
authorize() {
return new Promise((resolve) => {
// 首先判斷有沒有token文件
if (token) {
const {access_token, expiry_date} = token;
// 看看有沒有過時 + 1分鐘
if (expiry_date > (new Date().getTime() + 60 * 1000)) {
return resolve(access_token);
}
}
// 從新受權
let jwtClient = new google.auth.JWT(email, null, key, scopes);
// 直接能夠獲取到access_token,很方便,不須要人工干預
jwtClient.authorize().then(data => {
// 保存token到全局變量
token = data;
// 返回token
resolve(data.access_token)
}).catch(() => {
resolve('');
});
});
}
};
複製代碼
而後咱們經過上面的authorize能夠取到token信息,最後使用ajax客戶端來調用表格的接口,便可實現數據的讀取。
下面是讀取表格數據的實現:
module.exports = async function getSheetData({spreadsheetId, worksheets}) {
const axios = require('axios');
const qs = require('qs');
const auth = require('../auth/jwtclient');
const serviceEmailAddr = require('../auth/service-account').client_email;
const token = await auth.authorize();
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values:batchGet`;
return await axios
.get(url, {
params: {access_token: token, ranges: worksheets},
paramsSerializer(params) {
return qs.stringify(params, {arrayFormat: 'repeat', encodeValuesOnly: true});
}
})
.then(resp => resp.data.valueRanges)
.catch(error => {
if (error.response.status === 404) {
return Promise.reject('表格不存在,請檢查表格id是否正確');
}
if (error.response.status === 403) {
return Promise.reject('沒有權限訪問,請將表格分享給:' + serviceEmailAddr);
}
if (error.response.status === 400) {
return Promise.reject(error.response.data.error.message.replace('Unable to parse range', '請檢查後面表格是否存在'));
}
Promise.reject(error.message);
});
};
複製代碼
爲了保證隱私,我沒有上傳項目配置的json文件;
若是讀取數據的時候,google返回了403,那多是由於你沒有將表格共享給服務帳號,查看服務帳號:
console.developers.google.com/iam-admin/s…
在上面選擇你的項目,就能看到右邊的電子郵件,將谷歌表格共享給改郵箱就能夠訪問了。