2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nuxt.js + Netlify で RSS を取得して静的 JSON にする

Posted at

// この記事は、 note に投稿した記事の再掲です。

やりたいこと

IFTTT を使って note の更新を検知

Nuxt.js で note RSS を取得して、静的 JSON としてダウンロード

コンポーネント内で読み込みたい

けっこう改造した動作サンプルはこちら

使うもの

  • Nuxt.js
  • Netlify (デプロイ方法は割愛)
  • IFTTT (Netlify に note の更新通知を送信する)

Nuxt.js をインストールする

今回は {rss-nuxt-app} という名前でインストール。色々聞かれるので、 axios を追加する。そのほかは任意。

$ yarn create nuxt-app rss-nuxt-app

パッケージをインストールする

axios 以外のパッケージをインストール。
必要なのは fs-extra, xml2js, @nuxtjs/moment
そのほかは任意。

$ yarn add -D fs-extra xml2js @nuxtjs/moment

@nuxtjs/moment
タイムスタンプを整形するやつ。あると楽なので必須。

fs-extra
JSON をローカルに書き出して静的ファイルにするためのやつ。必須。

xml2js
RSS は XML 形式なので、 XML を JSON に変換するためのやつ。必須。

pug, SCSS の loader とか
プリプロセッサ。 pug, SCSS を使いたい場合は必須。

$ yarn add -D pug@2.0.3 pug-plain-loader node-sass sass-loader

RSS を静的 JSON にするためのファイルを作る

node_modules がある階層に modules ディレクトリを作成。
api-build-json.js という空のファイルを作成して保存する。

nuxt.config.js に設定を記述

@nuxtjs/moment と、さっき作った api-build-json.jsmodules に追加

nuxt.config.js
module.exports = {
  ...
  modules: [
    ...
    ['@nuxtjs/moment', ['ja']],
    '~/modules/api-build-json'
    ...
  ],
  ...
}

api-build-json.js を編集する

RSS を 取得して 静的 JSON にするソースコード
以下が全文

modules/api-build-json.js
import axios from 'axios'
import fse from 'fs-extra'
import ps from 'xml2js'

export default function apiBuildJson() {
  const api = axios.create()
  const distJosonFile = './static/_nuxt/api/index.json'
  const arr = []
  
  // サムネイルを取得する関数
  const getThumbnails = (data) => {
    let thumbnails = data.match(/https(.|\s)*?(jpg|png|gif|jpeg)/gi)
    return (thumbnails !== null && thumbnails !== undefined)
      ? Object.values(thumbnails)
      : false
  }

  // Axios で記事の RSS を取得
  return axios.all([
    api.get('https://note.nokura.me/rss'),
  ]).then(axios.spread((nokura) => {
    // XML を格納する
    const xml = nokura.data

    // 変換した JSON を格納するためのオブジェクト
    let json = {
      items: []
    }

    // XML オブジェクト を JSON に変換して JSON オブジェクトに格納する
    ps.parseString(xml, (message, xmlres) => {
      json.items = xmlres.rss.channel[0].item
    })

    // サムネイルを取得した配列を作成して結合
    json.items.forEach((data) => {
      let thumb = getThumbnails(data.description[0])
      Object.assign(data, { thumb: thumb })
    })

    // 空の配列に JSON オブジェクトを push
    arr.push(json)

    // 静的ファイルとして出力
    fse.outputFile(distJosonFile, JSON.stringify(arr))
  }))
}

use with Gist Search

7行目

JSON ファイルを吐き出す先を指定

modules/api-build-json.js
const distJosonFile = './static/_nuxt/api/index.json'

33 - 35 行目

ここで XML を JSON に変換している

modules/api-build-json.js
// XML オブジェクト を JSON に変換して JSON オブジェクトに格納する
ps.parseString(xml, (message, xmlres) => {
    json.items = xmlres.rss.channel[0].item
})

37 - 41 行目

RSS だと本文とサムネイルが同じ要素内にあるので
正規表現を使って画像だけを取得して配列にする

modules/api-build-json.js
// サムネイルを取得した配列を作成して結合
json.items.forEach((data) => {
    let thumb = getThumbnails(data.description[0])
    Object.assign(data, { thumb: thumb })
})

画像を取得して配列にする関数は 11 - 16 行目 にあるやつ

