Plausible Analytics を使って人気エントリーのランキングを生成する
Posted on
このブログのトラッキングには Plausible Analytics を使っています。オープンソースでシンプル、軽量、プライバシーに配慮し、Google Analytics の代替を謳うツールです。 Plausible Analytics には API も用意されており、JSON 形式でデータを取り出すことができます。
このデータを使って人気エントリーのランキングを出すようにしてみました(このページの下に表示されています)。
Plausible Analytics からデータを取得する
過去 30 日の中で訪問者数の多い順でトップ 5 のページを取得します。 GET リクエストを送るだけの簡単なシェルスクリプトを書きます。
#!/bin/bash
set -eu
base_dir=$(cd "$(dirname $0)/.."; pwd)
env_file="${base_dir}/.env"
if [ -f "${env_file}" ]; then
. "${env_file}"
fi
res=$(curl -sS -H "Authorization: Bearer ${PLAUSIBLE_TOKEN}" \
"https://plausible.io/api/v1/stats/breakdown?site_id=${PLAUSIBLE_SITE_ID}&property=event:page&limit=5")
echo "${res}" | jq -r ".results"
このスクリプトを実行すると次のような JSON が取得できます(数字はダミー)。
[
{
"page": "/2023/03/replace-onu-of-nuro/",
"visitors": 999
},
{
"page": "/2023/06/config-driven-import-via-terraform-1-5/",
"visitors": 888
},
{
"page": "/2020/03/elasticache-for-redis-with-terraform/",
"visitors": 777
},
{
"page": "/2012/05/jquery-ajax-status-code/",
"visitors": 666
},
{
"page": "/2021/08/review-the-kms-key-policy/",
"visitors": 555
}
]
Jekyll の Data Files で JSON を読み込む
Jekyll には _data
ディレクトリにある YAML や JSON を自動的にロードする Data Files という機能があります。先ほどの JSON ファイルを _data/popular.json
に置くと site.data.popular
でアクセスすることができます。
あとはテンプレート側で出力するだけですが、Plausible Analytics の JSON にはタイトルが含まれていないのでひと工夫が必要です。全エントリーの情報は site.posts
に入っているので、JSON の page
の値をもとに site.posts
から URL が一致するオブジェクトを取り出しています。
具体的には次のようなテンプレートを書いています。
<section>
<h2>Popular Entries</h2>
<ul>
{%- assign popular_pages = site.data.popular | map: 'page' %}
{%- for page in popular_pages %}
{%- assign post = site.posts | find_exp: 'post', 'post.url contains page' %}
<li>
<a href="{{ post.url | replace: 'index.html', '' }}">{{ post.title }}</a>
<time datetime="{{ post.date | date: '%Y-%m-%d %H:%M' }}">{{ post.date | date: '%Y-%m-%d' }}</time>
</li>
{%- endfor %}
</ul>
</section>
ブログ更新時に人気エントリーのランキングを自動更新する
このブログの更新頻度は月に数回なので、人気エントリーのランキングもそんなに入れ替わりません。そのためブログを更新するときにランキングも更新すれば十分です。
ブログの更新は GitHub Actions でビルドして S3 にアップロードしているだけなので、ビルドの前に先ほどのスクリプトを実行して _data/popular.json
を上書きします。
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Get Popular Entries
run: ./scripts/get-popular-entries.sh | tee ./_data/popular.json
env:
PLAUSIBLE_TOKEN: ${{ secrets.PLAUSIBLE_TOKEN }}
PLAUSIBLE_SITE_ID: ${{ vars.PLAUSIBLE_SITE_ID }}
continue-on-error: true
- name: Build
run: bundle exec jekyll build
env:
JEKYLL_ENV: production
# このあとに S3 にアップロードする step が続く
Plausible Analytics に依存してブログの更新ができないのは避けたいので、失敗してもジョブを進めるために continue-on-error: true
を指定しています。 API リクエストに失敗したとしても、コミットしてある JSON が使われて古いランキングが表示されるだけです。
もともとは「Hugo で人気記事ランキング機能を AWS のノーコードなサービスで作ったで」のような仕組みを考えていましたが、既存のパイプラインの延長でシンプルに実装できました。