1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Google AnalyticsのレポートをLambda&Pythonで取得しSlackに投稿する

Last updated at Posted at 2022-12-06

まえがき

やること

Google Analyticsで集計したデータ(ここでは1昨日の投稿ごとのページビュー)をPythonで取得してレポートを作成し、Slackに投稿してみたいと思います。
PythonはLambdaで動かします。

書くきっかけ

毎日、Google Analyticsで投稿ごとのページビューを確認しています。
スマホアプリで開いて確認したり、WEBで確認したりしています。
これをプログラムで行うことができないかと考え始め、Google Analytics Data APIというものがあることを知り、挑戦してみることにしました。

構成図

今回作成するものを構成図にすると、以下のようになると思います。
image.png

作業環境

作業環境にはAmazon Linux 2のEC2インスタンスを使用します。バージョンなどは以下のようになっています。また、Google AnalyticsはGA4を使用しています。

$ cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
$ cat /etc/image-id 
image_name="amzn2-ami-kernel-5.10-hvm"
image_version="2"
image_arch="x86_64"
image_file="amzn2-ami-kernel-5.10-hvm-2.0.20221103.3-x86_64.xfs.gpt"
image_stamp="b928-dd59"
image_date="20221112010958"
recipe_name="amzn2 ami"
recipe_id="5711a1a3-4075-cb3e-5910-2700-f037-ba87-de68b995"
$ python3 --version
Python 3.7.10
$ pip3 --version
pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)

Google Analyticsの利用開始はされており、サイト(ブログやQiita)にGoogleタグを追加してイベントデータを収集は開始されている前提とします。

手順

Google Analytics Data APIを有効化する

こちらは手元の作業PCで行います。
API Quickstartにアクセスして、[Enable the Google Analytics Data API v1]のボタンをクリックします。
image.png
プロジェクトの名前を適当に入力して(ここでは"Quickstart")、[NEXT]をクリックします。
image.png
[DOWNLOAD PRIVATE KEY AS JSON]のボタンをクリックして、Google認証情報が書かれたJSONファイルをダウンロードします。
このファイルは後ほどEC2にアップロードします。
image.png

Google AnalyticsへAPI用のユーザーを追加する

先ほどダウンロードしたJSONファイルに記載されたユーザー名で、Google Analyticsに新規ユーザーを追加します。
Google Analyticsにアクセスして、[管理]の歯車をクリックします。
image.png
[アカウントのアクセス管理]をクリックします。
image.png
右上の+ボタンから[ユーザーを追加]をクリックします。
image.png
メールアドレスを入力する欄に、先ほどダウンロードしたJSONファイルの中の、"client_email"のメールアドレスをコピペします。役割は「アナリスト」を選択して、[追加]ボタンをクリックします。
image.png

EC2にJSONファイルをアップロード

Google認証情報が記載されたJSONファイルをEC2にアップロードします。
ここではFileZillaを使用してec2-userのホームディレクトリにアップロードしました。
image.png

SlackのWebhookのURL作成

Slackでチャンネルを作成し、WebhookのURLを取得します。
Slack での Incoming Webhook の利用

パッケージダウンロード

ここからEC2インスタンスでの作業です。
Lambdaレイヤー作成のため、必要なパッケージをpipで集めます。

### Python仮想環境作成
$ python3 -m venv .venv
### Python仮想環境起動
$ source .venv/bin/activate
### pythonディレクトリ作成(Lambdaレイヤー作成のためのもの)
(.venv)$ mkdir python
### google-analytics-dataパッケージをpythonディレクトリにダウンロード
(.venv)$ pip3 install google-analytics-data -t python
Collecting google-analytics-data
  Using cached google_analytics_data-0.14.2-py2.py3-none-any.whl (108 kB)
(中略)
Collecting pyasn1>=0.1.3
  Using cached pyasn1-0.4.8-py2.py3-none-any.whl (77 kB)
Installing collected packages: protobuf, proto-plus, cachetools, pyasn1, rsa, pyasn1-modules, six, google-auth, googleapis-common-protos, urllib3, charset-normalizer, idna, certifi, requests, grpcio, grpcio-status, google-api-core, google-analytics-data
Successfully installed cachetools-5.2.0 certifi-2022.9.24 charset-normalizer-2.1.1 google-analytics-data-0.14.2 google-api-core-2.11.0 google-auth-2.15.0 googleapis-common-protos-1.57.0 grpcio-1.51.1 grpcio-status-1.51.1 idna-3.4 proto-plus-1.22.1 protobuf-4.21.10 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-2.28.1 rsa-4.9 six-1.16.0 urllib3-1.26.13
WARNING: Target directory /home/ec2-user/python/google already exists. Specify --upgrade to force replacement.
### slackwebパッケージをpythonディレクトリにダウンロード
(.venv)$ pip3 install slackweb -t python 
Collecting slackweb
  Downloading slackweb-1.0.5.tar.gz (1.3 kB)
Using legacy setup.py install for slackweb, since package 'wheel' is not installed.
Installing collected packages: slackweb
    Running setup.py install for slackweb ... done
Successfully installed slackweb-1.0.5

これで十分だと思ったのですが、実際にLambdaで動かしてみるとprotobufパッケージが無いとのエラーが出ました。
pip3 install protobuf -t pythonではダウンロードできず、pip3 install protobuf -t python --upgradeではgoogleフォルダが上書きされてしまうので、別ディレクトリにprotobufをダウンロードしてコピーしました。

### tmpディレクトリ作成
(.venv)$ mkdir tmp
### protobufパッケージをtmpディレクトリにダウンロード
(.venv)$ pip3 install protobuf -t tmp
Collecting protobuf
  Using cached protobuf-4.21.10-cp37-abi3-manylinux2014_x86_64.whl (408 kB)
Installing collected packages: protobuf
Successfully installed protobuf-4.21.10
### tmpディレクトリの中身をpythonディレクトリにコピー
(.venv)$ cp -rp tmp/* python/
### zipに固める
(.venv)$ zip -r layer.zip python
  adding: python/ (stored 0%)
  adding: python/idna/ (stored 0%)
  adding: python/idna/__init__.py (deflated 67%)
(中略)
  adding: python/slackweb-1.0.5-py3.7.egg-info/SOURCES.txt (deflated 46%)
  adding: python/slackweb-1.0.5-py3.7.egg-info/top_level.txt (stored 0%)
  adding: python/slackweb-1.0.5-py3.7.egg-info/installed-files.txt (deflated 44%)

Lambdaレイヤー作成

zipに固めたパッケージでLambdaレイヤーを作成します。

### AWS認証情報作成
(.venv)$ aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: ****************************************
Default region name [None]: us-east-1
Default output format [None]: 
## AWS認証情報設定
(.venv)$ export AWS_PROFILE=default
### Lambdaレイヤー作成
(.venv)$ aws lambda publish-layer-version \
    --layer-name analytics-data-slackweb \
    --zip-file fileb://layer.zip \
    --compatible-runtimes python3.7

Lambdaにアタッチするロールを作成します。

### Lambdaにアタッチするロール作成
(.venv)$ aws iam create-role \
    --role-name lambda-ex \
    --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'
### ロールにポリシーをアタッチ
(.venv)$ aws iam attach-role-policy \
    --role-name lambda-ex \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

プログラム作成

Google Analyticsのレポートを作成するプログラムのサンプルが公開されています。
Creating a Reportのサンプルプログラムを少し修正して、EC2のec2-userのホームディレクトリにlambda_function.pyとして保存しました。

from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
    DateRange,
    Dimension,
    Metric,
    MetricType,
    RunReportRequest,
)
import slackweb
from datetime import datetime
from datetime import timedelta

def lambda_handler(event, context):
    """Runs the sample."""
    # TODO(developer): Replace this variable with your Google Analytics 4
    #  property ID before running the sample.
    property_id = "XXXXXXXXX" # ←Google AnalyticsのプロパティIDを記載
    report = run_report(property_id)
    check_day = (datetime.today() - timedelta(days=1)).strftime('%Y-%m-%d')
    start_char = ("#############################" + "\n"
                  "#### {0} ###############".format(check_day) + "\n"
                + "#############################"
                )
    end_char = "#############################"

    slack = slackweb.Slack(url="https://hooks.slack.com/services/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")
    slack.notify(text=start_char)
    slack.notify(text=report)
    slack.notify(text=end_char)

def run_report(property_id="YOUR-GA4-PROPERTY-ID"):
    check_day = ((datetime.today())- timedelta(days=1)).strftime('%Y-%m-%d') # 昨日の日付取得

    """Runs a report of active users grouped by country."""
    client = BetaAnalyticsDataClient()

    request = RunReportRequest(
        property=f"properties/{property_id}",
        dimensions=[Dimension(name="pageTitle")], # ページごとのタイトルを取得する
        metrics=[Metric(name="screenPageViews")], # ページごとのビュー数を取得する
        date_ranges=[DateRange(start_date=str(check_day), end_date=str(check_day))],
    )
    response = client.run_report(request)
    return print_run_report_response(response)


def print_run_report_response(response):
    """Prints results of a runReport call."""
    print(f"{response.row_count} rows received")
    for dimensionHeader in response.dimension_headers:
        print(f"Dimension header name: {dimensionHeader.name}")
    for metricHeader in response.metric_headers:
        metric_type = MetricType(metricHeader.type_).name
        print(f"Metric header name: {metricHeader.name} ({metric_type})")

    print("Report result:")
    report = ""
    for rowIdx, row in enumerate(response.rows):
        if rowIdx < 30:
            for i, dimension_value in enumerate(row.dimension_values):
                dimension_name = response.dimension_headers[i].name
                dimension_result = f"タイトル: {dimension_value.value}".strip(" | Atsushi Notes")
                print(dimension_result)
    
            for i, metric_value in enumerate(row.metric_values):
                metric_name = response.metric_headers[i].name
                metric_result = f"ビュー数: {metric_value.value}"
                print(metric_result)
        else:
            break

        report = report + dimension_result + "\n" + metric_result + "\n" + "\n"

    return report

Google AnalyticsのIDは、プロパティを選択して、[プロパティ設定]から確認できます。
image.png

Lambda関数作成

作成したlambda_function.pyとGoogle認証情報が記載されたJSONファイルをzipに固めます。

(.venv)$ zip CheckGoogleAnalytics.zip lambda_function.py Quickstart-XXXXXXXXXXXX.json 
  adding: lambda_function.py (deflated 60%)
  adding: Quickstart-XXXXXXXXXXXX.json (deflated 31%)

AWS CLIでLambda関数を作成します。

(.venv)$ aws lambda create-function \
    --function-name CheckGoogleAnalytics \
    --zip-file fileb://CheckGoogleAnalytics.zip \
    --handler lambda_function.lambda_handler \
    --runtime python3.7 \
    --role arn:aws:iam::XXXXXXXXXXXX:role/lambda-ex \
    --timeout 900 \
    --layers "arn:aws:lambda:us-east-1:XXXXXXXXXXXX:layer:analytics-data-slackweb:1" \
    --environment Variables='{GOOGLE_APPLICATION_CREDENTIALS="Quickstart-XXXXXXXXXXXX.json", TZ="Asia/Tokyo"}'
  • 関数名は「CheckGoogleAnalytics」としました。
  • 先ほど作成したロールをアタッチします。
  • タイムアウトは最大の15分にしました。
  • 先ほど作成したレイヤーを指定します。
  • 環境変数にキーがGOOGLE_APPLICATION_CREDENTIALSで値がQuickstart-XXXXXXXXXXXX.json (Googleの認証情報が記載されたJSONファイル名)を指定します。
    lambda_function.pyと同じディレクトリにQuickstart-XXXXXXXXXXXX.jsonを保存しているので参照できます。

実行

Lambda関数を実行します。

(.venv)$ aws lambda invoke --function-name CheckGoogleAnalytics out --log-type Tail
{
    "LogResult": "(省略)", 
    "ExecutedVersion": "$LATEST", 
    "StatusCode": 200
}

無事Slackのチャンネルに投稿できました。
image.png

以上です。
最後までお読みいただきありがとうございました。
なにかの参考になれば幸いです。

参考サイト

API Quickstart
Creating a Report
API Dimensions & Metrics
Python ModuleNotFoundError: No module named 'google.analytics'
AWS LambdaでAWS CLIから関数にLayerを追加・削除する方法
AWS CLI での Lambda の使用
【Python】日付 datetimeの足し算・引き算
[解決!Python]日付や時刻をYYMMDDhhmmssなどの形式に書式化するには
Pythonからslackに通知する方法【サンプルコードあり】

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?