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

複数サイトのfeedをひとまとめにする

utility 複数サイトのfeedをひとまとめにする
作成日: 2024年6月16日

滅多に使わないだろうが、複数サイトのFeedをひとまとめにするphp。
実際用いたのはFacebookPAGEへの自動投稿をIFTTTで行っていたが、無料版のIFTTTではアップレットが2つまでしか使えないので管理を簡易にするためにFeedをひとまとめにしてアップレット一つで自動投稿するものを考えた。

<?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;// feed title等を手入力、スクレイピングよか早いので初期直書きecho '<title>YOUR_TITLE</title>' . PHP_EOL;echo '<link>https://表示したいURL.com</link>' . PHP_EOL;echo '<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://サイト1URL/feed','https://サイト2URL/feed','https://サイト3URL/feed','https://サイト4URL/feed',
// 他のRSSフィードのURLも追加可能);

$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;echo "<guid>{$entry->guid}</guid>" . PHP_EOL;

// descriptionを100文字に制限してCDATAセクションで囲む$description = $entry->description;if (strlen($description) > 100) {$description = mb_substr($description, 0, 100) . '...'; // 100文字に制限し、続きがあることを示す}echo "<description><![CDATA[{$description}]]></description>" . PHP_EOL;// content:encodedを取得し、iframeおよびscriptタグを削除$content_encoded = $entry->children('content', true)->encoded;$content_encoded = preg_replace(array('/<iframe.*?<\/iframe>/is', '/<p><script.*?<\/script>/is', '/<script.*?<\/script>/is'), '', $content_encoded);//ここは出力される内容からエラーになる部分を削除、任意で変えるecho "<content:encoded><![CDATA[{$content_encoded}]]></content:encoded>" . PHP_EOL;echo '</item>' . PHP_EOL;}

// フィードの終了タグを出力echo '</channel>' . PHP_EOL;echo '</rss>' . PHP_EOL;?>

これを任意にディレクトリに置けばOK。
WPの場合は今更だがautoPとかでエラーになる場合があるから注意。validatorでのチェックをお忘れなく。
それとたまにIFTTTのactivityを確認して稼働状態もチェックするのがベター。