CTO室の岩本 (@iwamot) です。同僚エンジニアの情報発信を活性化するのが、ぼくのミッションのひとつです。
ENECHANGEでは、Team Blog Hubを使って、所属エンジニアのブログ記事や発表スライドを集約・公開しています。経緯は「Team Blog Hub を用いた ENECHANGE エンジニア記事まとめサイトの公開」に書きました。
そして先日から、集約結果のAtomフィード配信も始めています。Team Blog Hubにはフィード配信機能がないため、forkしたソースコードに手を入れた形です。
今回の記事では、具体的にどう実装したかをご紹介します。
実装内容
結論から書くと、src/builder/posts.tsを下記のように編集しました。yarn build
の際に、静的なpublic/atom.xmlを出力します。
$ git diff cf65d3be29336b2a789a58b501c01dd5116bb7b6 src/builder/posts.ts diff --git a/src/builder/posts.ts b/src/builder/posts.ts index 21721c1..87b0eda 100644 --- a/src/builder/posts.ts +++ b/src/builder/posts.ts @@ -1,6 +1,8 @@ +import { Feed } from "feed"; import fs from "fs-extra"; import Parser from "rss-parser"; import { members } from "../../members"; +import { config } from "../../site.config"; import { PostItem, Member } from "../types"; export default {}; @@ -8,6 +10,7 @@ type FeedItem = { title: string; link: string; contentSnippet?: string; + content?: string; isoDate?: string; dateMiliSeconds: number; }; @@ -21,10 +24,11 @@ async function fetchFeedItems(url: string) { // return item which has title and link return feed.items - .map(({ title, contentSnippet, link, isoDate }) => { + .map(({ title, contentSnippet, content, link, isoDate }) => { return { title, contentSnippet: contentSnippet?.replace(/\n/g, ""), + content: content, link, isoDate, dateMiliSeconds: isoDate ? new Date(isoDate).getTime() : 0, @@ -77,6 +81,37 @@ async function getMemberFeedItems(member: Member): Promise<PostItem[]> { if (items) allPostItems = [...allPostItems, ...items]; } allPostItems.sort((a, b) => b.dateMiliSeconds - a.dateMiliSeconds); + + const feed = new Feed({ + title: config.siteMeta.title, + description: config.siteMeta.description, + id: config.siteRoot + "/", + link: config.siteRoot + "/", + feed: config.siteRoot + "/atom.xml", + copyright: "© " + config.siteMeta.teamName, + }); + allPostItems.slice(0, 15).forEach((post) => { + feed.addItem({ + title: post.title, + id: post.link, + link: post.link, + content: post.content, + author: [ + { + name: post.authorName, + link: + config.siteRoot + "/members/" + encodeURIComponent(post.authorId), + }, + ], + date: new Date(post.dateMiliSeconds), + }); + }); + fs.ensureDirSync("public"); + fs.writeFileSync("public/atom.xml", feed.atom1()); + fs.ensureDirSync(".contents"); - fs.writeJsonSync(".contents/posts.json", allPostItems); + fs.writeJsonSync(".contents/posts.json", allPostItems.map((post) => { + delete post.content; + return post; + })); })();
Atomフィードの構築にはfeedパッケージを使っています。yarn add --dev feed
で別途インストールしました。
また、フィードのエントリには、rss-parserのパース結果の content
を含めるようにしました。contentSnippet
だと、READMEの例のように情報量が少なくなってしまうためです。
content: '<a href="http://example.com">this is a link</a> & <b>this is bold text</b>' contentSnippet: 'this is a link & this is bold text'
まとめ
以上、Team Blog Hubでの集約フィード配信例をご紹介しました。あくまで一例ですが、参考になれば幸いです。