GAS Web アプリの画面をブラウザ操作なしで検証する(google.script.run 偽装・差し込み値置換・Sheets API 無効でも gviz で実データ)
ログイン必須の Apps Script Web アプリでも、index.html を Chromium で実描画して DOM を assert できる。偽 google.script.run は head に埋め込む(addInitScript は setContent で走らない)、サーバー差し込み値の置換、file:// が要る条件、Sheets API 無効時に OAuth トークンだけでタブ別 CSV を読む URL、書き込みはコマンドキューで read-back。
約5.1万トークンの節約 (API料金換算で約77円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「GAS Web アプリの画面をブラウザ操作なしで検証する(google.script.run 偽装・差し込み値置換・Sheets API 無効でも gviz で実データ)」は、Google WorkspaceカテゴリのAI指示書(MDファイル)です。ログイン必須の Apps Script Web アプリでも、index.html を Chromium で実描画して DOM を assert できる。偽 google.script.run は head に埋め込む(addInitScript は setContent で走らない)、サーバー差し込み値の置換、file:// が要る条件、Sheets API 無効時に OAuth トークンだけでタブ別 CSV を読む URL、書き込みはコマンドキューで read-back。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約5.1万トークン(API料金換算で約77円)・85%のトークンを節約できます。
- カテゴリ
- Google Workspace
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約6万トークン
- この巻物使用時
- 約9,000トークン
- 節約量
- 約5.1万トークン (約77円)
- 更新日
- 2026-10-15
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/gas-web-google-script-run-sheets-api-gviz/raw を読み込んで、この指示書どおりに実装して"
中身
GAS Web アプリ(HtmlService)の画面を、ブラウザ操作なしで検証する — google.script.run の偽装とサーバー差し込み値の置換
何が困るか
Apps Script の Web アプリは Google ログイン必須で、curl で開いてもサインイン画面しか返らない。画面の修正(プルダウンの候補、ボタンの開閉、初期ページの振り分け)を「本番で user に見てもらう」以外に確かめる手段が無いと思われがちだが、HTML は手元にあるので Chromium で実描画して DOM を assert できる。
手順(Node + Playwright)
clasp pullしたindex.htmlを読み込む。- サーバー差し込み(
<?= name ?>/<?!= name ?>)を、doGet が入れるのと同じ JSON 文字列で置換する。JSON.parse('<?= list ?>')の形ならJSON.stringify(値)を\と'だけエスケープして入れる。置換漏れは/<\?[=!]?[\s\S]*?\?>/で検出して例外にする。 google.script.runの偽物を<head>直下に<script>として埋め込む。page.addInitScriptはpage.setContentでは走らないので使わない(実測)。偽物はwithSuccessHandler / withFailureHandler / withUserObjectを受けて、任意の関数名の呼び出しをsetTimeout(…, 0)で success handler に返す Proxy にする。関数名ごとの戻り値はhandlersオブジェクトで差し替える。- 外部 CDN(バーコード・QR ライブラリ等)は
page.route(/^https?:\/\//, r => r.abort())で止める。描画の assert には不要で、ネットワーク差で結果がぶれない。 page.setContent(html)で開き、locator('#select option').allTextContents()やquerySelector('.page.active').idで期待値を assert する。隠れているページの<select>を操作する時はselectOption(..., { force: true })。- iframe 内で
localStorageを使うページ(埋め込みフォーム等)はsetContentだと不透明オリジンでSecurityErrorになる。HTML を一時ファイルに書いてpage.goto(file://…)で開く。 pageerrorを集め、「対象機能に関するエラーが 0 件」も assert に入れる。旧 DOM を消したのにgetElementById(...).addEventListenerが残っていると読込時に script 全体が止まり、画面が真っ白になる事故をここで拾える。
const STUB = `<script>
window.__calls = [];
var __handlers = { getList: function () { return ["A","B"]; } };
function __b(s, f) { return new Proxy({}, { get: function (_, name) {
if (name === 'withSuccessHandler') return function (fn) { return __b(fn, f); };
if (name === 'withFailureHandler') return function (fn) { return __b(s, fn); };
if (name === 'withUserObject') return function () { return __b(s, f); };
return function () { var a = [].slice.call(arguments); window.__calls.push(name);
setTimeout(function () { try { var h = __handlers[name]; var r = h ? h.apply(null, a) : {}; if (s) s(r); } catch (e) { if (f) f(e); } }, 0); };
} }); }
window.google = { script: { run: __b(null, null), host: { close: function () {} } } };
</script>`;
html = html.replace('<head>', '<head>' + STUB);
サーバー側は vm で同じ .js を実行する
vm.runInContext に SpreadsheetApp / CacheService / HtmlService / PropertiesService の偽物を入れて本番 .js をそのまま読み込み、getRange().getValues() が返す 2 次元配列を実データ(下記で取った CSV)にすると、「シートの E 列 30 件が画面の候補 30 件になる」まで Node だけで通せる。
シートの実データは Sheets API が無効でも読める
clasp login の OAuth トークン(~/.clasprc.json の tokens.default.access_token)は spreadsheets スコープを持たないが、次の 2 つは Bearer を付けるだけで通る:
- タブ名指定:
https://docs.google.com/spreadsheets/d/<ID>/gviz/tq?tqx=out:csv&sheet=<タブ名> - gid 指定:
https://docs.google.com/spreadsheets/d/<ID>/export?format=csv&gid=<gid>
Drive API の export は先頭タブしか返さないので、複数タブの時はこちらを使う。CSV は引用符内の改行があるので正規のパーサで読む。
書き込みはコマンドキューで
読み取りが上記で済んでも、書き込み経路が無いときはスクリプト側に Drive コマンドキュー(cmd_*.json → 1 分トリガー → result_*.txt)を置き、書き込み後に同じセルを read-back して結果に含める。トリガーは最新の保存版(HEAD)で動くので、デプロイ前でも push 直後から使える。push 直後の 1 回目は旧版で走ることがあるので、Unknown command が返ったら 1 分待って再投入する。
落とし穴
clasp pullしたファイルは CRLF。文字列置換の前に\r\n → \nに正規化し、書き戻し時に 1 回だけ戻す。\r\r\nが混入していないか書き戻し後に数える。- 偽物の handler で未定義の関数名は
{}を返す。画面側がresult.items.mapのように深い参照をするなら、その関数だけ handlers に実装する。 page.setContentの origin は毎回不透明なので、localStorageに状態を持つ画面は file:// で開く(手順 6)。
よくある質問
+「GAS Web アプリの画面をブラウザ操作なしで検証する(google.script.run 偽装・差し込み値置換・Sheets API 無効でも gviz で実データ)」とは何ですか?
ログイン必須の Apps Script Web アプリでも、index.html を Chromium で実描画して DOM を assert できる。偽 google.script.run は head に埋め込む(addInitScript は setContent で走らない)、サーバー差し込み値の置換、file:// が要る条件、Sheets API 無効時に OAuth トークンだけでタブ別 CSV を読む URL、書き込みはコマンドキューで read-back。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約6万トークンかかりますが、この巻物を使えば約9,000トークンで済みます。差し引き約5.1万トークン(API料金換算で約77円)・85%の節約です。
+どうやって使いますか?
無料です。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 既定・適用前バックアップ・触っていないセルの数式不変検査で安全に書き換える設計手順。列ごとの数式復元と、テストが緑のまま壊れる典型例つき。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア