Skip to content

Instantly share code, notes, and snippets.

@tsuki-lab
Last active July 27, 2021 02:21
Show Gist options
  • Save tsuki-lab/32c673c1b206c47c4a1bf5fbf1755ea6 to your computer and use it in GitHub Desktop.
Save tsuki-lab/32c673c1b206c47c4a1bf5fbf1755ea6 to your computer and use it in GitHub Desktop.
[Gatsby.js]RSS情報を元にFeed画像を取得してnodeに詰める。
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
const axios = require('axios')
const { JSDOM } = require('jsdom')
/**
* Feedのurl情報からOGP画像を取得してファイルノードを作成する
*
* @param {*} { actions: { createNode, createNodeField }, createNodeId, cache, store, getNodes }
*/
async function createFileNodeForFeedImage({ actions: { createNode, createNodeField }, createNodeId, cache, store, getNodes }) {
// `gatsby-source-rss-feed` を用いて取得した 'FeedQiitaPost', 'FeedZennPost'などを対象にした正規表現
const FeedPostRegExp = /^(?!.+Meta)Feed.+$/
const nodes = getNodes()
await Promise.all(nodes.map(async node => {
if (!FeedPostRegExp.test(node.internal.type)) return;
const url = node.link;
const ogp = await fetchOgpProperty(url);
// createRemoteFileNodeで外部の画像のファイルノードを作成する
const fileNode = await createRemoteFileNode({
url: ogp.image,
cache,
store,
createNode: createNode,
createNodeId: createNodeId,
name: node.title,
});
await createNodeField({
node: fileNode,
name: 'feedImage',
value: 'true',
});
await createNodeField({
node: fileNode,
name: 'feedId',
value: node.id,
});
return fileNode;
}));
}
/**
* urlからogpのプロパティを抽出して返却
*
* @param {*} url
* @return {*} any
*/
async function fetchOgpProperty(url) {
const { data } = await axios.get(url)
const dom = new JSDOM(data);
const meta = dom.window.document.querySelectorAll("head > meta");
// metaからOGPを抽出し、JSON形式に変換する
const ogp = Array.from(meta)
.filter((element) => element.hasAttribute("property"))
.reduce((pre, ogp) => {
const property = ogp.getAttribute("property").trim().replace("og:", "");
const content = ogp.getAttribute("content");
pre[property] = content;
return pre;
}, {});
return ogp;
}
exports.createFileNodeForFeedImage = createFileNodeForFeedImage
const {createFileNodeForFeedImage} =require('./gatsby-node/createFileNodeForFeedImage')
exports.sourceNodes = async (context) => {
await createFileNodeForFeedImage(context);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment