Android や iOS でアプリでは何度もバージョンアップしてリリースすることが多いです。
ですのでユーザーが最新のバージョンのアプリを使っているかなど、アプリバージョンごとのユーザー比率が気になることがあるかと思います。
最近、アプリバージョンごとのユーザー比率を BigQuery から取得して Slack に通知する仕組みを実装したので、その方法についてご紹介いたします。
実際に実行してみると、以下のような感じで Slack へ通知が行われるようになります。
アプリバージョンごとのユーザー比率 (2021年03月15日)
## Android
- 1.2.0 : 57.1% (4)
- 1.1.2 : 14.3% (1)
- 1.1.0 : 14.3% (1)
- 1.0.0 : 14.3% (1)
## iOS
- 1.2.0 : 54.2% (13)
- 1.1.1 : 37.5% (9)
- 1.1.0 : 4.2% (1)
- 1.0.4 : 4.2% (1)
この仕組みを実装するにあたって、以下の対応が必要になります。
- BigQuery からアプリバージョンごとのユーザー比率を取得するためのスクリプトを作成
- GitHub Actions のスケジュール機能を使って一日一回、上記で作成したスクリプトを実行
- 実行完了後、GitHub Actions から Slack へ通知
ちなみにアプリには Firebase Analytics を導入していることが前提になります。
1. スクリプト作成
認証のための準備
BigQuery からデータを取得するにあたって認証が必要になります。
詳細は こちら を参照してください。
まずはローカル環境で確認するために、私は以下の対応を行いました。
- 認証情報が記載されている JSON ファイルをダウンロードして用意
- 環境変数
GOOGLE_APPLICATION_CREDENTIALS
でダウンロードした JSON ファイルのパスを設定
余談ですが環境変数の設定は direnv を使うと、特定のディレクトリ配下にのみ環境変数を設定できるので便利です。
このファイルは後ほど GitHub Actions の設定でも必要になります。
スクリプト作成
スクリプトは Ruby で書きました。
まずは以下の内容で Gemfile を作成し、bundle install
を実行して Gemfile.lock
ファイルを生成します。
# frozen_string_literal: true
source "https://rubygems.org"
gem "google-cloud-bigquery"
続いて、スクリプトを以下のように作成します。
スクリプトは こちら を参考に実装しています。
require "google/cloud/bigquery"
def create_user_ratio_string(rows, os)
users = rows.filter { |row| row[:os] == os && !row[:ver].nil? }
# 「os」で指定されたユーザー数の合計を算出
user_count = users.reduce(0) { |sum, row| sum + row[:cnt] }
# 上位10件まで表示
users.take(10).reduce("## #{os}\n\n") do |str, row|
percent = sprintf("%.1f", row[:cnt] * 100.0 / user_count)
percent_str = "#{percent}%".ljust(6)
"#{str}- #{row[:ver].ljust(8)} : #{percent_str}(#{row[:cnt]})\n"
end
end
def query
bigquery = Google::Cloud::Bigquery.new
yesterday = Date.today - 1
sql = "SELECT device.operating_system AS os, app_info.version AS ver, COUNT(DISTINCT user_pseudo_id) AS cnt " \
"FROM `<project_name>.analytics_<property_id>.events_#{yesterday.strftime("%Y%m%d")}` " \
"GROUP BY os, ver " \
"ORDER BY os, cnt DESC"
# Location must match that of the dataset(s) referenced in the query.
rows = bigquery.query sql do |config|
config.location = "US"
end
str = "```\n#{yesterday.strftime("アプリバージョンごとのユーザー比率 (%Y年%m月%d日)")}\n\n"
str += create_user_ratio_string(rows, "Android")
str += "\n"
str += create_user_ratio_string(rows, "iOS")
str += "```"
puts str
end
query
query
メソッドの先頭の sql =
部分が BigQuery からデータを取得するための SQL になります。
SELECT device.operating_system AS os, app_info.version AS ver, COUNT(DISTINCT user_pseudo_id) AS cnt
FROM `<project_name>.analytics_<property_id>.events_#{yesterday.strftime("%Y%m%d")}`
GROUP BY os, ver
ORDER BY os, cnt DESC
テーブルについて
Firebase のプロジェクトごとに analytics_<property_id>
という名前のデータセットが BigQuery のプロジェクトに追加されます。
ですので FROM
の部分の <project_name>.analytics_<property_id>
にはそれぞれのプロジェクトで追加されているデータセットの名前を指定するようにしてください。
また、データセット内には events_YYYYMMDD
という形式の名前でテーブルが毎日作成されます。
ですので events_#{yesterday.strftime("%Y%m%d")}
の部分は前日のテーブルから情報を取得していることになります。
参考: https://support.google.com/firebase/answer/7029846?hl=ja
テーブルから取得できる情報について
テーブルから取得できる情報は こちら に記載があります。
上記の SQL では以下の情報を参照しています。
-
device.operating_system
: OS -
app_info.version
: アプリバージョン -
user_pseudo_id
: ユーザーの仮ID
これらの情報から、SQL では OS、アプリバージョン、アプリバージョンごとのユーザー数を取得しています。
データの整形
上記で取得した情報 create_user_ratio_string
メソッドに渡すことによって、OS ごとにユーザー数を合計してユーザー比率を計算して文字列に整形しています。
以上でスクリプトの作成は完了です。
2. GitHub Actions の設定
次に GitHub Actions の設定を行います。
GitHub 管理下のプロジェクトで先ほど作成した Gemfile
と get_ratio_of_users.rb
と自動生成された Gemfile.lock
を .ci/bigquery
ディレクトリ内に置きます。
私はファイルをまとめるためにここに置きましたが、好きなところに置いてください。ただしその場合、次の yml ファイルに記載してあるファイルパスを変更する必要があります。
そして以下の yml ファイルを .github/workflows
内に作成します。
# アプリバージョンごとのユーザー比率を取得し、Slackへ通知するためのワークフロー
name: Get ratio of users by app version
on:
workflow_dispatch:
schedule:
- cron: '30 0 * * *'
jobs:
get-ratio-of-users:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-ruby@v1
with:
ruby-version: '2.7'
- name: Install bundler
run: |
GEM_BUNDLER_VERSION=$(grep -A1 -E -i -w '(BUNDLED WITH){1,1}' .ci/bigquery/Gemfile.lock | grep -E -i -w "[0-9\.]{1,}" | xargs)
gem install bundler -v=$GEM_BUNDLER_VERSION --force
# 推奨されている方法ではないので注意
# https://docs.github.com/ja/actions/reference/encrypted-secrets#about-encrypted-secrets
- name: Create service account file
run: echo ${{ secrets.BIGQUERY_SERVICE_ACCOUNT_JSON_BASE64 }} | base64 -d > service-account.json
- name: Run ruby script
env:
GOOGLE_APPLICATION_CREDENTIALS: './service-account.json'
run: |
bundle install --gemfile=.ci/bigquery/Gemfile
echo 'SLACK_MESSAGE<<EOF' >> $GITHUB_ENV
ruby .ci/bigquery/get_ratio_of_users.rb >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Notify to slack
if: ${{ success() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXX
SLACK_COLOR: '#58A359'
SLACK_CHANNEL: XXXXXX
SLACK_ICON: XXXXXXXXXXXXXXXXXXXXXX
SLACK_TITLE: アプリバージョンごとのユーザー比率
SLACK_USERNAME: XXXXXXX
実行タイミングについて
上記の schedule:
の設定により、毎日午前9時30分に実行されます。
参考: https://docs.github.com/ja/actions/reference/events-that-trigger-workflows#scheduled-events
設定する時間は UTC なので、日本時間で午前9時30分に設定する場合はその9時間前の午前0時30分にする必要があります。
また workflow_dispatch:
の設定により、手動でも実行できるようにしています。
GitHub Actions の Secrets の設定について
BigQuery の実行のために認証が必要なので、そのための設定を行う必要があります。
私が行った方法は GitHub Actions の公式ドキュメントでは非推奨なので、設定する場合は自己責任でお願いします。
- 前述の認証に必要な JSON ファイルの内容を Base64 エンコードする
- Mac であれば
$ cat XXX.json | base64 | pbcopy
でエンコードした内容をクリップボードにコピーできます
- Mac であれば
- GitHub のプロジェクトページを開き、
Settings
>Secrets
でNew repository secrets
ボタンを押し、Name
にBIGQUERY_SERVICE_ACCOUNT_JSON_BASE64
、Value
にはクリップボードにコピーされた値を貼り付けてAdd secret
ボタンを押す
これで設定は完了です。
上記の yml ファイルではスクリプト実行前にこの Secret の内容を Base64 デコードし、その内容を JSON ファイルとして書き出しています。
スクリプトの実行
上記の yml ファイルの Run ruby script
の部分で作成した Ruby スクリプトを実行しています。
env
の部分で GOOGLE_APPLICATION_CREDENTIALS
という名前で JSON ファイルのパスを環境変数として設定しています。
スクリプトの実行の結果で出力された文字列は Slack に通知するために SLACK_MESSAGE
という名前の環境変数に保存するようにしておきます。(後述)
Slack への通知
最後に Slack へ通知しますが、GitHub Actions のマーケットプレイスにある Slack Notify を使用しました。
yml ファイルを見てわかるかと思いますが、色々と環境変数の設定が必要になります。
先ほど環境変数で設定した SLACK_MESSAGE
は Slack 通知が行われる際のメッセージの設定になります。
以上で設定は全て完了になります。
最後に
今までは Firebase Analytics の管理画面をからアプリバージョンごとのユーザー比率を見ていたのですが、この仕組みを導入したことによってその手間がなくなりました。
どなたかの参考になれば幸いです。
参考
- サービスアカウントの認証について
- BigQuery にエクスポートされる Firebase アナリティクスのデータについて
- Ruby での BigQuery のサンプル
- Slack Notify (GitHub Actions で Slack 通知を行うためのライブラリ)