VercelµCMS環境で記事コンテンツ内のリンク切れチェックを自動化する方法
記事コンテンツを運用していると、リンク切れが発生することがあります。リンク切れが発生すると、エンドユーザーが閲覧する際に不便を感じるだけでなく、SEOにも悪影響を及ぼす可能性があります。
自身が管理するドメイン内のリンク切れは、Google Search Consoleなどを利用して確認できます。一方で、外部サイトへのリンク切れは管理が難しくなります。とくにアフィリエイトなどの広告URLは、運用中にリンク切れが発生する可能性が高いため、手動管理の運用は骨が折れます。
今回は、上記のようなケースにVercelとmicroCMSを利用した環境で記事コンテンツのリンク切れチェックを自動で行う方法を紹介します。
記事内で記載する内容のGitHubリポジトリは以下になります。
目標設定
CMSで管理する記事コンテンツのリンク切れを自動でチェックする方法はいくつか考えられますが、この記事ではAPI経由でコンテンツ取得ができるmicroCMSの強みを利用し、リンク切れチェックを行うアプローチを取りたいと思います。
- 定期的に記事コンテンツのリンク切れチェックを行う
- チェック対象はCMSで管理している記事コンテンツに限定する
- リンク切れが発生した場合はメールで通知する(GoogleアカウントのGmailで送信)
技術スタック
Vercelにコンテンツをデプロイし、microCMSで記事コンテンツ管理していることを想定します。リンク切れチェックはVercelのサーバーレス関数を利用して実装します。さらにVercelで提供されているCron Jobの仕組みと組み合わせることで、定期的にリンク切れチェックを行うことが可能となります。
利用ライブラリ
今回の実装にあたり、メインで利用しているライブラリは以下になります。
microCMSの設定
記事コンテンツはリスト形式で管理されており、記事の登録は以下のようになっていることを想定します。
{
"id": "test-01",
"createdAt": "2022-11-10T08:03:33.441Z",
"updatedAt": "2022-11-10T15:23:10.089Z",
"publishedAt": "2022-11-10T08:03:33.441Z",
"revisedAt": "2022-11-10T15:23:10.089Z",
"title": "これはテスト投稿です",
"content": "<h2 id=\"he14a109d56\">Welcome to the Pure Liquid documentation!🎉</h2><p>ブログテンプレートからAPIを作成しました。<br>おつかれさまでした🎉<br></p><h2 id=\"hf45076424a\">APIプレビューを試そう🚀</h2><p>最初に「APIプレビュー」をしてみましょう。<br>入稿したコンテンツはAPI経由で取得し、Viewに繋ぎ込みます。<br>APIプレビューでは実際のAPIレスポンスを確認でき、あなたの開発を加速させます。<br><br>👇まずはここをクリックします。",
"eyecatch": {
"url": "https://images.microcms-assets.io/assets/test/blog-template.png",
"height": 630,
"width": 1200
},
"category": {
"id": "category-01",
"createdAt": "2022-11-10T08:03:32.159Z",
"updatedAt": "2022-11-10T08:03:32.159Z",
"publishedAt": "2022-11-10T08:03:32.159Z",
"revisedAt": "2022-11-10T08:03:32.159Z",
"name": "カテゴリー1",
}
}
記事のcontent
にはHTML形式の記事本文が格納されており、この中に任意のリンクが含まれていることを想定します。
赤枠がcontent部分
コンテンツリストのエンドポイントは以下のようになっていることを想定します。APIプレビューで対象のエンドポイントを確認してください。
https://<service_domain>.microcms.io/api/v1/blogs
service_domain
の箇所は後ほど環境変数として設定します。APIキーも同じく後で必要になるため、手元にひかえておいてください。
Gmailの設定
NodemailerでGmailを利用するためには、以下の設定が必要です。
- アプリパスワードの作成
アプリパスワードは以下から作成できます。取得したパスワードは後ほど環境変数に設定します。
開発環境のセットアップ
ここではpnpmでNext.jsプロジェクトを作成します。お好みのパッケージマネージャーを利用してください。
$ pnpm create-next-app
プロジェクトのセットアップが完了したら、以下のコマンドでmicroCMS JavaScript SDKとNodemaiilerをインストールします。
$ pnpm add microcms-js-sdk nodemailer
microCMS JavaScript SDKは記事の全件取得に利用し、Nodemailerはリンク切れが発生した場合のメール通知に利用します。
環境変数の設定
.env.local
ファイルを作成し、以下の環境変数を設定します。
# microCMSのプロジェクト情報
MICROCMS_API_KEY=YOUR_MICROCMS_API_KEY
MICROCMS_SERVICE_DOMAIN=YOUR_MICROCMS_SERVICE_DOMAIN
# 通知用のGmailアカウント
GMAIL_USER=YOUR_GMAIL_USER
GMAIL_APP_PASSWORD=YOUR_GMAIL_APP_PASSWORD
# 通知先のメールアドレス
NOTIFICATION_EMAIL=YOUR_NOTIFICATION_EMAIL
# Vercel Cron Jobsのシークレットキー
CRON_SECRET=YOUR_CRON_SECRET
- MICROCMS_API_KEY: microCMSのAPIキー
- MICROCMS_SERVICE_DOMAIN: microCMSのサービスドメイン
- GMAIL_USER: 送信元のGmailアカウント
- GMAIL_APP_PASSWORD: Gmailのアプリパスワード
- NOTIFICATION_EMAIL: 通知先のメールアドレス
- CRON_SECRET: Vercel Cron Jobsの実行でAPI保護に利用するシークレットキー
CRON_SECRETは以下のような生成ツールで作成すると便利です。
microCMS記事の取得処理
src/app/_libs/microcms.ts
にmicroCMS SDKの初期化処理を記述します。
fetchAllBlogs
を作成し、記事一覧を取得する処理を記述します。
Nodemailerでのメール送信処理
NodemailerでGmailを利用してメール送信する処理を記述します。
Cron Jobsの処理
VercelのCron Jobsで定期実行する処理を記述します。以下フォルダー構成でファイルを作成します。
src/app/api/cron/link-checker/route.ts
細かい処理内容は割愛しますが、以下のような処理を行っています。
- リクエストの信頼性を確認する(事前に作成したCRON_SECRETと一致するか検証)
- microCMSから記事一覧を取得
- 記事の
content
からリンクを抽出 - リンク切れチェックを行い、リンク切れが発生した場合はメール通知
- レスポンスを返却
CRON_SECRETを環境変数で設定すると、Vercel Cron JobsがAPIを実行する際に設定したトークンをリクエストヘッダーに付与してくれます。 API側では以下のようにauthorization
ヘッダーを取得し、CRON_SECRETと一致するか検証を行います。
import type { NextRequest } from 'next/server';
export function GET(request: NextRequest) {
const authHeader = request.headers.get('authorization');
if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response('Unauthorized', {
status: 401,
});
}
return Response.json({ success: true });
}
これによりAPIの保護を行うことができるため、必ず設定しましょう。
Cron Jobsの設定
プロジェクトルートにverce.json
ファイルを作成し、以下のように記述するだけで設定できます。path
にはCron Jobsのエンドポイントを指定し、schedule
には実行スケジュールを設定します。
{
"crons": [
{
"path": "/api/cron/link-checker",
"schedule": "0 1 * * *"
}
]
}
ローカルでの動作確認
以下のコマンドでローカルでプロジェクトを起動し、リンクチェック処理が正常に動作するか確認します。
$ pnpm dev
起動した状態で、http://localhost:3000/api/cron/link-checker
にアクセスし、リンク切れチェックが正常に動作するか確認します。
単純にURLを叩くだけではトークンの検証が通らないため、リクエストヘッダーにCRON_SECRET
で設定した値をセットしてリクエストを送信します。
記事コンテンツ内にリンク切れが発生している場合、以下のようにメール通知が受信できます。
Vercelへのデプロイ
ローカルでの動作確認が完了したら、Vercelにデプロイします。デプロイ方法は割愛します。管理画面ベースで簡単にGitHubリポジトリと連携してデプロイできます。必要に応じて公式ドキュメントを参考にしてください。
まとめ
今回採用したアプローチではAPIベースで記事コンテンツの品質監査を行えるため、スクレイピングなどの手法よりもより効率よく、信頼性の高い処理が可能となります。コンテンツのビルドプロセスを間に挟まなくていいのはかなりの利点かなと思います。
一方でこのアプローチは処理内容がAPIのスキーマに依存するため、APIの仕様変更には注意が必要です。また、ビルドプロセスでフロントのHTML構造が大きく変わる場合やコードベースで管理している箇所はチェックし切れないので、注意が必要です。
この記事ではメール送信を行っていますが、運用体制的に可能であればSlack通知などを検討いただいた方が有用かもしれません。
Vercel Cron Jobsを利用することで定期的なプロジェクトのメンテナンスや監視を自動化できます。今回の用途以外にもさまざまな活用方法が考えられるため、ぜひ検討してみてください。
Discussion