[GWSStudio100本ノック] マーケティングメールのドラフトを自動レビューし基準達成まで回すエージェントを作成してみた(GAS構築編)

 2025.12.18 Yudai Imai

はじめに

本記事は、Google Workspace Studio(旧Flows)の実践ノウハウを100本紹介する連載「Google Workspace Studio活用方法100本ノック」の一つとなります。  

今回は、マーケティングメールのドラフトを自動レビューし、定めたチェック基準を満たすまでブラッシュアップを繰り返すエージェントの最終ステップで利用していた、受け取ったGoogle Driveのファイルのリンクをもとにして対象のファイルをゴミ箱に入れるGoogle Apps Script(GAS)の構築を説明する番外編的な内容となります。エージェントから連携されるGoogle Driveのファイルのリンクをもとにして、ファイルがゴミ箱に入れられる処理を説明させていただきます。

ちなみに、2025年12月時点ではWorkspace Studioにはファイルをゴミ箱に移動する処理が存在していないので今回のGASを作成しています。近い将来、Workspace Studioでデフォルトで提供される機能になるのではと感じていますが、その際はこのGASは不要になると考えています。

難易度 上級者向け
実現すること マーケティングメールのドラフトを自動レビューし、基準を達成するまでレビューをし続けるエージェントを構築することで、高品質なマーケティングメールの内容を作成することができます
想定する対象者 マーケティング/広報チームでメール配信の品質管理を効率化したい人
利用サービス Google Docs,Google Sheets, Google Chat, Google Apps Script

ユースケース

今回作成するエージェントの代表的なユースケースとしては以下のようなことが考えられると思います。

  • キャンペーンメールの品質チェック
    • ドラフトがDriveにアップされたら自動レビューを走らせ、件名・本文・CTAが基準に満たない場合に指摘を集めてさらに質の高い内容に自動でブラッシュアップします。
  • ブランドトーンの統一
    • シリーズメールの口調や表現がブランドガイドラインに合っているかをGeminiで確認し、ズレがあれば修正ポイントを提示します。
  • 法務・コンプライアンス観点の一次レビュー
    • 禁止表現や必要な免責文言が入っているかをチェックし、必要があれば法務レビュー前にマーケチーム内で修正を完了させることができます。

前提条件

今回のエージェントを作成するための前提条件は以下となります。Google Workspace Studioは2025年12月時点ではそれまではFlowsという名前で提供されていたサービスからリネームされたサービスかつまだ提供されて間もないため、このブログの内容が最新ではなくなる可能性があることをご了承ください。
  • 利用環境:Google Workspace Studioにアクセスできるユーザーであること。
  • 利用アプリ:通知先のGoogle Chatスペース(またはDM)が事前に用意されていること。Google Apps Scriptが作成できる環境が存在しており、番外編のGASの構築とWorkspace Studioへのインストールが完了していること。
  • 社内ルール:メール内容をAIに渡す際の社内ポリシーや情報管理ルールを確認済みであること。

構築手順

今回のブログではGoogle Apps Scriptの構築の概要については説明しません。もしGoogle Apps Scriptの構築について詳しく知りたい場合はGoogleの公式ドキュメントなどを確認するようにされてください。

まずは、Google Apps Scriptのサイトにアクセスしてください。そして、新しいプロジェクトを作成して適当な名前をつけてください。今回は「ゴミ箱移動」という名前を付けました。

そして、サイドメニューの歯車ボタンから設定画面にアクセスして、全般設定の中の「「appsscript.json」マニフェスト ファイルをエディタで表示する」のチェックボタンにチェックを入れてください。

設定が完了したらエディタの画面に戻ってください。そして、ファイルの中の「appsscript.json」ファイルを選択して、エディタに以下の内容を入力して保存してください。

{
  "timeZone": "Asia/Tokyo",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Drive File Manager",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "trashFileAction",
          "state": "ACTIVE",
          "name": "Trash File by URL",
          "description": "Moves a Google Drive file to the trash using its URL.",
          "workflowAction": {
            "inputs": [
              {
                "id": "fileUrl",
                "description": "The URL of the Google Drive file",
                "cardinality": "SINGLE",
                "dataType": { "basicType": "STRING" }
              }
            ],
            "outputs": [
              {
                "id": "status",
                "description": "Execution result message",
                "cardinality": "SINGLE",
                "dataType": { "basicType": "STRING" }
              }
            ],
            "onConfigFunction": "onConfigTrash",
            "onExecuteFunction": "onExecuteTrash"
          }
        }
      ]
    }
  }
}

そして、ファイルの中の「コード.gs」ファイルを選択して、エディタに以下の内容を入力して保存してください。

// ---------------------------------------------------------
// Helper Functions (Boilerplate from Guidelines)
// ---------------------------------------------------------
function pushCard(card) {
  return { "action": { "navigations": [{ "push_card": card }] } };
}

function outputVariables(variableDataMap) {
 const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction().setVariableDataMap(variableDataMap);
 const hostAppAction = AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);
 return AddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();
}

