【Node.js/Google Analytics 4(GA4)/Contentful】Google Analytics Data APIを使って人気記事を取得する

Aug 12, 2021

はじめに

新バージョンGoogle Analytics 4(GA4)からGoogle Analytics Data APIを使ってページビュー数を取得、そこからContentfulの記事情報を取得して人気記事一覧を表示します。 この記事ではNode.jsクライアントを利用しての実装方法を紹介します。
よくgoogleapisというライブラリを使ってレポートデータを取得してたと思いますが、今回はまだベータの@google-analytics/dataを使ってみます。

この記事はすでにGoogle Analyticsのプロジェクトがある前提で話を進めます。

Google Analytics側

最初はGoogle Analytics側の設定から行います。

1. Google Cloud Platformのプロジェクトを作成する

Google Analyticsへプログラムからアクセスするためにはサービスアカウントを作成する必要があります。
まずはGoogle Cloud Platform(GCP)のプロジェクトを作成します。
すでにプロジェクトを作成済みの方は次に進んでください。

GCPでプロジェクトの選択画面

プロジェクト選択画面を開いて、「新しいプロジェクト」をクリック。

GCPでプロジェクトの作成画面

必要項目を入力して「作成」をクリック。

2. Google Analytics Data APIを有効にする

次に作成したプロジェクトで利用するAPIを有効にします。
今回はGoogle Analytics Data APIを利用してGoogle Analyticsのデータを取得するのでこのAPIを有効化します。
Google Cloud PlatformのGoogle Analytics Data APIを有効化するページへアクセスして有効化します。

Google Analytics Data APIの有効化画面

「有効にする」をクリック。

3. サービスアカウントを作成する

次にサービスアカウントを作成します。

GCPでメニューからサービスアカウントを選択

メニューから「IAMと管理」→「サービスアカウント」を選択。

GCPでサービスアカウント画面

「サービスアカウントを作成」をクリック。

GCPでサービスアカウント作成画面

必要項目を入力して「完了」をクリック。
作成画面の②、③は省略しました。

GCPでサービスアカウント作成後画面

作成後はこのサービスアカウントをGoogle Analyticsへ登録するのでメールアドレスをメモしておきます。

4. サービスアカウントのキーを発行する

作成したサービスアカウントを使ってプログラムからアクセスするためには、サービスアカウントキーが必要になります。

GCPでサービスアカウントキー画面

サービスアカウント画面から作成したサービスアカウントのメールをクリックしてサービスアカウントの詳細画面へ遷移。
「キー」というタブをクリックして、「鍵を追加」→「新しい鍵を作成」をクリック。
するとxxxx.jsonというファイルがダウンロードされます。
盗まれると不正利用される可能性があるので大事に保管しておきましょう。

5. Google Analyticsにサービスアカウントを追加する

ここでやっとGoogle Analyticsのダッシュボードを開きます。

GAで管理メニュー

左下の歯車アイコンをクリックして、「プロパティのアクセス管理」を選択。

GAでプロパティの権限画面

プロパティの権限画面でプラスアイコンボタンをクリック。

GAで権限の追加画面

権限の追加画面が表示されるので、サービスアカウントのメールを入力します。
その際に「新規ユーザーにメールで通知する」ボタンのチェックを外します。
権限は今回レポートデータを読み取るだけなので「表示と分析」のみにチェックでOKです。
全て入力したら「追加」をクリック。

6. プロパティIDをメモ確認する

APIを呼び出すにはプロパティIDも必要になるので確認しておきます。

GAでプロパティID確認画面

プロパティIDは管理メニューの「プロパティ設定」からコピーできるのでこれをメモしておいてください。

Node.js側

Google Analytics側の設定が終わったら、あとはコードを書いていきます。

1. クレデンシャルを設定する

先ほどダウンロードしたサービスアカウントキーをクレデンシャルとしてアプリケーションに設定します。

パターン1 環境変数を設定する

やり方はいろいろありますが、一番簡単なのが以下のようにGOOGLE_APPLICATION_CREDENTIALSの環境変数にダウンロードしたjsonファイルパスを設定することです。

$ export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/credentials.json"

するとコード内で

const {BetaAnalyticsDataClient} = require('@google-analytics/data');

const analyticsDataClient = new BetaAnalyticsDataClient();

BetaAnalyticsDataClientをインスタンス化して使えるようになります。

パターン2 コード内で直接ファイルを呼び出す

環境変数に設定するのが嫌な方は直接読み込むことで実現できます。

const {BetaAnalyticsDataClient} = require('@google-analytics/data');

const analyticsDataClient = new BetaAnalyticsDataClient({
  credentials: require("credentials.json"),
});

とソースコード内でjsonファイルを読み込みます。
この場合うっかりファイルを公開しないよう気をつけましょう。

パターン3 client_emailとprivate_keyの値を環境変数として設定する

ドキュメントを確認すると、BetaAnalyticsDataClientのcredentialsオプションにはclient_emailとprivate_keyの値だけを渡せば良いみたいです。

