🤩

Zennの投稿を取得してブログに取り込む

2023/01/29に公開

最初、RSSからpasrerを使用して取得しようかと諸々検討していましたがどうやらAPI(非公式?)があるようなのでそちらを使用することに変更しました。

RSSを使用する場合

ちなみにRSS自体はItemとして15件ほど取得できそうなので都度ページングを行いつつ取得→パース→各所に取り込むの流れでできそうだと思います。
https://www.npmjs.com/package/rss-parser
これを調べている内に下記のcatnoseさんのコメントを発見し、急遽Rest APIからfetchしてくる方針に切り替えました。
https://zenn.dev/link/comments/de8c8e9f253aa4

APIから取ってくる

次のURLで対象のusernameの方の記事を全県取得することが出来るようなのでそれを使用。
https://zenn.dev/api/articles?username=niiharamegumu&order=latest

簡単に自分のブログで追加したコードを載せておきます。
諸々雑多で手を加えたいところですが一旦動くものをということで導入しています🙇‍♂️
https://megumu.me/blogs/zenn

import { GetStaticProps } from 'next'
import { Flex, Grid, Text } from '@chakra-ui/react'
import { FcReading } from 'react-icons/fc'

import { ZennItem } from '../../../types/zenn/zennItem'
import Seo from '../../../components/Seo'
import { HeadH2 } from '../../../components/style/Common'
import BlogsNav from '../../../components/blogs/BlogsNav'
import VisibilitySection from '../../../components/VisibilitySection'
import { BlogCard } from '../../../components/blogs/BlogCard'

type BlogZennProps = {
  articles?: ZennItem[]
}

const zennApiURL = 'https://zenn.dev/'

const zennFetcher = async <T,>(path: string) => {
  const res = await fetch(`${zennApiURL}api/${path}`)
  const result: T = await res.json()
  return result
}

const BlogZenn = (props: BlogZennProps) => {
  const { articles } = props

  if (!articles) {
    return <p>Zennへの投稿はございません。</p>
  }

  return (
    <>
      <Seo
        pageTitle="Blogs-Zenn"
        pageDescription="zenn.devで投稿している記事一覧。"
        pageImg="https://megumu-me.vercel.app/icon.png"
        pageImgWidth={1280}
        pageImgHeight={640}
      />
      <HeadH2 display="flex" alignItems="center" gap={2}>
        <FcReading />
        blogs - zenn
      </HeadH2>
      <BlogsNav />
      <Grid templateColumns={'1fr'} gap={2}>
        {articles.map(article => (
          <VisibilitySection key={String(article.id)} delay={0.15}>
            <Flex gap={{ base: 6, md: 8 }} alignItems={'center'}>
              <Text fontSize={{ base: '4xl', sm: '6xl' }}>{article.emoji}</Text>
              <BlogCard
                link={`${zennApiURL}${article.path}`}
                title={article.title}
                createdAt={article.published_at}
                updatedAt={article?.body_updated_at}
                isBlank={true}
              />
            </Flex>
          </VisibilitySection>
        ))}
      </Grid>
    </>
  )
}

export default BlogZenn

export const getStaticProps: GetStaticProps = async () => {
  const result = await zennFetcher<{ articles: ZennItem[] }>(
    'articles?username=niiharamegumu&order=latest'
  )
  console.log()

  return {
    props: {
      articles: result.articles
    },
    revalidate: 60
  }
}

Discussion