こんにちは、松田です。
今日は日頃より多くご質問いただいている「microCMSを使って人気記事をどう実現するか」についてご説明していきます。
前提条件
今回のご説明の中では以下のような条件があるものとします。
- コンテンツの管理をmicroCMSで行っている
- アクセス解析をGoogle Analyticsで行っている
- 人気記事の集計はGoogle AnalyticsのReporting API (v4)を使って行う
- 集計結果を使ってmicroCMSで管理された「人気記事」コンテンツを編集する(PUT APIもしくはPATCH APIを利用する)
これを図にすると以下のような流れです。
この際のmicroCMSのスキーマとしては以下のような設定を想定しています。
※microCMSブログはオープンソース化されていますが、ほぼ下記と同じ構成です。ご参照ください。
記事(リスト形式)
・タイトル(テキストフィールド)
・本文(リッチテキスト) など
人気記事(オブジェクト形式)
・記事(複数コンテンツ参照)
ここで一点、よくご質問いただくのが「microCMSのAPIの利用回数などによる人気記事の算出はできないか」といったことです。
結論から述べるとこれはおすすめできません。
これはmicroCMSがご提供しているのはあくまでAPIであるため、特にページビュー数を数えるのは不向きなためです。
例えばSSG(Static Site Generation)であればAPIをコールするのはビルド時のみとなりますし、SSR(Server Side Rendering)ではサイト側のキャッシュによってAPIまでリクエストが到達しないことが理由としてあげられます。
また、自社DBなどに人気記事情報を格納しておくような場合にはmicroCMS側に「人気記事」APIを必ずしも用意する必要はありません。
一方でmicroCMSにAPIを用意しておくことのメリットは日次や週次で自動で修正されていく内容でありつつも必要に応じて手動で編集したいといった要件を実現できることとなりますので、このあたりは案件内容に応じてご判断いただければ幸いです。
集計を実装していく
それではGoogle Analyticsへアクセスして集計処理を行っていきましょう。
今回はReporting API v4とNode.jsのクライアントライブラリを使って集計を進めていきます。
Google Analytics側(GCP)の準備はクラスメソッド様の以下の記事に詳しく記載されておりました。
こちらを参照しつつ鍵ファイルのダウンロードやGoogle Analyticsでの権限付与を行ってください。
アナリティクス Reporting API v4を使ってGoogle Analyticsのデータを取得する
準備が整ったら集計処理を実装していきます。
まずはプロジェクトの準備です。
$ mkdir get-populars
$ cd get-populars
$ mv <YOUR_DOWNLOADS>/<YOUR_KEY_FILENAME>.json keys.json //ダウンロードした鍵ファイルをディレクトリ内に配置
$ npm install googleapis // https://github.com/googleapis/google-api-nodejs-client
$ touch getPopulars.js
getPopulars.js
の中身は以下のような実装としましょう。
ここでは前日までの1週間(8daysago
〜1daysago
)でのページビューが多かった順に最大30件を取得しています。
const { google } = require("googleapis");
(async () => {
//取得準備
const client = await google.auth.getClient({
keyFile: "./keys.json",
scopes: "https://www.googleapis.com/auth/analytics.readonly",
});
const reporting = await google.analyticsreporting({
version: "v4",
auth: client,
});
//ランキング取得
const response = await reporting.reports.batchGet({
requestBody: {
reportRequests: [
{
viewId: "201161107",
dateRanges: [{ startDate: "8daysAgo", endDate: "1daysAgo" }],
metrics: [{ expression: "ga:pageviews" }],
dimensions: [{ name: "ga:pagePath" }],
orderBys: [{ fieldName: "ga:pageviews", sortOrder: "DESCENDING" }],
pageSize: 30,
},
],
},
});
console.log(JSON.stringify(response.data, null, 2));
})();
microCMSにデータを書き込む
上記スクリプトでアクセスの多かったページが取得できたのでこのデータをmicroCMSに書き込んでいきます。
前提として、今回の記事はページ表示の際には1番目のパスにコンテンツID(スラッグ)が入るものとします。
(Nuxt / Next / Gatsby の実装サンプルでもコンテンツIDをパスに使用していますので必要に応じてご確認ください)
こうした場合、例えば以下のようにコンテンツIDを抽出し、microCMSに書き込みを行います。
今回はPATCHでの書き込みを行います。書き込みAPIの詳細な利用方法はこちらの記事をご確認ください。
const fetch = require("node-fetch"); // npm i node-fetch
//コンテンツID一覧を抽出
const rankedPaths = response.data.reports[0].data.rows.map(
(row) => row.dimensions[0]
);
const maybeContentIds = rankedPaths
.map((path) => path.split("/")[1])
.filter((v) => v);
//microCMSへのPATCH
const result = await fetch(
"https://<YOUR_SERVICE>.microcms.io/api/v1/popular-bs",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-MICROCMS-API-KEY": "<YOUR_API_KEY>",
},
body: JSON.stringify({ articles: maybeContentIds }),
}
);
console.log(await result.json());
ここまでの実装でGoogle Anlyticsからのランキング取得→microCMSへのデータ反映ができました。
あとはこのスクリプトをcronなどで日次・週次等で動作させれば人気記事は実現可能です。
今回のご説明は以上となります。
実案件でもお使いいただいている方法ですので、ご参考になりましたら幸いです!
Appendix:コード全体
const { google } = require("googleapis");
const fetch = require("node-fetch");
(async () => {
//取得準備
const client = await google.auth.getClient({
keyFile: "./keys.json",
scopes: "https://www.googleapis.com/auth/analytics.readonly",
});
const reporting = await google.analyticsreporting({
version: "v4",
auth: client,
});
//ランキング取得
const response = await reporting.reports.batchGet({
requestBody: {
reportRequests: [
{
viewId: "201161107",
dateRanges: [{ startDate: "8daysAgo", endDate: "1daysAgo" }],
metrics: [{ expression: "ga:pageviews" }],
dimensions: [{ name: "ga:pagePath" }],
orderBys: [{ fieldName: "ga:pageviews", sortOrder: "DESCENDING" }],
pageSize: 30,
},
],
},
});
console.log(JSON.stringify(response.data, null, 2));
//コンテンツID一覧を抽出
const rankedPaths = response.data.reports[0].data.rows.map(
(row) => row.dimensions[0]
);
const maybeContentIds = rankedPaths
.map((path) => path.split("/")[1])
.filter((v) => v);
//microCMSへのPATCH
const result = await fetch(
"https://<YOUR_SERVICE>.microcms.io/api/v1/popular-bs",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-MICROCMS-API-KEY": "<YOUR_API_KEY>",
},
body: JSON.stringify({ articles: maybeContentIds }),
}
);
console.log(await result.json());
})();
-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、お問い合わせからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!