いいねカウンタ @piyoppi/counter-tools を作りました
先日の記事 でブログにいいねできるようになった旨お知らせしましたが、このために @piyoppi/counter-tools を作りました。
せっかくつくったので、このアプリケーションについてご紹介します。
(このページは @piyoppi/counter-tools の実装の変更に伴い更新される可能性があります。)
@piyoppi/counter-tools とは?
Webページ(=URL)ごとに「いいね」を受け付けたり、現在の「いいね」の数を取得したりするアプリケーションです。
各ページに「いいね」ボタンを設置したり、カウント値を表示するカスタム要素を設置することができます。
@piyoppi/counter-tools の構成

このアプリケーションは以下の要素で構成されています。
- @piyoppi/counter-api カウント値を素得したり、カウントをインクリメントしたりするAPI
- @piyoppi/counter-button カウント値を表示したり、カウントをインクリメントするボタンを提供するカスタム要素
- actions-upload-url-whitelist-to-s3 sitemap.xmlからURLホワイトリストを生成して登録するGitHub Actions
各種サーバサイドのリソースにAWSが提供するサービスを用いています。
@piyoppi/counter-api は「カウント値の返却」「インクリメント」のエンドポイントを持っており、いずれもURLをリクエストパラメータとして受け付けます。 このURLは「現在表示中のウェブページのURL」が設定されることを期待しています。 このURLがStorage(S3)に配置されたURLホワイトリスト内に存在すれば、データベース内のカウンタをインクリメントします。
actions-upload-url-whitelist-to-s3 にサイトマップを入力することで、URLホワイトリストをGitHub ActionsのWorkflowで生成し、Storage(S3)にアップロードできます。
@piyoppi/counter-button はこれらのエンドポイントを利用してカウント値を表示したり、カウンタをインクリメントするUIを提供します。
アプリケーションの使い方
@piyoppi/counter-tools を予めクローンしておきます。
git clone git@github.com:piyoppi/counter-tools.git
@piyoppi/counter-api のデプロイ
まずは @piyoppi/counter-api をデプロイします。
このアプリケーションは Serverless Framework を用いて構成を管理しています。 serverlessコマンドをインストールします。
npm install -g serverless
また、お使いのAWSアカウントに紐づく各種リソースを作成するために、AWS CLIを使うなどして資格情報をセットアップしておきます
ここまでの準備が完了したら、@piyoppi/counter-tools のリポジトリ内の packages/counter
に移動し、パラメータを適切な値に変更したうえで以下のコマンドを実行します。
cd packages/counter
serverless deploy \
--param='sitemap=https://example.com/sitemap/sitemap-index.xml' \
--param='bucket=counter-settings' \
--param='urllist=urllist' \
--param='origin=http://localhost:3000'
各パラメータは以下のように設定します。
パラメータ | 設定する値 | 例 |
---|---|---|
sitemap | サイトマップのURL | https://example.com/sitemap/index.xml |
bucket | URLホワイトリストを設置するS3バケット名(デプロイとともに作成される) | counter-settings |
urllist | URLホワイトリストのオブジェクト名 | urllist |
origin | 設置対象のページのオリジン | https://example.com |
デプロイが完了したら、URLホワイトリストを更新します。デプロイされたLambda Functionのうち、「updateUrlList」を呼び出します。 このLambda Functionはデプロイ時にsitemapパラメータに設定したサイトマップにアクセスし、設定したS3バケットにURLホワイトリストのオブジェクト(オブジェクト名はデプロイ時に指定したurllistパラメータの値)を配置します。
(この作業は actions-upload-url-whitelist-to-s3 を使って自動化することができます。)
aws lambda invoke --function-name counter-dev-updateUrlList out --log-type Tail --query 'LogResult' --output text | base64 -d
作業が完了したら、以下のようなコマンドでインクリメントできるようになります。urlパラメータに指定するURLは、URLホワイトリストに含まれている必要があります。
curl -X POST \
-H'content-type: application/json' \
-d'{"url": "https://example.com/weblog/"}' \
https://xxxxxxx.execute-api.xxxxx.amazonaws.com/count
@piyoppi/counter-button の配置

