ZhgChg.Li

GA4自動数値通知ロボット:無料で作る3ステップ|Google Apps ScriptとTelegram Bot連携

GA4のデータ通知を自動化したい方必見。Google Apps ScriptでRPAを実装し、Telegram Botと連携する3ステップで無料の通知ロボットを構築。手間なくリアルタイムに重要指標を受け取れます。

GA4自動数値通知ロボット:無料で作る3ステップ|Google Apps ScriptとTelegram Bot連携

簡単3ステップ — 無料のGA4自動データ通知ボットを作る

Google Apps Script を使って RPA を実現し、GA4 と Telegram Bot を自分で連携したデータ通知ロボット

Photo by BoliviaInteligente

Photo by BoliviaInteligente

はじめに

大体2020年頃から手元のツールを使ってRPAの実現を模索し始めました。最初は個人のルーティン作業を自動化するためだけでしたが、後に仕事でもより大規模な組織に関わるようになり、チームをまたぐ作業や人に依存するタスク、さらには繰り返し発生する作業に頻繁に遭遇するようになりました。そこで初めてRPA自動化の効果を実感しました。

例えば、ある繰り返し作業が毎月10回発生し、1回あたり30分かかり、60人が対応するとします。年間でチームは合計3,600時間をこの作業に費やしています。これを自動化するために100時間を投資すれば、その後解放された時間をより価値のある仕事に充てることができます。実質的には、3,600時間の無駄な工数+3,600時間のより投資価値のある成果となります。

詳細は以前の記事をご参照ください:

他に行った RPA:

管理画面のデータを見ると、以前、多くの記事が ChatGPT やさまざまな GenAI サービスに収録されており、エンジニア以外の方でも RPA を使って問題を解決したい人たちに間接的に役立っていることがわかりました。そこで、今後も自分の生活や仕事で出会った RPA の事例と解決策を皆さんと共有していきます — ZRealm Robotic Process Automation

お知らせ時間

もしあなたやあなたのチームが自動化ツールやプロセス連携のニーズがある場合、Slackアプリ開発、Notion、Asana、Google Sheet、Google Form、GAデータなど、さまざまな連携のご要望に対応します。ぜひ開発お問い合わせください。

本記事の Google Analytics 4 x Telegram Bot

今回紹介する連携シナリオは、前回の記事「10分で簡単にLine NotifyからTelegram Bot通知へ移行」を読んで思いつきました。私のMediumバックアップサイト「zhgchg.li」のGA4ウェブサイトデータをずっと見ていなかったので、毎日過去7日間のサイトデータを指定のTelegramチャンネルに送信する通知ボットを作ろうと思いました。

本記事は小品ですが、完全な自動化データレポートを作成したい場合は、以前の記事「使用 Google Apps Script 實現每日數據報表 RPA 自動化」を参照してください。また、以前に GA4 を使って App Crash-free rate を取得した例もありますので、こちらの記事「Crashlytics + Google Analytics 自動查詢 App Crash-Free Users Rate」もご覧ください。

  • Google Apps Script の無料制限、詳細な使い方、デプロイ、機能紹介については本記事では詳しく説明しません。詳しくは以前の記事をご参照ください。

  • Telegram Bot の作成や使用方法については本記事では詳しく説明しません。以前の記事を参照してください:之前文章

成果

まず最終結果を示します。Google Apps Script は毎日12時から13時の間に自動で取得したい Google Analytics 4 のウェブサイトデータを取得し、メッセージにまとめて Telegram Bot を通じて私の Telegram チャンネルに送信します。これにより、直近7日間のサイトデータを素早く確認できます。

私が観測したいデータは:

  • 直近7日間の 7daysAgo ~ today 総閲覧数 screenPageViews

  • アクティブユーザー数 active7DayUsers

  • 新規ユーザー数 newUsers

  • Top 10 閲覧ページ screenPageViews / pageTitle

  • 新規ユーザーの初回参照元メディア newUsers / firstUserSourceMedium

実際にはご自身のニーズに合わせて GA Dev Tools を使って調整してください。

Step 1. GA4 Query Explorer 公式ツール を使ってデータレポートのクエリパラメータを生成する

まず、GA4 Query Explorer 公式ツールを使って、必要なクエリデータレポートのパラメータを生成します:

  1. Select Property: あなたの property 番号 をメモしてください
    property 番号は後で Google Apps Script を作成する際に使用します。

  2. start date, end date: レポートの開始~終了の日付範囲。YYYY-MM-DD または yesterdaytodayNdaysAgo のマジック変数を使用できます。

  3. metrics: 取得したい指標を選択してください

  4. dimensions: 取得したいディメンションを選択してください

  5. metric aggregations: データ集計ルール

