HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた②-2〜Lambdaプログラム開発〜
HUGOの記事をPV順で表示できるようにしてみました。その時の手順を解説します。
前回の記事の続きです。
HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた①〜Google Analytics APIの利用設定〜
HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた②-1〜Lambda開発環境の準備〜
前回はLambdaのローカル開発環境について説明しました。 今回は実際にPythonプログラムを作成してローカル環境で実行・デプロイまでの手順を説明します。
- Google Analytics APIの利用設定
- Lambda + API GatewayでGoogleアナリティクスの情報を取得するAPI作成
- HUGOでAPIを実行するパーツ作成
Google Analytics APIを呼び出すPythonコード
実際のプログラムを例に解説します。
今回作成したファイルは2つでGoogle Analytics APIを実行するGoogleAnalytics.py
とそれを呼び出すapp.py
です。
- app.py
import json
import GoogleAnalytics
def lambda_handler(event, context):
analytics = GoogleAnalytics.initialize_analyticsreporting()
response = GoogleAnalytics.get_report(analytics)
res_format = response['reports'][0]['data']['rows']
return {
"statusCode": 200,
"body": json.dumps(res_format),
}
- GoogleAnalytics.py
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
# APIの接続情報は環境に合わせて変更してください
KEY_FILE_LOCATION = 'secret.json'
VIEW_ID = 'XXXXXXXXX'
# 取得するメトリクスやディメンションの情報を設定
m_list = ['pageviews']
d_list = ['pagePath', 'pageTitle']
METRICS = [{'expression': 'ga:' + m} for m in m_list]
DIMENSIONS = [{'name': 'ga:' + d} for d in d_list]
START_DATE = '3daysAgo'
END_DATE = 'today'
SORT_FIELD = 'ga:pageviews'
SORT_ORDER = "DESCENDING"
PAGE_SIZE = 10
# フィルタ条件を設定
f_list = ['/post/', '/2ch/', '/layout/']
FILTER_OPERATOR = 'OR'
FILTERS = [{"dimensionName": "ga:pagePath", "operator": "PARTIAL", "expressions": "" + f} for f in f_list]
def initialize_analyticsreporting():
"""Initializes an Analytics Reporting API V4 service object.
Returns:
An authorized Analytics Reporting API V4 service object.
"""
credentials = ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILE_LOCATION, SCOPES)
# Build the service object.
# エラー回避のため"cache_discovery=False"を追加
analytics = build('analyticsreporting', 'v4', credentials=credentials, cache_discovery=False)
return analytics
def get_report(analytics):
"""Queries the Analytics Reporting API V4.
Args:
analytics: An authorized Analytics Reporting API V4 service object.
Returns:
The Analytics Reporting API V4 response.
"""
return analytics.reports().batchGet(
body={
'reportRequests': [
{
'viewId': VIEW_ID,
'dateRanges': [{'startDate': START_DATE, 'endDate': END_DATE}],
'metrics': METRICS,
'dimensions': DIMENSIONS,
'orderBys': [{'fieldName': SORT_FIELD, "sortOrder": SORT_ORDER}],
'pageSize': PAGE_SIZE,
'dimensionFilterClauses': [{"operator": FILTER_OPERATOR, "filters": FILTERS}]
}]
}
).execute()
基本的には以下のGoogle公式サイトにあるコードをそのまま使っています。
はじめてのアナリティクス Reporting API v4: サービス アカウント向け Python クイックスタート
簡単に説明しますとinitialize_analyticsreporting
で対象のGoogle Analyticsに接続してget_report
に接続情報を渡しています。
そしてreports.batchGet
メソッドで取得するデータの情報を定義することでレポート結果がオブジェクトで返却されます。
今回はページビューをメトリクスに指定して、ディメンションにページのパスとタイトルを指定しています。
またトップページなどの記事以外ページは除外したいためdimensionFilterClauses
で記事ページのみ表示するようにファイルを設定しています。
reports.batchGet
メソッドの詳細は以下のドキュメントに載っているため環境に合わせて変更してみてください。
なおKEY_FILE_LOCATION
はGoogle Analytics APIの利用設定でダウンロードしたサービスアカウントのキーを指定してください。
実行プログラムと同じ場所に配置する場合はパスの指定は必要ないです。
またVIEW_ID
はGoogle Analyticsの管理画面から確認できます。
【注意事項】
そのうち改善されるかもしれませんがLambdaのビルド時に以下のようなエラーが発生する可能性があります。
Runtime.ImportModuleError: Unable to import module 'app': No module named 'apiclient'
改善方法として以下のbuildメソッドの引数にcache_discovery=False
を追加してみてください。
analytics = build('analyticsreporting', 'v4', credentials=credentials, cache_discovery=False)
SAMテンプレートの作成
Google Analytics APIを実行するPythonプログラムは作成したのでそれを実行するための環境を作成する必要があります。
前回の記事で導入したPycharmのプロジェクトファイルにはあらかじめプロジェクト直下にSAMテンプレートtemplate.yaml
が用意されています。
このまま使っても良いのですがLambdaやAPI Gatewayの名前など変更したかったため以下のように書き直しています。
※SAMテンプレートの書き方は別の機会に紹介したいと思います
- template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Lambda and ApiGateway SAM Template for AWS
Globals:
Function:
Timeout: 3
Environment:
Variables:
TZ: Asia/Tokyo
Api:
OpenApiVersion: 3.0.2
Resources:
GetAnalyticsLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: GetAnalyticsLambdaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
GetAnalyticsFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.lambda_handler
Runtime: python3.8
Role: !GetAtt GetAnalyticsLambdaRole.Arn
FunctionName: GetAnalyticsFunction
Events:
GetAnalytics:
Type: Api
Properties:
RestApiId: !Ref GetAnalyticsApi
Path: /apipath
Method: get
GetAnalyticsFunctionPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref GetAnalyticsFunction
Principal: apigateway.amazonaws.com
GetAnalyticsApi:
Type: AWS::Serverless::Api
Properties:
Name: GetAnalyticsApi
StageName: prd
Outputs:
GetAnalyticsApi:
Description: "API Gateway endpoint URL for Prod stage for GetAnalytics function"
Value: !Sub "https://${GetAnalyticsApi}.execute-api.${AWS::Region}.amazonaws.com/prd/apipath/"
GetAnalyticsFunction:
Description: "GetAnalytics Lambda Function ARN"
Value: !GetAtt GetAnalyticsFunction.Arn
GetAnalyticsFunctionIamRole:
Description: "Implicit IAM Role created for GetAnalytics function"
Value: !GetAtt GetAnalyticsLambdaRole.Arn
ローカル実行とデプロイ
作成したプログラムをまずはローカル環境で実行してみましょう。
app.py
のlambda_handler
にアイコンが表示されているはずです。
このアイコンをクリックして実行を選択してください。
ローカル実行環境の構成の編集画面が表示されます。 入力情報をファイルかテキストから選択して実行してください。
今回は用意されている「API Gateway AWS Proxy」を選択しています。
実行時にAWS credentialsのエラーが出たら「AWS Connection」タブをクリックして接続情報を設定してください。
ローカル環境で動作確認ができたらAWS環境にデプロイしましょう。
デプロイはtemplate.yaml
を右クリックして「Deploy Serverless Application」をクリックします。
次にCloudFormationのスタック名とビルドしたファイルを配置するS3バケットを指定します。 スタックを新規に作成する場合は「Create Stack」、S3のバケットがない場合は「作成」をクリックして新しく作成しましょう。
配置をクリックするとデプロイがはじまります。
処理が完了するまでしばらく待機します。
以上でデプロイは完了です。 AWSコンソールからCloudFormationやLambdaの管理画面を開きリソースが作成されていることを確認してみてください。
最後に
これでようやくGoogle Analyticsの情報を取得する環境が整いました!
次回は作成したAPIをHUGOビルド時に実行して静的ファイルを出力する方法を紹介します!
Share this post
Twitter
Facebook
Email