HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた②-2〜Lambdaプログラム開発〜

HUGOの記事をPV順で表示できるようにしてみました。その時の手順を解説します。

Ishiguro Suguru

前回の記事の続きです。

HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた①〜Google Analytics APIの利用設定〜

HUGO + Lambda + Google Analytics APIを使ってPV順で記事を表示してみた②-1〜Lambda開発環境の準備〜

前回はLambdaのローカル開発環境について説明しました。 今回は実際にPythonプログラムを作成してローカル環境で実行・デプロイまでの手順を説明します。

  1. Google Analytics APIの利用設定
  2. Lambda + API GatewayでGoogleアナリティクスの情報を取得するAPI作成
  3. 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メソッドの詳細は以下のドキュメントに載っているため環境に合わせて変更してみてください。

メソッド: 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.pylambda_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ビルド時に実行して静的ファイルを出力する方法を紹介します!

comments powered by Disqus