ここでは私のケースを例にします:

  1. プロパティ番号: 318495208

  2. start_date: 7daysAgo

  3. end_date: yesterday
    GAのデータレポートは遅延があるため、前日から7日間のデータが最も正確です。

  4. metric aggregations: total

その他の filter、limit はご自身のニーズに応じて設定可能です:

filter は使わないので空欄にします;limit は 10 に設定します。なぜなら Top 10 だけ知りたいからです。

「MAKE REQUEST」をクリックして対応するデータレポートのクエリパラメータと結果を生成:

以下のリクエストパラメータをメモしてください。後で Google Apps Script を作成する際に使用します:

{
  "dimensions": [
    {
      "name": "pageTitle"
    }
  ],
  "metrics": [
    {
      "name": "screenPageViews"
    }
  ],
  "dateRanges": [
    {
      "startDate": "7daysAgo",
      "endDate": "yesterday"
    }
  ],
  "limit": "10",
  "metricAggregations": [
    "TOTAL"
  ]
}

結果:

  • GA上のデータとの比較は正確で、一致しています ✅✅✅

Step 2. Google Apps Script を作成し、Google Analytics Data API でデータを取得する

  • https://script.google.com/home にアクセスしてください

  • 新しいプロジェクトを作成し、プロジェクト名を設定する

  • 「サービス」->「+」をクリックしてサービスを追加

  • 「Google Analytics Data API」を選択してください

  • 「追加」をクリックしてください

Google Analytics Data API クエリコードを貼り付けて組み合わせる:

前の手順で生成したレポートクエリデータのパラメータ:

{
  "dimensions": [
    {
      "name": "pageTitle"
    }
  ],
  "metrics": [
    {
      "name": "screenPageViews"
    }
  ],
  "dateRanges": [
    {
      "startDate": "7daysAgo",
      "endDate": "yesterday"
    }
  ],
  "limit": "10",
  "metricAggregations": [
    "TOTAL"
  ]
}

プログラムに変換:

function execute() {
  Logger.log(JSON.stringify(fetchScreenPageViews("318495208")));
}

// 独立した関数に分けて、将来の再利用を簡単に...
// デフォルトは startDate=7daysAgo、endDate=yesterday
// 他の使い方:
// 例 fetchScreenPageViews("1111", "3daysAgo", "yesterday")
// 例 fetchScreenPageViews("2222", "yesterday", "today")
function fetchScreenPageViews(propertyId, startDate = "7daysAgo", endDate = "yesterday") {
  const screenPageViewsMetric = AnalyticsData.newMetric();
  screenPageViewsMetric.name = "screenPageViews";

  const dateRange = AnalyticsData.newDateRange();
  dateRange.startDate = startDate;
  dateRange.endDate = endDate;

  const pageTitleDimension = AnalyticsData.newDimension();
  pageTitleDimension.name = "pageTitle";

  const request = AnalyticsData.newRunReportRequest();
  request.dimensions = [pageTitleDimension];
  request.metrics = [screenPageViewsMetric];
  request.dateRanges = dateRange;

  request.limit = 10;
  request.metricAggregations = "TOTAL";

  return AnalyticsData.Properties.runReport(request, "properties/" + propertyId);
}

コード解析:

// metric 指標、複数宣言可能です...
const screenPageViewsMetric = AnalyticsData.newMetric();
screenPageViewsMetric.name = "screenPageViews";

// 例として別の active1DayUsers:
const active1DayUsersMetric = AnalyticsData.newMetric();
active1DayUsersMetric.name = "active1DayUsers";

// 日付範囲を宣言
const dateRange = AnalyticsData.newDateRange();
dateRange.startDate = startDate;
dateRange.endDate = endDate;

// dimension ディメンション、複数宣言可能です...
const pageTitleDimension = AnalyticsData.newDimension();
pageTitleDimension.name = "pageTitle";

// 例として別の dimension:
const firstUserSourceMediumDimension = AnalyticsData.newDimension();
firstUserSourceMediumDimension.name = "firstUserSourceMedium";

//

// リクエストオブジェクトを生成
const request = AnalyticsData.newRunReportRequest();
request.metrics = [active1DayUsersMetric, active1DayUsersMetric]; // 複数の場合は全て渡す...
request.dimensions = [pageTitleDimension, firstUserSourceMediumDimension]; // 複数の場合は全て渡す...

