MicroCMSのデータを取得してAlgoliaに登録するNodeの処理
2024年1月14日
2024年1月15日
目次
必要なnpm
package.json
"scripts": {
"generateMicroCmsToAlgolia": "node ./src/utils/server/generateMicroCmsToAlgolia",
},
build
時に、合わせて実行するようにしておくと良いです。
.env
MICROCMS_SERVICE_DOMAIN=MicroCMSのドメイン
MICROCMS_API_KEY=MicroCMSのAPIキー
SITE_DOMAIN=サイトのドメイン
NEXT_PUBLIC_ALGOLIA_APPLICATION_ID=AlgoliaアプリケーションID
ALGOLIA_ADMIN_API_KEY=Algolia管理APIキー
NEXT_PUBLIC_ALGOLIA_INDEX=Algoliaインデックス
generateMicroCmsToAlgolia
const axios = require('axios').default;
const removeMd = require('remove-markdown');
const algoliasearch = require('algoliasearch');
const getMicroCMSdata = async (name, limit, query) => {
const url = `https://${process.env.MICROCMS_SERVICE_DOMAIN}.microcms.io/api/v1/${name}`;
const apiKeyHeaderOption = {
headers: { 'X-API-KEY': process.env.MICROCMS_API_KEY },
};
const getUrlOption = (number, url) => {
return url + `?limit=${number}${query || ''}`;
};
const getTotalCountUrl = getUrlOption(0, url);
const totalCountUrlData = await axios
.get(getTotalCountUrl, apiKeyHeaderOption)
.then((r) => r.data);
const { totalCount } = await totalCountUrlData;
const getContentUrl = getUrlOption(limit || totalCount, url);
const contentUrlData = await axios
.get(getContentUrl, apiKeyHeaderOption)
.then((r) => r.data);
const data = await contentUrlData;
return data;
};
const generateMicroCmsToAlgolia = async () => {
if (
!process.env.MICROCMS_SERVICE_DOMAIN ||
!process.env.MICROCMS_API_KEY ||
!process.env.SITE_DOMAIN ||
!process.env.NEXT_PUBLIC_ALGOLIA_APPLICATION_ID ||
!process.env.ALGOLIA_ADMIN_API_KEY ||
!process.env.NEXT_PUBLIC_ALGOLIA_INDEX
) {
return;
}
const { contents: entries } = await getMicroCMSdata(
'entries',
999,
'&orders=-publishedAt&fields=id,title,categories.label,categories.value,tags.label,tags.value,publishedAt,image,description,body'
);
const htmlTagRegex = /<("[^"]*"|'[^']*'|[^'">])*>/g;
const objects = entries.map((entry) => {
return {
objectID: entry.id,
url: `https://${process.env.SITE_DOMAIN}/entry/${entry.id}`,
title: entry.title,
description: entry.description,
tags: entry.tags,
categories: entry.categories,
content: entry.body
.map((v) => {
const commentValue = v;
if (v.fieldId === 'comments') {
return commentValue.comments
.map((v) => `${v.name ? `${v.name}: ` : ''}${v.text}`)
.join('');
}
if (v.fieldId === 'html') {
return v.value.replace(htmlTagRegex, '');
}
if (v.fieldId === 'markdown') {
return removeMd(v.value);
}
if (v.fieldId === 'richeditor' && v.value) {
return v.value.replace(htmlTagRegex, '');
}
})
.join('')
.slice(0, 3200), // 数が多いAlgoliaの無料版の文字制限に引っかかってしまうため制限しています
};
});
const client = algoliasearch(
process.env.NEXT_PUBLIC_ALGOLIA_APPLICATION_ID,
process.env.ALGOLIA_ADMIN_API_KEY
);
const index = client.initIndex(process.env.NEXT_PUBLIC_ALGOLIA_INDEX);
await index.saveObjects(objects, { autoGenerateObjectIDIfNotExist: true });
};
generateMicroCmsToAlgolia().catch((error) => {
console.error(error);
});
これは、このブログのfield
をもとに制作しています。fieldId
やentry
の項目については
それぞれのMicroCMSの設定に合わせてください。
実行方法
MICROCMS_API_KEY=${MICROCMS_API_KEY} MICROCMS_SERVICE_DOMAIN=${MICROCMS_SERVICE_DOMAIN} NEXT_PUBLIC_ALGOLIA_APPLICATIO_IDN=${APPLICATIO_IDN} ALGOLIA_ADMIN_API_KEY=${ALGOLIA_ADMIN_API_KEY} NEXT_PUBLIC_ALGOLIA_INDEX=${ALGOLIA_INDEX} SITE_DOMAIN=${SITE_DOMAIN} npm run generateMicroCmsToAlgolia
NEXT_PUBLIC
となっているのは、Next
で使用するものも含まれているため共通で使えるようにしています。