Steamer Lane Studio技術備忘録ユーティリティ

複数のRSSフィードを纏めて一つのRSSフィードで出力

utility 複数のRSSフィードを纏めて一つのRSSフィードで出力
作成日: 2024年3月21日

普通使わないな。
複数サイトを運営する企業のFacebookページではiftttアプリ使ってfeedから自動投稿されるように組んでいるが、サイト毎にiftttを使うと無料アカウントではiftttアカウントが複数必要になり管理が面倒。
実際気付いたらいくつかのアカウントでFacebookへの接続が切れていたが、そのロジックを探って修正するよりFBへの投稿は1か所からにした方が管理しやすいことから、複数の外部サイトのfeedを拾って日付順に纏めるrssをphpで組んだ。

<?php
// ヘッダーを設定してRSSフィードであることをブラウザに伝える
header('Content-Type: application/rss+xml; charset=utf-8');
// RSSフィードの開始タグを出力
echo '<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>' . PHP_EOL;
echo '<channel>' . PHP_EOL;
echo '<title>フィードタイトルを手書き</title>' . PHP_EOL;echo '<link>URLを手書き</link>' .PHP_EOL;
echo '<description>フィードのdescription</description>' .PHP_EOL;
echo '<atom:link href="https://rssファイルのパス/rss.php" rel="self" type="application/rss+xml" />' . PHP_EOL;echo '<language>ja</language>' .PHP_EOL;
function fetch_feed($url) {
    $rss = simplexml_load_file($url);
    return $rss;
}
function combine_feeds($feed_urls) {
    $combined_entries = [];
    foreach ($feed_urls as $feed_url) {
        $feed = fetch_feed($feed_url);
        foreach ($feed->channel->item as $item) {
            $combined_entries[] = $item;
        }
    }
    // 日付でソート
    usort($combined_entries, function($a, $b) {
        return strtotime($b->pubDate) - strtotime($a->pubDate);
    });
    return $combined_entries;
}
// 取得したいRSSフィードのURLを配列に指定
$feed_urls = array(
    'https://a.com/feed',
    'https://b.com/feed',
);
$combined_entries = combine_feeds($feed_urls);
// 各エントリーの情報を表示
foreach ($combined_entries as $entry) {
    echo '<item>' . PHP_EOL;
    echo "<title>{$entry->title}</title>" . PHP_EOL;
    echo "<pubDate>{$entry->pubDate}</pubDate>" . PHP_EOL;
    echo "<link>{$entry->link}</link>" . PHP_EOL;
    // descriptionをCDATAセクションで囲む
    echo "<description><![CDATA[{$entry->description}]]></description>" . PHP_EOL;
    echo "<content:encoded><![CDATA[{$entry->children('content', true)->encoded}]]></content:encoded>" . PHP_EOL;
    echo '</item>' . PHP_EOL;
}
// フィードの終了タグを出力
echo '</channel>' . PHP_EOL;
echo '</rss>' . PHP_EOL;
?>
これで複数のフィードを拾い纏めてiftttのアップレットでFacebook投稿ができる。