そのため、環境変数GOOGLE_APPLICATION_CLIENT_EMAILGOOGLE_APPLICATION_PRIVATE_KEYを用意してjsonファイルに書かれてある情報をそれぞれ設定します。
すると以下のように書けます。

const { BetaAnalyticsDataClient } = require("@google-analytics/data");

const analyticsDataClient = new BetaAnalyticsDataClient({
  credentials: {
    client_email: process.env.GOOGLE_APPLICATION_CLIENT_EMAIL,
    private_key: process.env.GOOGLE_APPLICATION_PRIVATE_KEY,
  },
});

こうすることでCircleCI、Github ActionなどのCI/CDでの利用がしやすくなります。
私はNext.jsの静的サイト生成(SSG)をNetlifyまたはVercelでビルド、ホスティングを利用していますのでこの方法を採用しています。

2. @google-analytics/dataをインストール

クレデンシャルの設定が終わったら、あとはGoogle Analyticsのクライアントライブラリを使ってAPIを呼び出すだけです。
まずは@google-analytics/dataをインストールします。

$ npm install @google-analytics/data

3. APIを呼んでページビュー数を取得する

ページビュー数はrunReport()関数を使って取得できます。

const { BetaAnalyticsDataClient } = require("@google-analytics/data");

const propertyId = "Google AnalyticsのプロパティID";
const analyticsDataClient = new BetaAnalyticsDataClient({
  credentials: {
    client_email: process.env.GOOGLE_APPLICATION_CLIENT_EMAIL,
    private_key: process.env.GOOGLE_APPLICATION_PRIVATE_KEY,
  },
});

export async function fetchPopularPosts() {
  const [response] = await analyticsDataClient.runReport({
    property: `properties/${propertyId}`,
    dateRanges: [
      {
        startDate: "30daysAgo",
        endDate: "today",
      },
    ],
    dimensions: [
      {
        name: "pagePath",
      },
    ],
    metrics: [
      {
        name: "screenPageViews",
      },
    ],
    limit: 5,
  });
  response.rows.forEach(row => {
    console.log(row.dimensionValues[0], row.metricValues[0]);
  });
}

4. Contentfulから記事情報を取得する

私はヘッドレスCMSのContentfulを使って記事を書いているので、取得したGoogle Analyticsのデータを元に、記事情報をContentfulから取得します。
詳しくはContentful Delivery APIのドキュメントを確認してください。

const client = require("contentful").createClient({
  space: process.env.NEXT_CONTENTFUL_SPACE_ID,
  accessToken: process.env.NEXT_CONTENTFUL_ACCESS_TOKEN,
});

const { BetaAnalyticsDataClient } = require("@google-analytics/data");

const propertyId = "Google AnalyticsのプロパティID";
const analyticsDataClient = new BetaAnalyticsDataClient({
  credentials: {
    client_email: process.env.GOOGLE_APPLICATION_CLIENT_EMAIL,
    private_key: process.env.GOOGLE_APPLICATION_PRIVATE_KEY,
  },
});

export async function fetchPopularPosts({ preview = false } = {}) {
  const [response] = await analyticsDataClient.runReport({
    property: `properties/${propertyId}`,
    dateRanges: [
      {
        startDate: "30daysAgo",
        endDate: "today",
      },
    ],
    dimensions: [
      {
        name: "pagePath",
      },
    ],
    metrics: [
      {
        name: "screenPageViews",
      },
    ],
    limit: 5,
  });
  // 記事のパスは"/post/my-post"のようになっているためslug部分を抽出
  const slugs = response.rows
    .map((row) => row.dimensionValues[0].value.split("/")[2])
    .filter((v) => v);

  // Contentfulでpostのslugフィールドにマッチする記事データを全て取得
  const entries = await client.getEntries({
    content_type: "post",
    "fields.slug[in]": slugs.join(","),
  });

  if (entries.items) return entries.items;
  console.log(`Error getting Entries.`);
}

これでGoogle Analyticsから人気記事データ取得、Contentfulから記事内容データ取得までの流れができました。
あとは好きな形で表示するだけになります。
先ほども書きましたが、私はNext.jsのSSGでブログ記事をビルド生成しているので、これをGithub Actionなどで定期的に実行すれば良いだけになります。

おわりに

いかがでしたか?なるべく画像を使ってわかりやすく説明したつもりです。

Google Analyticsからアクセス数を取得する実装方法は多く見つかるのですが、GA4でしかもGoogle Analytics Data APIを使っての方法が見つからなかったので書きました。
ほとんどがGoogle Analytics Reporting APIやgoogleapisを使った方法ばかりで、この方法では「ビューID」が必要になりGA4ではビューIDは存在しないので実現できないのです。 (実際にはプロパティ作成時に「ユニバーサルアナリティクスプロパティの作成」をオンにするとビューIDが取得できますが、作成時に設定し忘れると取得できません)。

自分のサイトに人気記事を表示させたい方の助けになれば幸いです。

参考