External Publication
Visit Post

note記事をとってくるようにしてみた

watura February 28, 2025
Source

note記事をとってくるようにしてみた

どうするとブログを書くのが楽になるのかなぁというを考えていました。

とりあえず、流行りのAIを使ってサクッとnoteのRSSから記事を作成するようにしてみました。

投稿数が一気に増えてしっかり更新している人みたいになりました。

今回のコードは限りなくCursorに書いてもらったものになります。

ymlの方は雑に微調整しましたが、jsの方は完全に手を入れていないコードです。

画像とかどうなるんだろう?というぎもんがあるんですが、とりあえず、動いているのでいつか直すということでみなかったことにします。

name: フィードを取得してマークダウンに変換

on: schedule: - cron: "0 * * * *" # 毎時実行 workflow_dispatch: # 手動実行用

jobs: fetch-and-convert: runs-on: ubuntu-latest steps: - name: リポジトリをチェックアウト uses: actions/checkout@v4

  - name: Node.jsをセットアップ
    uses: actions/setup-node@v4
    with:
      node-version: "20"

  - name: 必要なパッケージをインストール
    run: npm install rss-parser turndown

  - name: RSSフィードを取得してマークダウンに変換
    run: |
      node .github/scripts/fetch-rss.js

  - name: 変更があるか確認
    id: check_changes
    run: |
      git diff --quiet content/blog || echo "changes=true" >> $GITHUB_OUTPUT

  - name: ブランチを作成
    if: steps.check_changes.outputs.changes == 'true'
    run: |
      git config --global user.name 'GitHub Action'
      git config --global user.email 'action@github.com'
      BRANCH_NAME="rss-feed-update-$(date +%Y%m%d-%H%M%S)"
      git checkout -b $BRANCH_NAME
      git add content/blog/
      git commit -m "RSSフィードから新しい記事を追加"
      git push origin $BRANCH_NAME
      echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
    id: create_branch

  - name: Pull Requestを作成
    if: steps.check_changes.outputs.changes == 'true'
    uses: peter-evans/create-pull-request@v7
    with:
      token: ${{ secrets.GITHUB_TOKEN }}
      commit-message: RSSフィードから新しい記事を追加
      title: RSSフィードから新しい記事を追加
      body: |
        このPRはRSSフィードから自動的に生成された新しい記事を追加します。
      branch: ${{ steps.create_branch.outputs.branch_name }}
      base: main

const fs = require('fs'); const path = require('path'); const Parser = require('rss-parser'); const TurndownService = require('turndown');

const parser = new Parser({ customFields: { item: [ ['content:encoded', 'content'] ] } });

const turndownService = new TurndownService({ headingStyle: 'atx', codeBlockStyle: 'fenced' });

// 画像のURLを保持するように設定 turndownService.keep(['img']);

async function fetchAndConvert() { try { const feed = await parser.parseURL('https://wtr.io/rss?f=full_text');

    for (const item of feed.items) {
        // リンクからファイル名を生成
        const urlPath = new URL(item.link).pathname;
        const pathSegments = urlPath.split('/');
        const fileName = pathSegments[pathSegments.length - 1] + '.md';
        const filePath = path.join('content', 'blog', fileName);

        // ファイルが既に存在する場合はスキップ
        if (fs.existsSync(filePath)) {
            console.log(`ファイルは既に存在します: ${fileName}`);
            continue;
        }

        // 日付をフォーマット
        const pubDate = new Date(item.pubDate);
        const formattedDate = pubDate.toISOString().split('T')[0];

        // HTMLをマークダウンに変換
        const content = item.content || item.description;
        const markdown = turndownService.turndown(content);

        // 指定されたテンプレートに従ってマークダウンファイルを作成
        const fileContent = `+++

title = "${item.title}" date = "${formattedDate}" tags = ["note"] canonicalUrl = "${item.link}" +++

${markdown} `;

        fs.writeFileSync(filePath, fileContent);
        console.log(`新しいファイルを作成しました: ${fileName}`);
    }
} catch (error) {
    console.error('エラーが発生しました:', error);
    process.exit(1);
}

}

fetchAndConvert();

Discussion in the ATmosphere

Loading comments...