@piyoppi/counter-button は3つのコンポーネントを提供します。
<counter-display>
: カウントの表示<counter-increment-button>
: カウントをインクリメントするボタン<counter-container>
: 上記2つのコンポーネントを管理するコンポーネント
import構文で読み込む場合は以下のようにロードします。
import '@piyoppi/counter-button'
スクリプトタグで読み込む場合は、対象のページに以下のように記述します。
<script src="https://cdn.jsdelivr.net/npm/@piyoppi/counter-button@0.1.4/dist/counter-button.umd.js"></script>
以下のようにマークアップを記述します。
<counter-container>
の apiurl属性には、@piyoppi/counter-api のデプロイによって払い出されたAPIのベースURLを設定します。
<counter-display>
や <counter-container>
にはほとんどスタイルが適用されていないので、自分でCSSを用意するなどして見た目を整える必要があります
<counter-container
apiurl="https://xxxxxxx.execute-api.xxxxx.amazonaws.com"
>
<counter-increment-button>
<span>
🌟
<counter-display>
<span slot="loading">...</span>
<span slot="error">error</span>
</counter-display>
</span>
</counter-increment-button>
</counter-container>
actions-upload-url-whitelist-to-s3 によるサイトマップ更新の自動化
@piyoppi/counter-api でデプロイされるLambda function「updateUrlList」を実行することで、サイトマップからURLホワイトリストを生成できますが、GitHub Actionsが使える環境の場合はこの作業を簡単に自動化できます。
たとえば、以下のようなディレクトリ構成の中にサイトマップが存在するとします。
.
|-- public
| `-- sitemap
| |-- sitemap-index.xml
| |-- sitemap-0.xml
| `-- sitemap-1.xml
これらのサイトマップは以下のURLで公開されているとします。
https://garakuta-toolbox.com/sitemap/sitemap-index.xml
https://garakuta-toolbox.com/sitemap/sitemap-0.xml
https://garakuta-toolbox.com/sitemap/sitemap-1.xml
この場合、以下のようにGitHub Actions Workflowを記述することで、リポジトリ内のサイトマップをURLホワイトリストの形式に整形し、指定のS3 Bucketにアップロードできます。
name: Update counter urls v2
on:
workflow_dispatch:
push:
branches:
- master
jobs:
update-counter-urls:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# 予めアクセスキーを用いて資格情報をセットしておく必要がある
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- uses: piyoppi/actions-counter-tools-upload-url-whitelist-to-s3@main
with:
sitemap_filename: ${{ github.workspace }}/public/sitemap/sitemap-index.xml # サイトマップのエントリポイントのFull Path
sitemap_baseurl: https://garakuta-toolbox.com/sitemap/ # サイトマップが存在するURL
sitemap_basepath: ${{ github.workspace }}/public/sitemap/ # サイトマップの存在するパス
s3_bucket_name: ${{ secrets.S3_BUCKET_NAME }} # アップロード先のS3 Bucket(@piyoppi/counter-apiのデプロイ時に指定したS3 Bucket Nameを設定)
output_urllist_filename: 'urllist' # @piyoppi/counter-api をデプロイする際の urllist パラメータとして設定したURLホワイトリストオブジェクトの名前
まとめ
ウェブページにかんたんにいいねボタンを設置できるツールを作りました。もしかすると、今後は以下の機能を実装したいなと思っています。
- 特定のクエリパラメータを許可することで、1ページに複数の投票ボタンを設置できるようにする
- 署名付きリクエストをサポートし、ログインユーザーのみが投票できるようにする
カウンタに特化したアプリケーションにしていこうと思っています。ではでは~。
クリックすると匿名でいいねできます。
(@piyoppi/counter-tools を使っています )