request.dateRanges = dateRange;

// 上位10件のみ取得 (Top 10)
request.limit = 10;

// データ集計ロジックを設定:合計 (SUM)
request.metricAggregations = "TOTAL";

// クエリ結果を生成
return AnalyticsData.Properties.runReport(request, "properties/" + propertyId).rows;

初回実行時には認証が必要です(後日、コードに新たな権限が追加された場合も再認証が必要になります):

実際には、Google Apps Script は今後あなたのアカウントの権限でこれらのスクリプトを実行するため、選択したアカウントに対応するGAレポートへのアクセス権があることを確認してください。

  • コードを書き終えたら、「デバッグ」→「権限の確認」をクリックしてください。

  • 実行するアカウントを選択します。通常は現在の Google Apps Script アカウントと同じです。

  • 「詳細設定」を展開 -> 「XXX に移動」をクリック
    これは自分たちが使うためのアプリケーションなので、Google の認証は不要です。

  • 「許可する」をクリックしてください

許可後に「デバッグ」や「実行」をクリックするとプログラムが実行されます:

ここではまず Logger.log(JSON.stringify()) を使って出力結果を取得します:

{
  "kind": "analyticsData#runReport",
  "dimensionHeaders": [
    {
      "name": "pageTitle"
    }
  ],
  "rowCount": 71,
  "metadata": {
    "currencyCode": "TWD",
    "timeZone": "Asia/Taipei"
  },
  "rows": [
    {
      "dimensionValues": [
        {
          "value": "ZhgChgLi"
        }
      ],
      "metricValues": [
        {
          "value": "166"
        }
      ]
    },
    {
      "metricValues": [
        {
          "value": "109"
        }
      ],
      "dimensionValues": [
        {
          "value": "Apple Watch 原廠不鏽鋼米蘭錶帶開箱 \\| ZhgChgLi"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "iOS ≥ 13.1 使用「捷徑」自動化功能搭配米家智慧家居 \\| ZhgChgLi"
        }
      ],
      "metricValues": [
        {
          "value": "101"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Medium Partner Program 終於對全球(包含台灣)寫作者開放啦! \\| ZhgChgLi"
        }
      ],
      "metricValues": [
        {
          "value": "85"
        }
      ]
    },
    {
      "metricValues": [
        {
          "value": "77"
        }
      ],
      "dimensionValues": [
        {
          "value": "iOS 捷徑自動化應用場景 — 自動轉發簡訊與自動建立提醒待辦事項 \\| ZhgChgLi"
        }
      ]
    },
    {
      "metricValues": [
        {
          "value": "51"
        }
      ],
      "dimensionValues": [
        {
          "value": "遊記 9/11 名古屋一日快閃自由行 \\| ZhgChgLi"
        }
      ]
    },
    {
      "metricValues": [
        {
          "value": "42"
        }
      ],
      "dimensionValues": [
        {
          "value": "iOS 隱私與便利的前世今生 \\| ZhgChgLi"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "iOS Vision framework x WWDC 24 Discover Swift enhancements in the Vision framework Session \\| ZhgChgLi"
        }
      ],
      "metricValues": [
        {
          "value": "34"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "iOS ≥ 18 NSAttributedString attributes Range 合併的一個行為改變 \\| ZhgChgLi"
        }
      ],
      "metricValues": [
        {
          "value": "30"
        }
      ]
    },
    {
      "metricValues": [
        {
          "value": "30"
        }
      ],
      "dimensionValues": [
        {
          "value": "手工打造 HTML 解析器的那些事 \\| ZhgChgLi"
        }
      ]
    }
  ],
  "metricHeaders": [
    {
      "type": "TYPE_INTEGER",
      "name": "screenPageViews"
    }
  ],
  "totals": [
    {
      "dimensionValues": [
        {
          "value": "RESERVED_TOTAL"
        }
      ],
      "metricValues": [
        {
          "value": "1229"
        }
      ]
    }
  ]
}
  • Google Apps Script が GA データの取得に成功しました!🎉🎉🎉

Step 3. 組み合わせる!Google Apps Script + GA4 + Telegram Bot

上記の記事「 10 分鐘快速移轉 Line Notify 到 Telegram Bot 通知 」に従って、Telegram Bot を作成し、Bot Token と通知先の Channel Chat ID を取得してください。

