アプリを開発していて、そのデータをGoogleスプレッドシートで管理したいと思うことが多々あります。表計算ではありますが、データベースのように使っている方も多いでしょう。
そこで、本記事ではGoogleスプレッドシートをAPI化する2つの方法をご紹介します。
GoogleスプレッドシートをAPI化する2つのアプローチ
手軽に始めたい人向け:GASで簡易的にAPI化する方法
GoogleスプレッドシートをAPI化する簡易的な方法として、GAS(Google Apps Script)を使う方法があります。GASはGoogleが提供するJavaScriptベースのスクリプト環境で、Googleスプレッドシートを操作するためのAPIが用意されています。
以前、Google スプレッドシートを データベース代わりに使うには? 初心者でもできるAPI連携の始め方 – モナカプレスの記事で紹介したSheetToRESTというライブラリを使った場合、以下のようなコードでWebアプリを作成できます。
const sheetName = 'YOUR_SHEET_NAME';
// 取得系処理用
function doGet(e) {
const sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
const { action, limit, skip, term, id } = e.parameter;
switch ((action || '').toUpperCase()) {
case 'ONE': // 1件取得
return SheetToRest.get(sheet, id);
case 'FIND': // 検索
return SheetToRest.find(sheet, term);
case 'COUNT': // カウント
return SheetToRest.count(sheet);
default: // 一覧取得
return SheetToRest.list(sheet, limit, skip);
}
}
function doPost(e) {
const sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
const { action, id } = e.parameter;
switch ((action || '').toUpperCase()) {
case 'UPDATE': { // データ更新
const params = JSON.parse(e.postData.getDataAsString());
return SheetToRest.update(sheet, id, params);
}
case 'DELETE': // データ削除
return SheetToRest.remove(sheet, id);
default: { // データ登録
const params = JSON.parse(e.postData.getDataAsString());
return SheetToRest.create(sheet, params);
}
}
}
このコードの中では認証は行っていませんので、独自の仕組みが必要です。ただし、Google Apps Scriptではヘッダー情報は受け取れないので、クエリパラメータでトークンを渡すなどの工夫が必要です。
本番利用・拡張性重視:Google Sheets APIを使った本格的な方法
より本格的に使う場合には、Googe Sheets APIを使う方法がおすすめです。Googe Sheets APIを使う場合には、Google Cloud Platformでプロジェクトを作成し、APIを有効化する必要があります。
あらかじめ固定のシートIDを使う場合には、Sheets APIを有効にしてください。シートIDが不定、たとえばユーザーにファイル一覧から選択させる場合には、Drive APIも有効にする必要があります。
プロジェクトのクライアントキーやシークレットキーをアプリの中に組み込むのはセキュリティ的に問題があるので、別途Webアプリケーションを用意し、そこからGoogle Sheets APIを呼び出すのが良いでしょう。例えばGoogle Cloud Runや、Cloudflare Workers、AWS Lambdaなどを使う方法があります。
もしCloudflareを使う場合には、実行エンジンがNode.jsではないので下記の googleapis は利用できないので注意してください。
スプレッドシート一覧を取得する方法
以下は、Node.jsでGoogle Sheets APIを使って、シート一覧を取得するサンプルコードです(Expressを利用)。まず、認証を行ってアクセストークンとリフレッシュトークンを取得します。その後、Drive APIを使ってスプレッドシートの一覧を取得します。
import express from "express";
import { google } from "googleapis";
// Google OAuth2 クライアントの設定
const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.GOOGLE_REDIRECT_URI
);
// スコープ(Google Sheets と Drive)
const SCOPES = [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive",
];
// 認証URLへリダイレクト
app.get("/auth", (req, res) => {
const url = oauth2Client.generateAuthUrl({
access_type: "offline",
scope: SCOPES,
prompt: "consent",
});
res.redirect(url);
});
// 認証後のコールバック処理
app.get("/oauth2callback", async (req, res) => {
const code = req.query.code;
if (!code) {
return res.status(400).send("Authorization code missing.");
}
try {
// トークンを取得
const { tokens } = await oauth2Client.getToken(code);
oauth2Client.setCredentials(tokens);
const drive = google.drive({ version: "v3", auth: oauth2Client });
// Google スプレッドシートのみ取得するクエリ
const query = "mimeType='application/vnd.google-apps.spreadsheet' and trashed=false";
const response = await drive.files.list({
q: query,
fields: "files(id, name, modifiedTime, owners)",
pageSize: 20, // 最大取得件数(必要に応じて調整)
});
const files = response.data.files || [];
if (files.length === 0) return res.send("<p>スプレッドシートが見つかりませんでした。</p>");
// 結果をHTMLで表示
const html = `
<h2>スプレッドシート一覧</h2>
<ul>
${files
.map(
(f) =>
`<li>
<b>${f.name}</b>(ID: ${f.id})<br>
更新日: ${f.modifiedTime}<br>
所有者: ${f.owners?.[0]?.emailAddress || "不明"}
</li>`
)
.join("")}
</ul>
`;
res.send(html);
} catch (err) {
console.error(err);
res.status(500).send("Error retrieving access token");
}
});
// 起動
app.listen(port, () => {
console.log(Server running at http://localhost:${port});
});
スプレッドシートのデータを取得・更新する方法
その後、指定したシートIDの情報を取得するには、以下のようなコードを追加します。以下の場合は、A1セルの値を取得しています。
const sheets = google.sheets({ version: "v4", auth: oauth2Client });
const response = await sheets.spreadsheets.values.get({
spreadsheetId, // 取得したいスプレッドシートのID
range: 'A1', // 最初のシートのA1セルを取得
});
const value = response.data.values?.[0]?.[0];
console.log('A1セルの値:', value);
更新する場合には、以下のようなコードを使います。
// A1セルを更新
const response = await sheets.spreadsheets.values.update({
spreadsheetId,
range: "A1",
valueInputOption: "USER_ENTERED", // ユーザーが入力した形式で反映(数式などもOK)
requestBody: {
values: [['Hello, World!']],
},
});
GoogleスプレッドシートをAPI公開する際の注意点
Googleスプレッドシートを外部公開する上で懸念すべき点は以下の通りです。
- 不特定多数からアクセスさせても問題ないか?
- 読み取り専用か、更新・削除・追加まで許可するか?
不特定多数からアクセスさせても問題ないか?
Google Sheet APIを使う場合、APIキー(プロジェクト)ごとにレートリミットがあります。使用制限 | Google Sheets | Google for Developersによれば、1分あたり300件のリクエストが上限です。さらに1ユーザーあたり、60回/分という制限があります。
リクエストサイズについてはハードリミットはありませんが、Googleの推奨として最大ペイロードは2MBまでにするのが良いとされています。
読み取り専用か、更新・削除・追加まで許可するか?
データ公開のみとする場合には、SSSAPIのようなサービスを使うのが手軽です。読み取り専用なので、セキュリティ面でも安心です。
他の操作(更新、削除、作成)も可能にする場合には、Google Sheets APIまたはApps Scriptを使う必要があります。いずれの場合においても、セキュリティが重要になります。Google Sheets APIを使う場合には、サービスアカウントを使ってアクセス制御を行います。Apps Scriptの場合には、独自の認証を実装する必要があります。
Googleスプレッドシートはデータベースではないので、型が指定できるわけではありません。同じ列の値でも、数字や文字列、日付が混在することがあります。取得した値の検証を行わないと、意図しない動作をする可能性があります。
また、同時操作の競合が発生する可能性があります。複数のユーザーが同じシートを同時に更新する場合、最後に更新した内容が反映されるため、データの整合性が保たれないことがあります。必要に応じてロック機構を実装するなどの対策が必要です。
最後にデータの削除です。行のデータを削除すると、以降の行が繰り上がるため、IDなどで特定して削除する場合には注意が必要です。そのため、行の削除ではなく、論理削除(削除フラグを立てるなど)や行の内容をクリアする(空文字にする)方法を検討してください。
何よりレートリミットがありますので、データの取得はキャッシュ(加えて定期的な更新)するなどの工夫が必要です。もしキャッシュを行う場合には、スプレッドシート側での更新はデータの不整合につながるので、アプリケーションを介してのみ更新するなど運用ルールが必要でしょう。
まとめ:用途に応じたGoogleスプレッドシートAPI化の選び方
今回はGoogleスプレッドシートをAPI化する2つの方法をご紹介しました。簡易的に使う場合にはGASを使う方法が手軽ですが、セキュリティ面での工夫が必要です。より本格的に使う場合にはGoogle Sheets APIを使う方法がおすすめです。
展示会などのデモでは、GAS版を使うことで、手早くAPI化できるので便利です。ぜひ試してみてください。