function getStringValue(inputItem) {
  if (!inputItem) return "";
  if (inputItem.stringValues && inputItem.stringValues.length > 0) return inputItem.stringValues[0];
  if (inputItem.integerValues && inputItem.integerValues.length > 0) return String(inputItem.integerValues[0]);
  return "";
}

// ---------------------------------------------------------
// Main Functions
// ---------------------------------------------------------

/**
 * ■ 設定画面 (Configuration Card)
 */
function onConfigTrash() {
  var card = {
    "sections": [
      {
        "header": "Trash File Settings",
        "widgets": [
          {
            "textInput": {
              "name": "fileUrl", // マニフェストのIDと一致
              "label": "Google Drive File URL",
              "hint": "e.g. https://docs.google.com/document/d/xxxx/edit",
              "hostAppDataSource" : {
                "workflowDataSource" : { "includeVariables" : true }
              }
            }
          }
        ]
      }
    ]
  };
  return pushCard(card);
}

/**
 * ■ 実行関数 (Execution Function)
 */
function onExecuteTrash(event) {
  console.log("Event: " + JSON.stringify(event));

  // 1. 入力の取得
  const inputs = event.workflow.actionInvocation.inputs;
  const url = getStringValue(inputs["fileUrl"]);
  
  var statusMsg = "";

  try {
    if (!url) throw new Error("File URL is empty.");

    // 2. URLからIDを抽出
    const fileId = extractIdFromUrl(url);
    if (!fileId) throw new Error("Invalid Google Drive URL. Could not extract File ID.");

    // 3. ファイルを取得してゴミ箱へ移動
    const file = DriveApp.getFileById(fileId);
    const fileName = file.getName();
    
    // 既にゴミ箱にあるかどうかのチェック(任意)
    if (file.isTrashed()) {
      statusMsg = "Skipped: File is already in trash (" + fileName + ")";
    } else {
      file.setTrashed(true);
      statusMsg = "Success: Moved to trash (" + fileName + ")";
    }

  } catch (e) {
    console.error(e);
    statusMsg = "Error: " + e.toString();
  }

  // 4. 結果の返却
  const variableDataMap = {
    "status": AddOnsResponseService.newVariableData().addStringValue(statusMsg)
  };
  
  return outputVariables(variableDataMap);
}

// ---------------------------------------------------------
// Logic Helpers
// ---------------------------------------------------------

/**
 * Google DriveのURLからファイルIDを抽出する
 * 対応パターン:
 * - /d/FILE_ID/
 * - id=FILE_ID
 */
function extractIdFromUrl(url) {
  if (!url) return null;
  
  // 一般的なパターン (/d/xxxx)
  const matchD = url.match(/\/d\/([a-zA-Z0-9_-]+)/);
  if (matchD && matchD[1]) return matchD[1];

  // パラメータパターン (id=xxxx)
  const matchId = url.match(/id=([a-zA-Z0-9_-]+)/);
  if (matchId && matchId[1]) return matchId[1];

  // URLそのものがIDの場合(念の為)
  if (url.match(/^[a-zA-Z0-9_-]+$/)) return url;

  return null;
}

すべての保存が完了したら画面右上にある「デプロイ」ボタンを選択した後に、「デプロイをテスト」を選択してください。

デプロイをテストのポップアップ画面が出てくると思いますので、この画面の中の「Application(s): Workspace Studio」の右側に出てくる「インストール」ボタンを選択してください。はじめてインストールする時には認証画面が出てくると思いますがその時は画面の表示に従って認証を実施してください。

インストールが完了するとWorkspace Studio側の中に作成した処理が追加されます。この時にWorkspace Studioに表示されない場合は画面の再読み込みを試してみてください。

初めてこのStepを設定すると以下のような認証を要求する画面が出てきます。「Grant permission」を選択して認証を順番に実施してください。

認証がすべて完了すると以下のような入力フォームのある画面に更新されます。

実行テスト

実行テストについてはこちらのブログの内容を確認してください。一連のエージェントの実行の流れを記載させていただいております。

上記のブログではファイルが削除されているかまでは画像で見せておりませんが、以下の画像のようにレビューの結果スコアが足りなかった残骸のファイルがゴミ箱に移動させられていることがわかると思います。

まとめ

マーケティングメールの品質管理を手作業で行うと、レビューの抜け漏れや表現のばらつきが発生しがちです。Workspace StudioとGeminiを組み合わせれば、ドラフト提出→自動レビュー→指摘フィードバック→再レビューというサイクルを自動化し、基準達成まで繰り返すことができます。

本記事では元記事のWorkspace Studioの中で多く作成されてしまうレビュー結果ファイルをそのままにせず、ちゃんとゴミ箱に移動させるアクションを実現するためのGASの作成方法とWorkspace Studioにインストールする方法を解説しました。エージェントの構築と合わせて試してみて、レビューの自動化による業務効率化を体感してみてください。


BACK TO LIST

   

Recent post最新記事

Contentsコンテンツ