const telegramToken = "XXXX" // あなたの Telegram Bot トークンを入力してください
//

function execute() {
  const screenPageViewsReport = fetchScreenPageViews("318495208");
  
  //
  const total = parseInt(screenPageViewsReport.totals[0].metricValues[0].value);
  var message = "総閲覧数:"+total.toLocaleString()+"\n";

  screenPageViewsReport.rows.forEach(function(element, index) {
    const pageTitle = element.dimensionValues[0].value;
    const value = parseInt(element.metricValues[0].value);

    message += "[トップ "+(index + 1)+"] "+pageTitle+": "+value.toLocaleString()+"\n";
  });

  sendNotifyMessage(message, -xxxx); // あなたのチャンネルチャットIDを入力してください
}


// Telegramの指定チャンネルチャットIDにメッセージを送信する
function sendNotifyMessage(message, chatId) {
  var url = "https://api.telegram.org/bot"+telegramToken+"/sendMessage";
  
  const payload = {
    "chat_id": chatId,
    "text": message,
    "disable_web_page_preview": true
  } 
  const options = {
    'method': 'post',
    'contentType': 'application/json',
    'muteHttpExceptions': true,
    'payload': JSON.stringify(payload)
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  if (data["ok"] == undefined \\|\\| data["ok"] != true) {
    if (data["error_code"] != undefined && data["error_code"] == 429) {
      Utilities.sleep(1000);
      sendNotifyMessage(message, chatId);
    }
  }
}

function fetchScreenPageViews(propertyId, startDate = "7daysAgo", endDate = "yesterday") {
  const screenPageViewsMetric = AnalyticsData.newMetric();
  screenPageViewsMetric.name = "screenPageViews";

  const dateRange = AnalyticsData.newDateRange();
  dateRange.startDate = startDate;
  dateRange.endDate = endDate;

  const pageTitleDimension = AnalyticsData.newDimension();
  pageTitleDimension.name = "pageTitle";

  const request = AnalyticsData.newRunReportRequest();
  request.dimensions = [pageTitleDimension];
  request.metrics = [screenPageViewsMetric];
  request.dateRanges = dateRange;

  request.limit = 10;
  request.metricAggregations = "TOTAL";

  return AnalyticsData.Properties.runReport(request, "properties/" + propertyId);
}

コード解析:

//...
  // レポートから返された JSON の total の位置を取得し、parseInt で文字列を整数に変換
  // .toLocaleString() -> 数字をフォーマット、123456 -> 123,456
  const total = parseInt(screenPageViewsReport.totals[0].metricValues[0].value);
  var message = "総閲覧数:"+total.toLocaleString()+"\n";

  // レポートから返された JSON のデータをループし、メッセージを作成
  screenPageViewsReport.rows.forEach(function(element, index) {
    const pageTitle = element.dimensionValues[0].value;
    const value = parseInt(element.metricValues[0].value);

    message += "[Top "+(index + 1)+"] "+pageTitle+": "+value.toLocaleString()+"\n";
  });
//...

実行:上部の「実行」または「デバッグ」をクリックし、メソッド名が「 execute 」になっていることを確認してください:

  • 成功!🎉🎉🎉

スケジュールを設定して定期的に自動実行する

最後のステップは、レポートロボットを定期的に自動実行させることです。左側メニューから「トリガー」へ移動します:

  • 右下の「トリガーを追加」ボタンを選択してください

  1. 実行する機能を選択: 「execute」メソッド名を選択してください

  2. 実行するデプロイ作業を選択: 「上端」を選択してください

  3. アクティビティのソースを選択: 「時間駆動」を選択してください

  4. 時間型トリガーの種類を選択:希望するトリガーの頻度を選んでください

  5. 選択期間:毎日自動実行したい時間を選択してください

  6. 実行失敗時の通知メールの頻度設定

  7. 保存

完了です!これで指定した時間に自動で実行されます。 🎉🎉🎉

拡張課題

他のデータ、新規ユーザー数や参照元なども、前述のコードで同様に取得可能です。ここでは繰り返しませんので、みなさんの宿題としてお考えください。

Post MediumからZMediumToMarkdownで変換。

GitHub で編集
この記事を改善
本記事は Medium で初公開
オリジナルを読む
この記事をシェア
リンクをコピー · SNS でシェア
ZhgChgLi
著者

ZhgChgLi

An iOS, web, and automation developer from Taiwan 🇹🇼 who also loves sharing, traveling, and writing.

コメント