Use Cases

Claude CodeでRSSフィードを実装する方法【ブログ配信の自動化】

Claude Codeを活用してRSS/Atomフィードの生成を自動化する方法を解説。Astroやnext.jsでの実装例、カスタマイズ、バリデーションまで紹介します。

RSSフィードでブログの読者獲得を加速する

RSSフィードを提供することで、ブログ記事の更新をRSSリーダーで購読してもらえます。Claude Codeを使えば、RSS 2.0やAtomフィードの生成を短時間で実装できます。

基本的なRSSフィード生成

> ブログ記事のRSSフィードを生成するエンドポイントを作成して。
> RSS 2.0形式で、最新20件の記事を配信して。
// src/pages/rss.xml.ts
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import sanitizeHtml from 'sanitize-html';
import MarkdownIt from 'markdown-it';

const parser = new MarkdownIt();

export async function GET(context: { site: string }) {
  const posts = await getCollection('blog');
  
  const sortedPosts = posts
    .filter(post => !post.data.draft)
    .sort((a, b) => 
      new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime()
    )
    .slice(0, 20);

  return rss({
    title: 'My Tech Blog',
    description: 'Web開発に関する技術ブログ',
    site: context.site,
    items: sortedPosts.map(post => ({
      title: post.data.title,
      pubDate: new Date(post.data.pubDate),
      description: post.data.description,
      link: `/blog/${post.slug}/`,
      content: sanitizeHtml(parser.render(post.body), {
        allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']),
      }),
      categories: post.data.tags,
    })),
    customData: `<language>ja</language>`,
  });
}

Atomフィードの実装

// src/pages/atom.xml.ts
import { getCollection } from 'astro:content';

export async function GET() {
  const posts = await getCollection('blog');
  const siteUrl = 'https://example.com';

  const sortedPosts = posts
    .filter(p => !p.data.draft)
    .sort((a, b) => 
      new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime()
    )
    .slice(0, 20);

  const atom = `<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>My Tech Blog</title>
  <link href="${siteUrl}/atom.xml" rel="self"/>
  <link href="${siteUrl}"/>
  <id>${siteUrl}/</id>
  <updated>${sortedPosts[0]?.data.pubDate ?? new Date().toISOString()}</updated>
${sortedPosts.map(post => `  <entry>
    <title>${escapeXml(post.data.title)}</title>
    <link href="${siteUrl}/blog/${post.slug}/"/>
    <id>${siteUrl}/blog/${post.slug}/</id>
    <published>${post.data.pubDate}</published>
    <summary>${escapeXml(post.data.description)}</summary>
    <category term="${post.data.tags?.[0] ?? ''}" />
  </entry>`).join('\n')}
</feed>`;

  return new Response(atom, {
    headers: { 'Content-Type': 'application/atom+xml; charset=utf-8' },
  });
}

function escapeXml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

HTMLヘッダーへのフィードリンク追加

<head>
  <link rel="alternate" type="application/rss+xml" 
        title="RSS Feed" href="/rss.xml" />
  <link rel="alternate" type="application/atom+xml" 
        title="Atom Feed" href="/atom.xml" />
</head>

カテゴリ別フィードの生成

// src/pages/rss/[category].xml.ts
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const posts = await getCollection('blog');
  const categories = [...new Set(posts.map(p => p.data.category))];
  
  return categories.map(category => ({
    params: { category },
  }));
}

export async function GET({ params, site }: { params: { category: string }; site: string }) {
  const posts = await getCollection('blog');
  const filtered = posts
    .filter(p => p.data.category === params.category && !p.data.draft)
    .sort((a, b) => 
      new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime()
    );

  // RSS生成ロジック(カテゴリ名をタイトルに含める)
  return generateRss({
    title: `My Tech Blog - ${params.category}`,
    posts: filtered,
    site,
  });
}

フィードのバリデーション

生成したRSSフィードが正しい形式か、W3C Feed Validation Serviceで確認できます。

> RSSフィードのバリデーションテストを書いて。
> XMLの構造とRSS 2.0仕様に準拠しているか確認して。
import { describe, it, expect } from 'vitest';
import { XMLParser } from 'fast-xml-parser';

describe('RSS Feed', () => {
  it('有効なRSS 2.0形式であること', async () => {
    const response = await fetch('http://localhost:4321/rss.xml');
    const xml = await response.text();
    const parser = new XMLParser();
    const result = parser.parse(xml);

    expect(result.rss).toBeDefined();
    expect(result.rss.channel.title).toBeTruthy();
    expect(result.rss.channel.item.length).toBeGreaterThan(0);
    expect(result.rss.channel.item.length).toBeLessThanOrEqual(20);
  });
});

まとめ

RSSフィードの実装は、ブログ読者の獲得とリテンションに大きく貢献します。Claude Codeを活用すれば、SEO対策と組み合わせてサイトの発見性を高められます。サイトマップと一緒にビルド時に自動生成する設定を推奨します。フィードの仕様についてはRSS 2.0 Specificationを参照してください。

#Claude Code #RSS #Atom #フィード #ブログ
無料プレゼント

無料PDF: Claude Code はじめてのチートシート

まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。

スパムは送りません。登録情報は厳重に管理します。

Claude Codeを仕事で使える形にしませんか?

無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。

Masa

この記事を書いた人

Masa

現役DX室長|Claude Code でゼロから多言語AI技術メディア運営中。実務直結の自動化、AI開発相談・研修受付中。

PR

関連書籍・参考図書

この記事のテーマに関連する書籍を楽天ブックスで探せます。

※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。