Node.js googleapis npmパッケージで Google スプレッドシートを await/async で読み取るメモ

Node.js googleapis npmパッケージで Google スプレッドシートを await/async で読み取るメモです。

背景

実は、Node.js で Google スプレッドシートを取得する知識。GoogleのAPIバージョンの変遷もあって、自分の中で結構フワッとしていたんですが、大好きな Node-RED で node-red-contrib-google-sheets というGoogle スプレッドシートを読み込めるノードがあり、Node.jsとしてもとても勉強になりました。

node-red-contrib-google-sheets/gsheet.js at master · sammachin/node-red-contrib-google-sheets

実際には、こちらのソースを参考にしました。

  • 事前準備
    • Google Cloud Platform プロジェクトを作成する必要がある
    • サービス アカウントを作成する必要がある
    • 読み込みたい Google スプレッドシートにサービス アカウントで作られたメールアドレスを登録
    • JSON の鍵ファイルをサービス アカウントページでダウンロード
  • ノードの仕組み
    • googleapis npmパッケージで使用している
    • JSON の鍵ファイルを読み込ませたら、googleapisに従ってGoogle スプレッドシートを読み込んでいる

こちらを参考にします。

事前準備

2020/05/08 時点での画面で進めます。

プロジェクトの準備

プロジェクトの作成と管理  |  Resource Manager のドキュメント  |  Google Cloud

こちらに書いてある リソースの管理ページ に移動します。

image

プロジェクトを作成をクリック。

image

名前を決めて作成を押します。

サービスアカウントの作成

image

作成したら、リソース管理のリストに戻るので、先ほど作成したプロジェクトの設定をクリックします。

image

設定ページに移動したら、サービスアカウントを作成します。

image

サービスアカウントの詳細で作成ボタンを押します。

次のページの

  • 「このサービス アカウントにプロジェクトへのアクセスを許可する」
    *「ユーザーにこのサービス アカウントへのアクセスを許可」

は、何も設定せずに進めて完了を押します。

JSON の鍵ファイルの保存

Node.js のコードで、実際に使う JSON の鍵ファイル

image

サービスアカウントが出来たら操作から鍵を作成します。

image

JSONで作成を押したら、JSONファイルがダウンロードされるので、Node.jsを書くときに使えるように保存しておきます。

Sheets API を有効にする

左上のハンバーガーメニューをクリックしてメニューを出します。(再度この記事を作ろうとしたときに見失ってて困りました笑)

image

APIとサービスをクリックします。

image

APIとサービスの有効化をクリックします。

image

APIの検索ページに行くので Sheet で検索して絞り込みます。

image

有効にする をクリックします。

image

再度有効にしたページに行って作成できていれば完了です!

余談:サービスアカウント設定のページに戻るには

いつも、忘れてしまうのですが、サービスアカウント設定のページに戻るには

image

さきほどのハンバーガーメニューから IAMと管理 をクリックすれば戻ることができます。このあたりの遷移、慣れてないー。

サービスアカウントのメールアドレスで使いたい Google スプレッドシートの共有に加える

client_email の準備

ダウンロードしたJSON の鍵ファイルの中身をエディタで表示します。

image

client_email をコピーします。

使いたい Google スプレッドシートに移動

今回のGoogle スプレッドシートは、データはダミーの名前で埋められています。

image

client_email を Google スプレッドシートに共有

image

共有をクリックします。

image

さきほどの client_email をペーストして候補が出てらクリックして完了を押します。

image

再度、共有画面で登録されていたら完了です。

シートIDをメモ

image

使いたいGoogleスプレッドシートのURLを確認にします。シートのURLから抽出したシートIDをメモしておきましょう。

仮に以下のURLの場合は ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG の部分です。

https://docs.google.com/spreadsheets/d/ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG/edit#gid=0

取得する範囲を決める

シートの取得する範囲を決めます。

image

今回は A1:A3にしました。

ソースコード

ということで以下がソースコードです。

// Google 公式の npm googleapis
// https://www.npmjs.com/package/googleapis
let {google} = require('googleapis');

// ダウンロードしたJSON の鍵ファイルの中身をコピーアンドペースト
const creds = {
  "type": "service_account",
  "project_id": "project_id",
  "private_key_id": "private_key_id",
  "private_key": "private_key",
  "client_email": "client_email",
  "client_id": "client_id",
  "auth_uri": "auth_uri",
  "token_uri": "token_uri",
  "auth_provider_x509_cert_url": "auth_provider_x509_cert_url",
  "client_x509_cert_url": "client_x509_cert_url"
};

// JSON Web Token(JWT)の設定
let jwtClient = new google.auth.JWT(
  creds.client_email,
  null,
  creds.private_key,
  ['https://www.googleapis.com/auth/spreadsheets',
   'https://www.googleapis.com/auth/drive']
);

// シートのURLから抽出したID = {{SheetID}}
// 仮に以下のURLの場合は ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG の部分
// https://docs.google.com/spreadsheets/d/ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG/edit#gid=0

const sheet = '{{SheetID}}';

// スプレッドシートのセルの指定
let cells = 'A1:A3';

// スプレッドシートAPIはv4を使う
let sheets = google.sheets('v4');

async function getSheetRequest(){

  // JSON Web Token(JWT) の認証
  let resultJwtClient;
  try {
    resultJwtClient = await jwtClient.authorize();
    // console.log(resultJwtClient);
  } catch (error) {
    console.log("Auth Error: " + error);
  }

  // シートを読み込む
  let responseGetSheet;
  try {
    responseGetSheet = await sheets.spreadsheets.values.get({
      auth: jwtClient,
      spreadsheetId: sheet,
      range: cells
    });
    console.log(responseGetSheet.data.values);
  } catch (error) {
    console.log('The API returned an error: ' + error);
  }
}

// スプレッドシートを読み込む
getSheetRequest();

ダウンロードしたJSON の鍵ファイルの中身をコピーアンドペースト

image

ダウンロードしたJSON の鍵ファイルは、ソースコードの以下の部分を置き換えます。

const creds = {
  "type": "service_account",
  "project_id": "project_id",
  "private_key_id": "private_key_id",
  "private_key": "private_key",
  "client_email": "client_email",
  "client_id": "client_id",
  "auth_uri": "auth_uri",
  "token_uri": "token_uri",
  "auth_provider_x509_cert_url": "auth_provider_x509_cert_url",
  "client_x509_cert_url": "client_x509_cert_url"
};

シートIDを反映

{{SheetID}} の部分を先ほどメモしたシートIDに置き換えます。

js
// シートのURLから抽出したID = {{SheetID}}
// 仮に以下のURLの場合は ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG の部分
// https://docs.google.com/spreadsheets/d/ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG/edit#gid=0

const sheet = '{{SheetID}}';

セルの指定を反映

取り出したいセルの範囲を cells の変数に反映します。

// スプレッドシートのセルの指定
let cells = 'A1:A3';

動かしてみる

取り出したいセルの範囲や取り出したい Google スプレッドシートのシートIDは、みなさんそれぞれのものです。

私のデータの場合、動かして見るとこのように取得できます。

image

トラブルシューティング

  • The API returned an error: Error: Requested entity was not found. が出てしまう
    • 応答で上記が出る場合は、シートIDがうまく指定できてない場合に出ます
  • The API returned an error: Error: The caller does not have permission が出てしまう
    • client_email を 使いたいGoogle スプレッドシートに共有きてない場合に出ます