modules/api-build-json.js
// サムネイルを取得する関数
const getThumbnails = (data) => {
  let thumbnails = data.match(/https(.|\s)*?(jpg|png|gif|jpeg)/gi)
  return (thumbnails !== null && thumbnails !== undefined)
    ? Object.values(thumbnails)
    : false
}

ビルドしてみる

~/dist/_nuxt/api/index.json てファイルが生成されるはず

$ yarn build

生成された JSON を読み込む

ウェブサイト全体で読み込みたいので、 ~/store/index.jsimport する

store/index.js
import jsonData from '~/static/_nuxt/api/index.json'

export const state = () => ({
  jsonData: jsonData
})

use with Gist Search

~/pages/index.vue で表示してみる

pages/index.js
 <template>
  <div v-if="$store.state.jsonData[0]" class="p_note_mu">
    <div class="p_note_mu-body">
      <a
        v-for="(post, index) in $store.state.jsonData[0].items"
        :key="index"
        :href="post.link[0]"
        target="_blank"
      >
        <article>
          <!-- サムネイル -->
          <div class="p_nt-mv">
            <img v-if="post.thumb" :src="post.thumb[0]" :alt="post.title[0]" />
            <div v-else class="no-image">
              <div class="no-image-text">NO IMAGE</div>
            </div>
          </div>
          <div class="p_nt-body">
            <div class="p_nt-body-header">
              <p>
                <!-- 日付 -->
                {{ getTheDate(post.pubDate[0]) }}
              </p>
              <h3 class="p_nt-body-heading-text">
                <!-- タイトル -->
                {{ post.title[0] }}
              </h3>
            </div>
          </div>
        </article>
      </a>
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    getTheDate(date) {
      return this.$moment(date).format('YYYY.MM.DD (ddd)')
    }
  }
}
</script>

<style>
.p_note_mu {
  padding: 80px 0;
}

.p_note_mu-body {
  width: 960px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

a {
  width: 300px;
  margin: 0 10px 20px;
  border: 1px solid #ccc;
}

.p_nt-mv {
  width: 100%;
  height: 200px;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f1f1f1;
}

.p_nt-body {
  padding: 20px;
  border-top: 1px solid #ccc;
}
</style>

use with Gist Search

上記のコードでこんなかんじになる

picture_pc_664b18c1faf845c62956661629b8b336.png

IFTTT を使って Netlify に note の更新通知を送る

Netlify 側での作業

Netlify で webhook の URL を発行する

Settings > Build & deploy > Build hooks > Add build hook で URL が発行できる。
ここで発行した URL をメモしておく。

IFTTT を利用した作業

更新通知は IFTTT を利用して Netlify に送る。

IFTTT
https://ifttt.com/

(1) 登録をして、右上のアカウント名をクリック → New Applet
picture_pc_2333e352ff5c68d448d8f58021a36b06.png

(2) +this をクリック
picture_pc_728c26a80b53fc85944e1f0c23241b0e.png

(3) RSS を選択
picture_pc_96205dd46d44aeb04f49ddfa9f2797a7.png

(4) New feed item を選択
picture_pc_7dc4ada3371d97a1df8f6d04f5c05437.png

(5) RSS の URL を入力し、 Create trigger をクリック
picture_pc_374abfc642243d4703dc05a990f4d341.png

(6) +that をクリック
picture_pc_6119db8feec473d63c37abbd4e41efcb.png

(7) Webhooks を選択
picture_pc_0462fc509bc9ec40844938b26576e45c.png

(8) Make a web request をクリック
picture_pc_eda961a888a4f2294b3092cc3c4018c3.png

(9) 下記の設定項目を入力し、 Create action をクリックして終了

項目 内容
URL Netlify で発行した webhook の URL
Method POST を選択
Content Type application/json を選択

picture_pc_31c0b35fde2b0fd37b50076f56092979.png

タイムラグはあるものの、 note の更新を Netlify が検知できるようになりました。

あとは普通に note を更新するだけ。

おわり。

参考リンク

のくらさんの note
https://note.nokura.me/

のくらさんの Twitter
https://twitter.com/riman114

けっこう改造した動作サンプル
https://rss-nuxt-app.netlify.com/

けっこう改造した動作サンプルのソースコード
https://github.com/incolorsnet/rss-nuxt-app.netlify.com

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?