申請Google Sheet API

Google的試算表是一個很好存放資料的地方,許多人收集訂單資訊或是收集問卷資料,都會使用Google表單來做,而Google表單的資料也可以存進Google的試算表,如果手邊沒有資料庫可儲存資料,利用現成的Google試算表倒是一個不錯的方案。LineBot和使用者的對話,如果也能善用試算表,將會有許多的應用可以產生。但LineBot要能和Google試算表的API溝通,便要先經過許多的認證,取得Google的憑證及權杖,申請的過程有點繁雜,步驟如下:

一、啟用Google Sheet API及建立憑證

1、登入google後進入啟用的網站,https://console.developers.google.com/start/api?id=sheets.googleapis.com

2、進入後請依下方指示同意後便會啟用試算表 API

3、準備開始建立OAuth


4、這裡請注意,要按「取消」

5、請依序輸入相關資料後儲存

6、在這裡請選擇「OAth用戶端ID」

7、依下圖依序操作,名稱Google Sheets API Quickstart

8、不須要管這裡的ID及密鑰,直接按確定便建立好了憑證。

9、將此憑證檔案下載,複製到LineBot程式所在的資料夾,並改名叫做client_secret.json

10、進入Node.js的命令列模式,安裝Google API 需要的模組(googleapis以及google-auth-library):

  • d:
  • cd bottest (以上指令請視自己程式的工作資料夾來更改)
  • npm install googleapis --save
  • npm install google-auth-library --save

安裝完這二個模組後,package.json應該會長成這個樣子

{
  "name": "bottest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node ."
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.15.3",
    "google-auth-library": "^0.10.0",
    "googleapis": "^19.0.0",
    "linebot": "^1.3.0"
  }
}

11、在工作資料夾新增一個叫做quickstart.js的程式檔,這個程式檔最主要是要幫我們產生能夠和Google試算表溝通的權杖,程式內容如下:

var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');

// If modifying these scopes, delete your previously saved credentials
// at ~./sheetsapi.json
var SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
var TOKEN_DIR = './';
var TOKEN_PATH = TOKEN_DIR + 'sheetsapi.json';

// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the
  // Google Sheets API.
  authorize(JSON.parse(content), listMajors);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];
  var auth = new googleAuth();
  var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function(err, token) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client);
    }
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */
function getNewToken(oauth2Client, callback) {
  var authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES
  });
  console.log('Authorize this app by visiting this url: ', authUrl);
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter the code from that page here: ', function(code) {
    rl.close();
    oauth2Client.getToken(code, function(err, token) {
      if (err) {
        console.log('Error while trying to retrieve access token', err);
        return;
      }
      oauth2Client.credentials = token;
      storeToken(token);
      callback(oauth2Client);
    });
  });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
  try {
    fs.mkdirSync(TOKEN_DIR);
  } catch (err) {
    if (err.code != 'EEXIST') {
      throw err;
    }
  }
  fs.writeFile(TOKEN_PATH, JSON.stringify(token));
  console.log('Token stored to ' + TOKEN_PATH);
}

/**
 * Print the names and majors of students in a sample spreadsheet:
 * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
 */
function listMajors(auth) {
  var sheets = google.sheets('v4');
  sheets.spreadsheets.values.get({
    auth: auth,
    spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
    range: 'Class Data!A2:E',
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var rows = response.values;
    if (rows.length == 0) {
      console.log('No data found.');
    } else {
      console.log('Name, Major:');
      for (var i = 0; i < rows.length; i++) {
        var row = rows[i];
        // Print columns A and E, which correspond to indices 0 and 4.
        console.log('%s, %s', row[0], row[4]);
      }
    }
  });
}


12、回到Node.js的命令列模式,執行如下的指令(下圖的紅框部份):

  • node quickstart.js

執行後請將下方出現的文字反白起來複製下來(下圖的紫色框的部份),但是請注意,這個命令列模式不要關掉

13、在nodepad++貼上後,把https以前的文字全部拿掉,並且把它弄成一行如下,它是一個網址,我們需要靠這個網址取得google的授權碼

14、將此網址複製下來,到瀏覽器貼上這個網址,進入後它會要求你選擇你的Google帳戶並登入。

15、請點選「允許」

16、這時候會出現一組授權碼,請複製這段授權碼

17、回到剛才的Node.js的命令列視窗,找到Enter the code from that page here:的後面,把剛才在瀏覽器複製的授權碼貼上在這裡,並且按Enter。

18、這裡它會提示說明權杖資料已儲存在sheetsapi.json檔案中,並且會冒出一堆人的名字,它是網路上一個Google試算表內的資料,列出來給你看我們已經可以透過Google的API去抓取試算表內的資料了。

19、這時我們的資料夾裡面會有二個很重要的能夠跟Google Sheets API溝通的二個檔案,client_secret.json以及sheetsapi.json

附註:日後如果還要管理自己的Google API憑證,請由https://console.developers.google.com/登入後,便可以看到這次申請的憑證