この記事は、ポート株式会社 サービス開発部 Advent Calendar 2025 17日目の記事です。
はじめに
こんにちは!ポート株式会社で就活会議のバックエンドエンジニアをしている太田です。
本記事では、Google Apps Script (GAS) を活用して、面倒なGoogle Tag Manager (GTM) のABテスト運用を「自動生成」と「自動削除」の両面から効率化したワークフローについてご紹介します。
課題
私たちのチームでは、ABテストを実施する際にGTMを頻繁に利用しますが、その運用には大きな課題がありました。
-
設定がとにかく面倒
- ABテストのたびに、類似のフォルダ、変数、トリガー、タグを手作業で大量に作成する必要がある。
- 手作業のため、設定ミスがテスト全体に影響するリスクが伴う。
-
削除がもっと面倒
- テスト終了後、不要になった大量のコンポーネントを手動で削除するのが大変。
- 削除作業が手間なため、古い設定がGTMコンテナに放置され、管理が煩雑になりがち。
実装したもの概要
これらの課題を解決するため、2つのスプレッドシートとGASを利用したワークフローを開発しました。
- 生成ワークフロー: スプレッドシートからABテストの設定をGTMに自動で作成する。
- 削除ワークフロー: スプレッドシートから不要になったABテストの設定をGTMから自動で一括削除する。
これにより、ABテスト設定の準備から後片付けまで、一連のライフサイクルを自動化しました。
開発の裏側:Geminiとのペアプログラミング
実は、今回ご紹介したGASのスクリプト開発の大部分は、Google製の生成AIであるGeminiとペアプログラミングする形で進められました。
「GTM APIを使ってフォルダ内のタグを全部削除したい」「APIのQuotaエラーを回避するためにエクスポネンシャルバックオフを実装したい」といった、やりたいことベースの質問を投げるだけで、Geminiは精度の高いコードスニペットや実装方針を次々と提案してくれました。
特にGoogle関連サービスのAPIや仕様に関する知識は非常に正確で、まるでGTMの仕様を熟知した専属エンジニアが隣にいるかのような開発体験でした。
生成ワークフローの実装内容
用意したもの
- Google Apps Script (GAS): GTM APIを操作するロジックを実装。
- スプレッドシート: ABテストの設定情報を入力するUIとして利用。
処理のフロー図
GAS内のロジック
-
スプレッドシートからの情報取得
ユーザーが実行すると、スプレッドシートのアクティブな行からIssue番号やABテストのパターンといった情報をオブジェクトとして取得します。 -
GTM APIによる動的生成
取得した情報を基に、TagManagerサービスを使って、今回のABテスト専用の新しいワークスペースと、設定一式を格納するフォルダを動的に作成します。 -
テンプレートを用いたコンポーネント生成
変数、トリガー、タグといった各コンポーネントは、あらかじめGAS内にJSON形式のテンプレートとして定義しておきます。このテンプレート内のプレースホルダ(例:#{ISSUE_NUMBER})を、スプレッドシートから取得した動的な値で置換し、GTM APIにリクエストを送信して各コンポーネントを生成します。// 変数設定のテンプレート(概念) const variableTemplate = { name: `ABテストのパターン #{ISSUE_NUMBER}`, type: 'c', // ファーストパーティCookie parameter: [{ key: 'cookieName', value: 'ab_test_#{ISSUE_NUMBER}_cookie' }] }; // テンプレートに動的な値を埋め込んで変数を作成 const variableName = variableTemplate.name.replace('#{ISSUE_NUMBER}', issueNumber); // ...同様に他の値も置換 TagManager.Accounts.Containers.Workspaces.Variables.create( { name: variableName, /* ...他のパラメータ */ }, workspacePath );
工夫したところ
-
ワークスペースの柔軟な選択
コードの一部を修正することで、毎回新しいワークスペースを作るだけでなく、既存の「Default Workspace」に設定を作成することも可能にし、運用に合わせて柔軟に選択できるようにしました。 -
JSONテンプレートの活用
GTMの各コンポーネント設定をJSONテンプレートとして管理することで、複雑なトリガーや変数の依存関係をコード上で意識することなく、正確な設定を注入できるようにしました。これにより、実装の簡素化とメンテナンス性の向上を実現しています。
削除ワークフローの実装内容
用意したもの
- Google Apps Script (GAS): 削除ロジックを実装。
- スプレッドシート: 削除対象のフォルダを選択するUIとして利用。
処理のフロー図
GAS内のロジック
-
削除対象の確定
ユーザーがスプレッドシート上で削除したいフォルダにチェックを入れ、実行すると、対象フォルダIDのリストを取得します。 -
動的なワークスペース作成
生成時と同様に、他のユーザーの編集と競合しないよう、削除処理専用の新しいワークスペースをAPIで作成します。 -
フォルダ内要素の完全削除
GTMではフォルダを削除しても中身は残ってしまうため、依存関係の解除 → 中身の削除 → フォルダの削除の順番でTagManager.Accounts.Containers.Workspaces.Tags.listなどからで取得し、一つずつ削除します。 -
API制限対策 (エクスポネンシャルバックオフ)
短時間に大量のAPIリクエストを送るとQuota exceededエラーが発生します。これを回避するため、API呼び出しをラップするリトライ処理を実装しました。エラーを検知すると、待機時間を指数関数的に延ばしながら再試行します。function callGtmApiWithRetry(apiCall, maxRetries = 5) { for (let i = 0; i < maxRetries; i++) { try { return apiCall(); // API呼び出しを実行 } catch (e) { if (e.message.includes('Quota exceeded')) { const waitTime = Math.pow(2, i) * 1000; Utilities.sleep(waitTime); // 待機 } else { throw e; } } } throw new Error('API call failed after multiple retries.'); } -
フォルダ自体の削除
フォルダ内が空になったことを確認してから、最後にフォルダ自体を削除します。
工夫したところ
-
安全な実行環境の確保
生成ワークフローと同様に、毎回新しいワークスペースや既存のワークスペースを指定しながら行うようにすることで、他の作業と競合することなく安全に削除処理を実行できるようにしました。 -
最適な削除手順の確立
GTMのコンポーネント間には依存関係が存在し、削除する順序を間違えるとエラーになります。このワークフローでは、依存関係の末端(タグなど)から順に削除していくロジックを組むことで、エラーを防ぎ、確実なクリーンアップを実現しました。
まとめ
「自動生成」と「自動削除」、2つのワークフローを開発したことで、私たちのチームのABテスト運用は劇的に改善されました。
-
工数削減
面倒な手作業がなくなり、ABテストの準備と後片付けにかかる時間が数時間から数分に短縮されました。 -
ミス防止
ヒューマンエラーの介在をなくし、設定ミスや削除漏れを撲滅しました。 -
GTMの健全化
不要な設定が溜まることなく、GTMコンテナを常にクリーンな状態に保てるようになりました。
今回、開発のパートナーとしてGeminiを活用しましたが、特にGoogleサービス(GAS, GTM, Googleスプレッドシート)に関する知見は驚くほど正確で、複雑なAPIの仕様やエラーハンドリングについても的確なアドバイスを得ることができました。まさに「餅は餅屋」を実感した開発体験でした。
日々の業務で感じる「ちょっとした面倒」は、自動化によって解決できるチャンスの宝庫です。
この記事が、皆さんの業務改善のヒントになれば幸いです。
最後までお読みいただきありがとうございました!