この記事はGASでできること完全ガイドの実装編です。 「GASとは何か」から知りたい方は、先にそちらをご覧ください。
この記事では、Google Apps Script(GAS)でスプレッドシートをデータベースとして使うDiscord Botを約60分で構築する手順を解説します。 排他制御付きのデータ登録・照会機能まで、コードをコピペするだけで動くように全コードを掲載しています。
この記事の前提
| 項目 | 内容 |
|---|---|
| 必要なアカウント | Google、Discord(サーバー管理権限) |
| 必要な知識 | GAS入門ガイドを読了済み |
| 所要時間 | 約60分 |
| 費用 | 0円(GAS・Discord無料、2026年2月時点) |
| 完成物 | スプレッドシートにデータを登録・照会するDiscord Bot |
この記事で作るもの
DiscordスプレッドシートDBとは、Googleスプレッドシートをデータベース代わりに使い、Discord Botからデータの登録・照会を行う仕組みです。専用のデータベースサーバーを用意せずに、無料でDiscordデータ管理機能を構築できます。
ユーザーがDiscordで「/add 商品A 50」と入力
→ GASがスプレッドシートに在庫データを登録(排他制御付き)
ユーザーがDiscordで「/list」と入力
→ GASがスプレッドシートから在庫一覧を取得して表示
スプレッドシートDBと本格DBの比較
| 項目 | スプレッドシートDB | 本格DB(Firestore等) |
|---|---|---|
| 費用 | 無料 | 無料枠あり(超過で課金) |
| セットアップ | GASのみで完結 | クラウド設定が必要 |
| データ上限 | 約500万セル | 実質無制限 |
| 同時アクセス | LockServiceで排他制御 | ネイティブ対応 |
| GUIでの編集 | スプレッドシートで直接編集可能 | 管理コンソールが必要 |
| 向いている規模 | 数百〜数千行 | 数万行以上 |
完成すると、次の3つができるようになります。
- データの登録: スラッシュコマンドでスプレッドシートにデータを追加します(自動採番ID付き)
- データの照会: スラッシュコマンドでスプレッドシートのデータを一覧表示します
- 排他制御付き書き込み: LockServiceにより、複数ユーザーの同時書き込みでもデータが壊れません
準備・環境構築
環境構築とは、スプレッドシートのカラム設計とGASプロジェクトを準備する作業です。
| 準備項目 | 取得方法 | 備考 |
|---|---|---|
| Discordアプリ・Bot | Developer Portalで作成 | スラッシュコマンド登録済みが前提 |
| Bot Token | アプリ設定 → Bot → Reset Token | 一度しか表示されないため必ず控える |
| Application ID | アプリ設定 → General Information | コマンド登録APIに使用 |
| Googleスプレッドシート | Google Driveで新規作成 | URLの /d/ と /edit の間がスプレッドシートID |
スラッシュコマンドの登録方法やBotのサーバー招待手順はDiscordスラッシュコマンド実装ガイドで解説しています。
スプレッドシートのカラム設計
スプレッドシートをデータベースとして使う場合、1行目にヘッダーを設定します。以下は在庫管理の例です。
| 列 | ヘッダー | 型 | 説明 |
|---|---|---|---|
| A | id | 数値 | 自動採番の一意識別子 |
| B | name | 文字列 | 商品名 |
| C | quantity | 数値 | 在庫数 |
| D | createdAt | 日時 | 登録日時(自動記録) |
シート名は「在庫管理」とし、1行目にヘッダーを入力してください。
GASプロジェクトの作成
- Google Driveで「新規」→「その他」→「Google Apps Script」を選択します
- GASエディタの「プロジェクトの設定」→「スクリプトプロパティ」に以下を追加します
| プロパティ名 | 値 |
|---|---|
DISCORD_BOT_TOKEN | 取得したBot Token |
DISCORD_APPLICATION_ID | 取得したApplication ID |
SPREADSHEET_ID | スプレッドシートのID |
スクリプトプロパティ(GASが提供する安全な設定値の保存機能)を使うことで、コードへのハードコードを防げます。 スプレッドシートIDやBot Tokenは必ずスクリプトプロパティに保存してください。
実装手順
実装手順とは、データ読み取り・データ追加・doPostハンドラーの3ステップでDiscord Botデータベース機能を完成させる作業です。 すべてのコードを1つのスクリプトファイルに貼り付けてください。
ステップ1 — データの読み取り(Read)
スプレッドシートからデータを読み取り、Discord上に一覧表示する関数を実装します。
function getSheet() {
const sheetId = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
return SpreadsheetApp.openById(sheetId).getSheetByName('在庫管理');
}
function handleListCommand() {
try {
const sheet = getSheet();
if (!sheet) {
return createResponse('在庫管理シートが見つかりません');
}
const values = sheet.getDataRange().getValues();
if (values.length <= 1) {
return createResponse('在庫データがまだ登録されていません');
}
const lines = [];
for (let i = 1; i < values.length; i++) {
const id = values[i][0];
const name = values[i][1];
const quantity = values[i][2];
lines.push('#' + id + ' ' + name + ': ' + quantity + '個');
}
const message = '**📦 在庫一覧**\n' + lines.join('\n');
return createResponse(message);
} catch (error) {
Logger.log('在庫一覧エラー: ' + error.message);
return createResponse('在庫データの取得中にエラーが発生しました');
}
}
このコードのポイント:
getSheet()ヘルパー関数でスプレッドシートIDをスクリプトプロパティから取得していますopenById()を使うことで、Webアプリ(doPost)環境でも正しくシートを取得できます- データが0件の場合にも適切なメッセージを返しています
スプレッドシートの自動化について詳しくはGAS×スプレッドシート自動化をご覧ください。
ステップ2 — データの追加(Create + 排他制御)
LockService(GASが提供する排他制御の仕組み)を使って、複数ユーザーの同時書き込みでもデータが壊れない安全なデータ追加を実装します。
function handleAddCommand(options) {
try {
const name = options[0];
const quantity = Number(options[1]);
if (!name || isNaN(quantity) || quantity < 0) {
return createResponse('入力形式: /add 商品名 数量(例: /add 商品A 50)');
}
const lock = LockService.getScriptLock();
const locked = lock.tryLock(10000);
if (!locked) {
return createResponse('他のユーザーが書き込み中です。数秒後に再試行してください。');
}
try {
const sheet = getSheet();
if (!sheet) {
return createResponse('在庫管理シートが見つかりません');
}
// 最終行のIDを取得して自動採番
const lastRow = sheet.getLastRow();
const newId = lastRow <= 1 ? 1 : Number(sheet.getRange(lastRow, 1).getValue()) + 1;
sheet.appendRow([newId, name, quantity, new Date()]);
return createResponse('✅ 登録しました: #' + newId + ' ' + name + '(' + quantity + '個)');
} finally {
lock.releaseLock();
}
} catch (error) {
Logger.log('データ追加エラー: ' + error.message);
return createResponse('データの追加中にエラーが発生しました');
}
}
このコードのポイント:
LockService.getScriptLock()でスクリプト全体のロックを取得しますtryLock(10000)は最大10秒間ロック取得を待ちます。取得できない場合はユーザーにメッセージを返しますfinallyブロックで必ずロックを解放し、デッドロックを防いでいます- 最終行のIDに+1して自動採番します。データが空の場合はID 1から開始します
- 入力バリデーションで商品名と数量が正しく入力されているか確認しています
ステップ3 — doPostハンドラー
doPostとは、GASをWebアプリとしてデプロイした際にPOSTリクエストを受信する関数です。Discord Botからのインタラクション(コマンド操作)を受け取り、適切な処理に振り分けます。
function doPost(e) {
try {
const data = JSON.parse(e.postData.contents);
// PING → PONG(Interactions Endpoint URL検証用)
if (data.type === 1) {
return ContentService.createTextOutput(
JSON.stringify({ type: 1 })
).setMimeType(ContentService.MimeType.JSON);
}
// APPLICATION_COMMAND(スラッシュコマンド実行)
if (data.type === 2) {
const commandName = data.data.name;
if (commandName === 'list') {
return handleListCommand();
}
if (commandName === 'add') {
const options = (data.data.options || []).map(function(opt) {
return opt.value;
});
return handleAddCommand(options);
}
return createResponse('不明なコマンドです: /' + commandName);
}
return createResponse('処理できないリクエストです');
} catch (error) {
Logger.log('doPostエラー: ' + error.message);
return createResponse('エラーが発生しました。管理者に連絡してください。');
}
}
function createResponse(message) {
return ContentService.createTextOutput(
JSON.stringify({
type: 4,
data: { content: message },
})
).setMimeType(ContentService.MimeType.JSON);
}
このコードのポイント:
data.data.optionsからスラッシュコマンドのオプション(引数)を取得しています/listはデータ照会、/addはデータ追加に振り分けますcreateResponse()ヘルパー関数でJSON形式のレスポンスを統一しています- doPostの実装パターンはDiscordスラッシュコマンド実装ガイドと共通です
動作確認・トラブルシューティング
動作確認とは、構築したデータ管理機能が期待どおりに動くかテストする作業です。
まずGASエディタの右上「デプロイ」→「新しいデプロイ」でWebアプリとしてデプロイします。
次にDiscordで/listを実行し、「在庫データがまだ登録されていません」と表示されることを確認します。
続いて/add 商品A 50を実行し、「登録しました」のメッセージが返ることを確認してください。
よくあるエラーと解決策
| エラー・症状 | 原因 | 解決策 |
|---|---|---|
| 「在庫管理シートが見つかりません」 | シート名の不一致 | スプレッドシートのシート名が正確に「在庫管理」か確認 |
| 「他のユーザーが書き込み中です」 | LockServiceがロック中 | 数秒後に再試行。頻発する場合はtryLockの待機時間を延長 |
| 「入力形式: /add 商品名 数量」 | コマンドの引数が不正 | 数量は0以上の数値で入力。例: /add 商品A 50 |
| 401エラー(コマンド登録時) | Bot Tokenが無効 | Developer PortalでTokenを再発行し、スクリプトプロパティを更新 |
| データが二重登録される | ロック取得前に複数リクエスト到着 | LockServiceの待機時間内に処理が完了しているか確認 |
| 「Exception: Invalid argument」 | SPREADSHEET_IDが未設定 or 無効 | スクリプトプロパティにIDが正しく設定されているか確認 |
GASエディタの「実行数」タブ(左メニュー)で過去の実行履歴とエラー内容を確認できます。
応用・カスタマイズ例
応用・カスタマイズとは、基本のCRUD機能をベースに業務シナリオを追加していくことです。
中小企業向けDiscordデータ管理シナリオ
| シナリオ | コマンド例 | 活用場面 |
|---|---|---|
| 在庫管理 | /add 商品A 50 /list | 入出庫の記録、在庫照会 |
| 問い合わせ管理 | /ticket 内容 /tickets | 顧客問い合わせの記録・一覧表示 |
| タスク管理 | /task タスク名 /tasks | チームのタスク登録・進捗確認 |
Webhookによる自動通知を組み合わせたい場合はDiscord Bot×GAS連携をご覧ください。
スプレッドシートDBの制限事項
運用前に以下の制限を把握しておきましょう。
| 制限事項 | 上限 | 対策 |
|---|---|---|
| セル数上限 | 約500万セル | 不要データの定期削除、シート分割 |
| スクリプト実行時間 | 6分/回 | 大量データの一括処理は分割実行 |
| 同時書き込み | LockServiceで排他制御 | 高頻度アクセスにはCloud Firestoreを検討 |
| 読み取り速度 | 行数に比例して低下 | 1万行を超えたら本格DBへの移行を検討 |
| Discordの応答制限 | 3秒以内 | 重い処理はDeferred Response(type 5)で対処 |
まとめ
GASとスプレッドシートを組み合わせれば、約60分・無料(2026年2月時点)でDiscord Botデータベース機能を構築できます。 LockServiceによる排他制御とエラーハンドリングにより、複数ユーザーが同時に使っても安全な運用が可能です。
GASの基礎から学びたい方はGAS入門ガイドをご覧ください。 Webhook通知を追加したい方はDiscord Bot×GAS連携をご確認ください。