【GA4】記事のアクセス数を検知してSlackで通知する仕組み
前回の記事本題に入る前に結論としてはこんな機能ができました!課題や背景(前回からの続き)実装したけど、、、まだ機能が足りていないフィードバックの重要性実装案実装の流れストレスなく見れるようにするための工夫実際にSlackに送信された内容具体的な実装早朝に実行するスクリプト群①:サイトのアクセスイベントデータをBigQueryExport機能によってBigQueryに送信する。②:データの整形③:DataPotalからBigQueryを参照するよう設定する。④:DataPotalのメール配信機能を用いてGmailにPDFを送信する。11時ごろに実行するスクリプト⑤⑥:②で整形したデータをSQLで必要な形にして取得する。⑦⑧:④で送信したPDFを取得する。結果&反応
課題や背景(前回からの続き)
実装したけど、、、
前回のNotionAPIによるプロパティ変更検知によって記事の執筆完了を検知し、Slackに通知を飛ばせるようになりました。
その後、似たような仕組みで社外向け記事の公開も検知できるようにしたのですが、まる美botに話させる内容はこれだけでは不十分だなと感じていました。
【補足】
オーリーズでは社内ナレッジ共有のために、各メンバーがNotionに業務で得た知見や情報に関する記事を執筆しています。
そして、その中の一部を外部公開しており、当サイトに掲載されるようになっています。
以前はKibelaをナレッジ共有に使っていましたが、当サイトの公開に合わせて、連携のしやすいNotionに移行したという経緯があります。
まだ機能が足りていない
「以前使っていたKibelaと比較して新規公開記事を検知しづらいよね」という課題を解消するため(あと、まる美とのふれあいのため)に実装したまる美botですが、実はKibelaでは記事に対するコメントに関しての通知機能もありました。
ただ同様の機能を実装しようとしても、Notionではコメント機能が使いづらそうなうえ、新着コメントをNotionAPIで抽出することも難しそうだということがわかりました。
フィードバックの重要性
ということで運用面でも技術面でも早々に暗礁に乗り上げてしまったコメント通知機能ですが、そもそも「なぜ」記事を書いたことに対するコメントを通知したかったのでしょうか?
結論から言うと、僕は「コメントをもらうということ」は記事投稿に対する報酬のひとつであると考えています。記事に対して「参考になりました」とか「役に立ちました」って言われるのって単純に嬉しいですし、モチベーションになりますよね?
オーリーズでは外部公開のネタ元になるように、各チームにナレッジ記事投稿の目標があります。(1人当たり数か月に1本程度なので少ないですが)
しかし、本来的には目標に関係なく、個人個人が良い記事を書くことで適切に報酬を得られて自発的に書きたくなる状態が理想的ではないかと思います。
そのような状態を作る枠組み作りを目標としたときに、フィードバックの種類は必ずしもコメントの通知にこだわる必要はありません。記事の質に対する適切なフィードバックを与えられれば良いのです。
そこで僕は「アクセスランキング発表システム」をつくることで、コメント通知のフィードバック的側面の代替とすることにしました。
これは、記事が社外のユーザーにどれだけ読まれたかということを可視化して発表するシステムで、自分の記事がどれだけ貢献したがが分かるようになります。また貢献度の高い記事を表彰することで外部に公開されるような記事を書きたいという皆のモチベーション向上にも繋げられるのではないかと考えました。
実装案
実装の流れ
実行したいのはアクセスランキングの発表ですが、それだけではもったいないのでランキング外の記事の分析ができる基盤があると便利です。
アクセス数の把握はGoogle Analytics 4を使用しBigQueryへのエクスポート機能で元となるデータを取得します。そしてBigQueryと相性の良いData PotalをBIとして利用しましょう。
システムの概要が以下になります。
それぞれのタスクで行っている作業の概要は以下となります。
①:サイトのアクセスイベントデータをBigQueryExport機能によってBigQueryに送信する。
②:イベントデータのままでは使いづらいので整形をする。
③:DataPotalからBigQueryを参照するよう設定する。
④:DataPotalのメール配信機能を用いてGmailにPDFを送信する。
⑤⑥:②で整形したデータをSQLで必要な形にして取得する。
⑦⑧:④で送信したPDFを取得する。
⑨:Slackにアクセスイベントランキングを送信する。
なお、処理についてですが、①~④まではGASではない箇所です。スクリプトの実行などはそれぞれのツールのスケジューリング機能を作って実行しています。
⑤~⑨まではGASでトリガーをスケジュールして実行しています。
これで完全自動化を達成しています。
ストレスなく見れるようにするための工夫
Slackで送信する情報についてはとにかく見る人にストレスがかからないことを意識し、BIの情報もPDFで送ることで遷移しなくても色々な情報が見れる作りにしました。(Slack上でPDFは開けるので)
また、発表のリアルタイム感を出すために随所で「タメ」をつくって発表する作りにしました。
ところどころでまる美botが「教えてやるにゃ」とか「まとめておいてやったからみるにゃ」みたいにやたらと高圧的な話し方なのは、僕のまる美のイメージによるもので特に意味はないです。
ここだけの話
まる美の口調についてはあまり意味がないのですが、「まる美が話者である」ことには非常に意義があると思っています。例えばこれが「社内通知bot」みたいなものだったら味気ないし、「誠愛さん(副社長)」からの通知だと業務色が強すぎると思います。
業務にあまり関係がないけど全従業員から親しみがある「まる美」の存在はこういったときに非常にありがたい存在です。
実際にSlackに送信された内容
以下が実際のSlackへの送信になります。
具体的な実装
それぞれの具体的な実装についてみていきます。
早朝に実行するスクリプト群
①:サイトのアクセスイベントデータをBigQueryExport機能によってBigQueryに送信する。
特筆すべきポイントはないので設定方法については割愛します。頻度は毎日とストリーミングの双方にチェックを入れいています。これでBigQuery側にユーザーアクセスの都度データがたまることになります。
テーブルの内容については以下を参照してください。
②:データの整形
データの整形についてはBigQueryのスケジュールされたクエリの機能を使います。
データの加工については、以下のように必要情報を抽出したうえで著者名などを付加する形にしています。最終的にはユニークなユーザーID数(以下UU数)をカウントしたいのですが、あえてこの段階ではUU数をカウントして日別のデータに集約することはしていません。※後で説明します。
データの更新に関してはデータを毎回全量delete&insertしているとデータの読み込み量が経過日数に比例してしまうので二週間前のデータから削除するスクリプト、同期間のデータを挿入するスクリプトの2本をワンセットで実行することで更新しています。
- 削除スクリプト
- 挿入スクリプト
注意点
- CURRENT_DATE()はタイムゾーンを指定しないと自動実行ではUTCになってしまうようです。早朝に更新するのでタイムゾーンの指定はしておいた方が良いです。
- 早朝に実行するためintradayのテーブルに前日のデータが残ってしまっていることが多いです。最初にUnionして一つのデータとして扱っておきます。
③:DataPotalからBigQueryを参照するよう設定する。
DataPotalの具体的な作表に関しては今回は説明しません。
PDFで送ることを考慮して以下のようなシンプルな作表にしています。
UU数を集計するために「APPROX_COUNT_DISTINCT(user_pseudo_id)」を指標としています。
なぜBigQueryで集計しないのか
UU数の集計をBigQueryで日別で行った場合、Aというユーザーが4/1,4/2の二日間アクセスした場合UU数は2となります。
一方で、DataPotalでAPPROX_COUNT_DISTINCTを利用した場合は期間内でのUU数がカウントされるので、指定期間に4/1,4/2の両方が含まれていればUU数は1となります。
指定期間に合わせた集計ができるところはDataPotalの関数の強みですね。
④:DataPotalのメール配信機能を用いてGmailにPDFを送信する。
以下から設定
11時ごろに実行するスクリプト
⑤⑥:②で整形したデータをSQLで必要な形にして取得する。
よく見られた記事TOP3を取得するSQLを実行します。トップページのビューが多いのは当然なので除外しておきます。また、今回はUU数をSQLで計算していますが、日ごとではなく指定期間内でのUU数を数えているので同期間のDataPotalの数値と一致するような仕組みとなっています。
以下のスクリプトでresultに記事情報が代入されます。(BigQueryのクライアントライブラリの追加も必要です。)
const result = BigQuery.Jobs.query(queryRequest, "プロジェクト名");
の後からは、まる美を話させるために以下のスクリプトを追加します。
(先程のシステムの概要図ではわかりやすさのため⑨でSlackへ送信していましたが、実際はデータを取得しつつSlackへの送信も並行して行っています。)
Utility.sleepはまる美をゆっくりしゃべらせるために利用しています。
- 利用しているメソッド
新着記事のランキングも似たようなスクリプトで実装しました。
⑦⑧:④で送信したPDFを取得する。
こちらの実装はほぼこちらのサイトのままです。