稼働中の既存GASを、副作用を起こさずに検証してから本番反映する
定期実行中のApps Scriptに仕様変更を入れる手順。メール送信などの副作用を起こさずに実データでロジックを検証し、clasp push後にpullで突合するまでを機械判定で閉じる。clasp loginの認可URLが死ぬ罠、pullの拡張子違いで差分ゼロを誤認する罠つき。
約3.3万トークンの節約 (API料金換算で約50円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「稼働中の既存GASを、副作用を起こさずに検証してから本番反映する」は、Google WorkspaceカテゴリのAI指示書(MDファイル)です。定期実行中のApps Scriptに仕様変更を入れる手順。メール送信などの副作用を起こさずに実データでロジックを検証し、clasp push後にpullで突合するまでを機械判定で閉じる。clasp loginの認可URLが死ぬ罠、pullの拡張子違いで差分ゼロを誤認する罠つき。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.3万トークン(API料金換算で約50円)・79%のトークンを節約できます。
- カテゴリ
- Google Workspace
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約4.2万トークン
- この巻物使用時
- 約9,000トークン
- 節約量
- 約3.3万トークン (約50円)
- 更新日
- 2026-08-30
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/gas-4/raw を読み込んで、この指示書どおりに実装して"
中身
稼働中の既存 GAS を、副作用を起こさずに検証してから本番反映する
対象: すでに定期トリガーで動いている Apps Script(アラートメール送信・シート更新など)に 仕様変更を入れたいが、検証のために本番実行するとメールが飛ぶ/データが書き換わるケース。
「スクリプトエディタを開いて貼ってください」と人に頼まず、AI 側で完結させる手順。
0. 前提の分岐: そのGASにコマンドキューがあっても使えない
既存GASに「Driveへjsonを置くと関数を実行する」式のコマンドキューが仕込んであっても、 whitelist に載った関数を呼べるだけでソースの書き換えはできない(新関数を足すには先にソースを変える必要があり循環する)。 コード変更の自動経路は clasp push 一択。ここを最初に判断する。
1. 認証前にソースを読む(Drive API 経由)
clasp 認証より先に中身を読める。scriptId が分かればよい。
# スクリプトを探す
mimeType = 'application/vnd.google-apps.script'
# 中身を取る(プロジェクト全体が1つのJSONで返る)
exportMimeType: application/vnd.google-apps.script+json
返るJSONは {files: [{name, type, source}, ...]}。type は server_js / json。
これをファイルへ展開すれば、認証を待たずに調査・設計を始められる。
import json, os
j = json.load(open('script.json', encoding='utf-8'))
for f in j['files']:
ext = '.gs' if f['type'] == 'server_js' else '.json'
open(os.path.join(outdir, f['name'] + ext), 'w', encoding='utf-8', newline='').write(f['source'])
2. clasp を用意する(人の操作は「許可」クリック1回だけ)
npm i -g @google/clasp
# プロジェクトディレクトリに
echo '{"scriptId":"<SCRIPT_ID>","rootDir":"."}' > .clasp.json
人に必要なのは次の2つだけ。両方とも直リンクで渡す。
- Apps Script API を ON:
https://script.google.com/home/usersettings clasp loginが出す認可URLを開いて「許可」
落とし穴A: 認可URLはセッションと寿命を共にする
clasp login はランダムポートのローカル待受サーバーを立て、そこへ戻ってくるコードを拾う。
AI 側のセッションやバックグラウンドプロセスが終わるとこのサーバーが死ぬ。
人が後からURLを踏んでも ERR_CONNECTION_REFUSED になり、認可コードは宙に浮く。
- URLの提示と、人がクリックするまでを同一ターン内に収める
- 提示前に長い処理を挟まない
- 落ちたら作り直す(ポートが変わるのでURLも変わる。古いURLを再掲しない)
- 認可コードを人に貼り直させるのは筋が悪い(そもそも代理入力すべきでない情報)
落とし穴B: 「どのアカウントで」を明示する
トリガーを所有しているアカウント=メールの送信元アカウントで認証する。 オーナーが別人でも、編集権があるアカウントなら push できる。 アカウント選択画面で迷わせないよう、どのアドレスを選ぶかを手順に書く。
3. 本番実行せずに検証する(これが本題)
変更対象の関数がメール送信・書き込みを含むなら、絶対に実行しない。 代わりに「本番と同じ入力」でロジックだけを手元で再現する。
3-1. 本番データを丸ごと取る
バインド先スプレッドシートを xlsx でエクスポートする
(exportMimeType: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)。
CSVエクスポートは先頭シートしか出ないので、対象シートが2枚目以降なら必ず xlsx。
import openpyxl
wb = openpyxl.load_workbook('book.xlsx', data_only=True)
ws = wb['<対象シート名>']
# 日付セルは datetime で返る = GAS の Date と同じ扱いにできる
3-2. 判定ロジックは「本物のソースから読み込む」
再実装するとコピペのズレで検証が嘘になる。これから push する .gs から関数本体を抜き出して評価する。
const src = fs.readFileSync(gsPath, 'utf8');
const body = src.match(/function isTargetExcluded\(name\) \{[\s\S]*?\n\}/)[0];
const fn = new Function(body + '; return isTargetExcluded;')();
3-3. 「再現が正しいこと」を先に証明する
いきなり変更後を見ない。変更前のロジックを実データで流し、実際の本番出力と一致するかを確かめる。
- アラートメールなら「(32件)」のような件数、顧客名の並び
- 一致 → 再現は正しい。その上で変更後を流して差分を見る
- 不一致 → 列番号・型・フィルタ条件の読み違い。ここで気づけば本番を壊さない
この「変更前を実測値に合わせる」工程を飛ばすと、変更後の数字に根拠がなくなる。
3-4. 合否を機械判定にする
目視で「よさそう」で終えない。
const ok = added.length === 0 // 意図せず増えた対象がない
&& leaked.length === 0 // 除外したはずのものが残っていない
&& removed.length > 0; // そもそも変化している
process.exit(ok ? 0 : 1);
除外「された」件数だけでなく、残った側の一覧も出す。過剰除外はこれでしか見つからない。
4. push して、引き戻して照合する
clasp push --force
push が成功したことは、反映が正しいことを意味しない。別ディレクトリへ pull して全ファイル突合する。
mkdir verify && cp .clasp.json verify/ && (cd verify && clasp pull)
落とし穴C: pull は拡張子が変わる
clasp pull は .js で書き出す(push元は .gs)。素直に diff -rq すると全ファイルが
「片側にしかない」と出て差分ゼロを差分だらけと誤認する。basename で突き合わせる。
for f in "$LOCAL"/*.gs; do
b=$(basename "$f" .gs)
diff -q <(tr -d '\r' < "$f") <(tr -d '\r' < "$VERIFY/$b.js") >/dev/null || echo "DIFFERS: $b"
done
改行コード差で誤検知するので tr -d '\r' を噛ませる。
不一致0 + 変更箇所を実物から grep して見せる、までが検証。
5. 変更コードの書き方(既存GASを壊さない)
- 既存の記述スタイルに合わせる。
var/constの混在、コメントの言語、function宣言など既存のままに寄せる - 除外条件などはキーワード配列にして、次に増やす人が1行足すだけで済む形にする
- 新しいトップレベル関数を足す時は、プロジェクト全ファイルに同名がないか grep する (GAS は全ファイルが同一グローバルスコープ。名前衝突は静かに壊れる)
appsscript.jsonのoauthScopesを後から明示列挙しない。既存GASでは自動検出に任せる方が安全 (明示した瞬間、書き漏らしたスコープの機能が止まる)- 表記ゆれを吸収する(前後スペース・全角空白・半角カナ)。人が手入力する列を条件にするなら必須
- push 前に構文チェック
node -e "fs.readdirSync('.').filter(f=>f.endsWith('.gs')).forEach(f=>new Function(fs.readFileSync(f,'utf8')))"
チェックリスト
- コマンドキューでは足りない=clasp push が必要、と判断した
- 認証前に Drive 経由でソースを読み、変更設計を終えた
- 認可URLの提示とクリックを同一ターンに収めた
- 副作用のある関数を本番実行していない
- 変更前ロジックの再現結果が、実際の本番出力と一致した
- 合否を機械判定にし、残った側の一覧も確認した
- push 後に pull して全ファイル突合(拡張子違いを吸収)し、不一致0を確認した
- ローカルミラーを残し、次回以降 clasp だけで完結できる状態にした
よくある質問
+「稼働中の既存GASを、副作用を起こさずに検証してから本番反映する」とは何ですか?
定期実行中のApps Scriptに仕様変更を入れる手順。メール送信などの副作用を起こさずに実データでロジックを検証し、clasp push後にpullで突合するまでを機械判定で閉じる。clasp loginの認可URLが死ぬ罠、pullの拡張子違いで差分ゼロを誤認する罠つき。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約9,000トークンで済みます。差し引き約3.3万トークン(API料金換算で約50円)・79%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
GAS完全自動化テンプレ — Driveコマンドキュー方式
Google Apps Script の「毎回エディタで▶実行」を根絶。Drive 経由のコマンドキューで、初回1クリック以降は AI がすべての GAS 関数をリモート実行できるようになるテンプレート指示書。
人間の手入力台帳を壊さずに自動更新する — GAS Web App upsert 設計
各PC/各拠点の点検結果を、人間が手運用しているスプレッドシート台帳へ自動反映する。手入力列とコメントを絶対に壊さない突合設計、タブ/列の解決、並行POST対策、配布シークレットの落とし穴まで。
数式まみれの業務スプレッドシートを、Webアプリから壊さずに編集させる型
ArrayFormula と per-row 数式が混在する台帳を、セル単位 allowlist・dry-run 既定・適用前バックアップ・触っていないセルの数式不変検査で安全に書き換える設計手順。列ごとの数式復元と、テストが緑のまま壊れる典型例つき。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア