簡単な3ステップ — 無料でGA4自動データ通知ボットを作成する
Google Apps Script を使って RPA を実現し、GA4 と Telegram Bot を連携したデータ通知ロボットを自作する

Photo by BoliviaInteligente
はじめに
大体2020年頃から、自分の手元にあるツールを使ってRPAを試行錯誤してきました。最初は個人のルーティン作業の自動化だけでしたが、後に仕事でもより大規模な組織に関わるようになり、チーム間の連携や人に依存する作業、さらには繰り返しの作業に頻繁に直面するようになりました。そこで初めて、RPA自動化の効果を実感しました。
例えば、ある繰り返し作業が毎月10回発生し、1回あたり30分かかるとします。これに60人が関わる場合、年間でチーム全体で3,600時間を費やしています。もし100時間を投資して自動化を開発できれば、その後に解放された時間をより価値のある仕事に充てることができます。実質的には3,600時間の無駄な工数+3,600時間のより価値ある成果ということになります。
詳細は以前の記事をご参照ください:
その他に行ったRPA:
-
[GMail to Slack] Google Apps Script を使って Gmail メールを Slack に転送する方法
-
[Google Form x Google Sheet xSlack] Slackで作る完全自動WFH社員健康状況報告システム
-
[Big Query x Slack ] Crashlytics + Big Query でよりリアルタイムで便利なクラッシュ追跡ツールを作る
-
[Google Analytics x Slack] Crashlytics + Google Analytics 自動で App のクラッシュフリー ユーザー率を照会
-
[Github Webhook x Line Notify] Google Apps Scriptを使って3ステップで無料でGithubリポジトリのスター通知を作成する方法
-
[Slack x OpenAI (ChatGTP)] Slack & ChatGPT インテグレーション
-
[Google Analytics x Google Sheet] Google Apps Scriptを使った毎日データレポートのRPA自動化
-
[iOS Shortcut x Line x Reminders] iOSショートカット自動化の活用例 — SMS自動転送とリマインダー自動作成
-
[Apple Store API x Google Play Console API x Github Action] Github Action x ZReviewTender 無料で素早くあなたのアプリストア評価監視ロボットをデプロイ
-
[Telegram Bot] 10分で簡単にLine NotifyからTelegram Bot通知へ移行する方法
-
[Medium to Jekyllrb] Mediumから自分のサーバーへ無痛で移行する方法
バックエンドのデータを見ると、以前多くの記事が ChatGPT やさまざまな GenAI サービスに収録されており、エンジニア以外の方でも RPA を使って問題を解決したいと思っている方々の助けになっています。そこで、今後も自分の生活や仕事で出会った RPA のシナリオと解決策を皆さんと共有していきます — ZRealm Robotic Process Automation 。
お知らせタイム
もしあなたやチームが自動化ツールやワークフロー連携を必要としている場合、Slackアプリ開発、Notion、Asana、Google Sheets、Google Forms、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 公式ツールを使って、必要なクエリデータレポートのパラメータを生成します:

-
Select Property: あなたの
property 番号をメモしてください
property 番号は後で Google Apps Script を作成する際に使用します。 -
start date, end date: レポートの開始日と終了日の範囲。
YYYY-MM-DDまたはyesterday、today、NdaysAgoのマジック変数が使えます。 -
metrics: 取得したい指標を選択してください
-
dimensions: 取得したいディメンションを選択してください
-
metric aggregations: データの集計方法
こちらは私のケースを例にします:
-
プロパティ番号:
318495208 -
start_date:
7daysAgo -
end_date:
yesterday
GAのデータレポートは遅延があるため、前日から7日間のデータを取得するのが最も正確です。 -
metric aggregations:
total
その他の filter や limit は必要に応じて設定可能です:

filter は使わないので空欄にします;limit は 10 と入力します。トップ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 += "[Top "+(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 で文字列を INT 数値に変換
// .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 」になっていることを確認してください:


- 成功!🎉🎉🎉
スケジュール設定で定期的に自動実行する
最後のステップは、レポートボットを定期的に自動実行させることです。左側のメニューから「トリガー」へ進みます:

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

-
実行する関数を選択: 「
execute」という関数名を選んでください -
実行するデプロイを選択: 「
上端」を選択してください -
トリガーの種類を選択: 「
時間主導」を選択してください -
時間型トリガーのタイプを選択: 希望するトリガーの頻度を選んでください
-
実行時間の設定: 毎日自動で実行したい時間を選択してください
-
実行失敗時の通知メールの頻度設定
-
保存
完了です!これで指定した時間に自動で実行されます。 🎉🎉🎉
拡張課題
他のデータ、新規ユーザー数や参照元メディアなども、前述のコードで同様に取得可能です。ここでは繰り返しませんので、皆さんの宿題としてお考えください。
Post Mediumから変換されたもの ZMediumToMarkdown.



コメント