本文へスキップ
TYP create

noteの新着記事をWebサイトに自動で出す方法

Web

noteで記事を書いたら、自分のサイトの「最新のnote記事」欄にも、自動で出したい。noteにはRSSがあるので、仕組みさえ作れば更新作業なしで実現できます。この記事では、noteのRSSをサーバーのcronで定期的に取得し、軽いJSONにして保存し、サイトのJavaScriptで読み込んで表示する方法を、そのまま使えるコードつきで解説します。PHPを使わず、XMLのまま保存して読み込む方法も紹介します。


先に結論:RSSは直接は読めないので、一度サーバーで取り込む

  • noteの公式ヘルプにも、直接は埋め込めないと書かれています:RSSを自分のサイトに載せるには、一度サーバー上で取り込む必要があり、直接埋め込むことはできません。
  • 全体の流れ:noteのRSS → サーバーのPHPで取得 → JSONファイルに保存 → ブラウザのJavaScriptで読み込んで表示。PHPを使わず、XMLのまま保存してJavaScriptで読む方法もあります。
  • 定期実行には2つの方法:レンタルサーバーのcron、またはWordPressのWP-Cron。確実に動かしたいならサーバーのcronです。

noteのRSSでできること・できないこと

noteのRSSは、記事の見出し画像、投稿日、タイトル、記事の冒頭の一部などを配信するXMLのデータです。noteの公式ヘルプでは、次の2種類が案内されています。

種類配信される内容件数
RSS(クリエイター)最新の更新情報最新の25件(note proで独自ドメインを適用している場合は50件)
マガジンRSSマガジンの更新情報(事前にマガジンの作成が必要)25件(note proで独自ドメインの場合は50件)

RSSのURLは、公式ヘルプによると、クリエイターページやマガジンのトップページにある赤丸のボタンから取得できます。URLは、必ずご自身の画面で確認したものを使ってください。

また、公式ヘルプには、RSS(XML)をカスタマイズした場合は、読み込み後の動作は保証の対象外になるとも書かれています。サーバーで取り込む仕組みはご自身で用意する必要があり、この場合も動作保証の対象外と案内されています。この記事のように、自分のサーバーで取り込んで加工する使い方は、この点を理解したうえで使うものです。

この記事は、ご自身のnoteの更新情報を、ご自身のサイトに載せる使い方を前提にしています。他の人のアカウントのRSSを載せる場合は、権利や利用条件を別に確認してください。

全体の流れ

順番どこで何をする
1サーバー(cron)決まった間隔で、PHPのスクリプトを実行する
2サーバー(PHP)noteのRSSを取得して、必要な項目だけのJSONにして保存する
3ブラウザ(JavaScript)自分のサイト内のJSONを読み込んで、HTMLにして表示する

ブラウザからは、自分のサイトの中にあるJSONファイルを読むだけです。noteのサーバーに毎回アクセスしないので、表示が速く、noteの側に負荷もかけません。外部のサイトを直接読むわけではないため、ブラウザの制限(CORS)の問題も起きません。

手順1:PHPでRSSを取得してJSONにする

次のスクリプトを note-feed.php として、サーバーに置きます。公開フォルダの外(ホームディレクトリの直下など)に置くと、外部から実行されずに済みます。

<?php
// note-feed.php : noteのRSSを取得して、軽いJSONにして保存する
date_default_timezone_set('Asia/Tokyo');                    // 日付のずれ防止
$feedUrl = 'https://note.com/ユーザー名/rss';          // 自分のRSSのURL
$outFile = '/home/ユーザー名/サイトの公開フォルダ/wp-content/uploads/note-feed.json'; // 保存先
$limit   = 5;                                           // 表示する件数

// 1) RSSを取得(タイムアウト付き)
$ch = curl_init($feedUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT        => 15,
    CURLOPT_USERAGENT      => 'Mozilla/5.0 (compatible; MyNoteFeed/1.0)',
]);
$xml  = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($xml === false || $code !== 200) { exit(1); }        // 失敗したら、前回のJSONをそのまま残す

// 2) XMLを解析
libxml_use_internal_errors(true);
$rss = simplexml_load_string($xml);
if ($rss === false || !isset($rss->channel->item)) { exit(1); }

// 3) 必要な項目だけを取り出す
$items = [];
foreach ($rss->channel->item as $item) {
    $media = $item->children('http://search.yahoo.com/mrss/');
    $items[] = [
        'title' => (string) $item->title,
        'url'   => (string) $item->link,
        'date'  => date('Y-m-d', strtotime((string) $item->pubDate)),
        'image' => isset($media->thumbnail) ? (string) $media->thumbnail : '',
    ];
    if (count($items) >= $limit) { break; }
}
if (!$items) { exit(1); }                                // 0件のときは上書きしない

// 4) 一時ファイルに書いてから置き換える(読み込み中に壊れないように)
$json = json_encode($items, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$tmp  = $outFile . '.tmp';
if ($json === false || file_put_contents($tmp, $json) === false) { exit(1); }  // 書き込みに失敗したら置き換えない
rename($tmp, $outFile);

コードのポイント

  • 失敗したときは何も書き換えない:取得に失敗したときや、記事が0件のときは、前回のJSONをそのまま残します。noteの側が一時的に不調でも、サイトの表示は壊れません。
  • 一時ファイルに書いてから置き換える:ちょうど書き込み中にブラウザが読み込んでも、途中のファイルを読んでしまうことを防げます。
  • 画像の項目は、実際のRSSで確認する:サムネイルは、RSSの media:thumbnail を読む作りにしています。note公式のフィードには media の名前空間が宣言されていますが、記事ごとの画像がどの要素に入るかは、ご自身のRSSを開いて確認してください。画像を使わないなら、image の行は消して構いません。
  • 必要なもの:PHPの curl と SimpleXML が使えるサーバーが前提です。多くのレンタルサーバーで標準で使えます。

この流れは、ダミーのRSSを使って、JSONが期待どおりに作られることと、取得に失敗したときに前回のJSONが残ることを確認済みです。

手順2:cronで定期的に実行する

スクリプトを、決まった間隔で自動実行します。方法は2つあります。

サーバーのcronWordPressのWP-Cron
実行のきっかけ決めた時刻に、サーバーが実行サイトにアクセスがあったときに、予定を確認して実行
確実さアクセスがなくても動くアクセスが少ないと、実行が遅れる
設定する場所サーバーの管理画面(cron設定)テーマの functions.php など
おすすめ確実に更新したいときサーバーのcronが使えないとき

方法A:レンタルサーバーのcron

レンタルサーバーの管理画面には、たいていcronの設定画面があります。そこに、実行する時刻とコマンドを登録します。たとえば、毎時0分に実行する場合は、次のようになります。

0 * * * * /usr/bin/php /home/ユーザー名/note-feed.php

cronの書式は、左から「分・時・日・月・曜日・実行するコマンド」の順です。/usr/bin/php の部分は、サーバーによってPHPの場所が違います。各サーバーの案内に載っているPHPのパスに置き換えてください。noteの記事は頻繁には増えないので、1時間に1回で十分です。

方法B:WordPressのWP-Cron

cronの設定画面が使えないときは、WordPressの仕組みでも動かせます。次のコードを、子テーマの functions.php などに追加します。

// 毎時、noteのRSSを取得してJSONに保存する
add_action( 'init', function () {
	if ( ! wp_next_scheduled( 'my_note_feed_update' ) ) {
		wp_schedule_event( time(), 'hourly', 'my_note_feed_update' );
	}
} );

add_action( 'my_note_feed_update', function () {
	$res = wp_remote_get( 'https://note.com/ユーザー名/rss', array( 'timeout' => 15 ) );
	if ( is_wp_error( $res ) || 200 !== wp_remote_retrieve_response_code( $res ) ) {
		return;
	}
	libxml_use_internal_errors( true );
	$rss = simplexml_load_string( wp_remote_retrieve_body( $res ) );
	if ( false === $rss || ! isset( $rss->channel->item ) ) {
		return;
	}
	$items = array();
	foreach ( $rss->channel->item as $item ) {
		$items[] = array(
			'title' => (string) $item->title,
			'url'   => (string) $item->link,
			'date'  => wp_date( 'Y-m-d', strtotime( (string) $item->pubDate ) ),
		);
		if ( count( $items ) >= 5 ) {
			break;
		}
	}
	if ( $items ) {
		file_put_contents(
			WP_CONTENT_DIR . '/uploads/note-feed.json',
			wp_json_encode( $items, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES )
		);
	}
} );

wp_schedule_event() の繰り返しの指定には、hourly(1時間ごと)、twicedaily(1日2回)、daily(1日1回)などが使えます。同じ予定を何度も登録しないよう、wp_next_scheduled() で確認してから登録するのが、公式の案内にある基本の書き方です。あとでこの仕組みを使わなくなったときは、コードを消すだけでなく、wp_clear_scheduled_hook( 'my_note_feed_update' ); を一度実行して、登録した予定も解除しておきます。なお、このWP-Cron版のコードは、実際のWordPress上では動作を確認していません。使う前に、テスト環境などで試してください。

functions.php を編集する前には、バックアップを取っておくと安心です。WordPressの変更前に必ず取りたいバックアップも参考にしてください。

WP-Cronを、サーバーのcronで動かす方法

WP-Cronは、サイトにアクセスがあったときにしか動きません。WordPressの公式ドキュメントにも、アクセスがないと予定した時刻に実行されない場合があると書かれています。解決策として、公式は「WP-Cronを無効にして、サーバーのcronから wp-cron.php を呼び出す」方法を案内しています。

まず、wp-config.php に次の1行を追加して、アクセス時の自動実行を止めます。

define( 'DISABLE_WP_CRON', true );

そのうえで、サーバーのcronに、wp-cron.php を呼び出すコマンドを登録します。公式ドキュメントの例をもとにすると、次のようになります(URLは自分のサイトに置き換えます)。

*/15 * * * * wget --delete-after https://自分のサイト/wp-cron.php

この方法なら、アクセスの多少にかかわらず、15分おきにWordPressの予定が確認されます。WordPressの他の予約投稿なども、同じ仕組みで動くようになります。

手順3:JavaScriptで読み込んで表示する

表示したい場所に、次のHTMLを置きます。WordPressなら「カスタムHTML」ブロックやウィジェットに貼り付けます。

<div id="note-feed"></div>
<script src="/wp-content/themes/テーマ名/note-feed.js"></script>

note-feed.js は、次の内容です。テーマのフォルダなど、サイトから読める場所に置きます。

(function () {
  var box = document.getElementById('note-feed');
  if (!box) return;
  fetch('/wp-content/uploads/note-feed.json')
    .then(function (res) { return res.ok ? res.json() : []; })
    .then(function (items) {
      var ul = document.createElement('ul');
      items.forEach(function (it) {
        if (!/^https?:\/\//.test(it.url)) return;   // http・https以外のリンクは使わない
        var li = document.createElement('li');
        var a = document.createElement('a');
        a.href = it.url;
        a.textContent = it.title;   // textContentなので、タイトルにHTMLが入っていても実行されない
        a.target = '_blank';
        a.rel = 'noopener';
        var d = document.createElement('time');
        d.textContent = it.date + ' ';
        li.appendChild(d);
        li.appendChild(a);
        ul.appendChild(li);
      });
      box.appendChild(ul);
    })
    .catch(function () { /* 読み込めなかったときは何も出さない */ });
})();

このコードも、ダミーのJSONを使ってブラウザ上で動かし、日付つきのリンク一覧が表示され、リンクに rel="noopener" が付くこと、http・https 以外のリンクは表示されないことを確認しています。

安全に表示するために

タイトルをHTMLに直接差し込む書き方(innerHTML など)は避け、textContent で入れています。外部から取り込んだ文字をそのままHTMLにすると、悪意のあるタグが混ざったときに実行されてしまう恐れがあるためです。リンクの target="_blank" には、rel="noopener" を一緒に付けています。また、リンク先は http または https で始まるものだけを使い、それ以外の形式のURLは表示しません。

PHPなしで済ませる方法:XMLのままJavaScriptで読む

JSONに変換せず、noteのRSS(XML)をそのまま自分のサイトに保存して、JavaScriptで読む方法もあります。PHPのスクリプトは不要で、cronにcurlのコマンドを1行登録するだけで保存できます。保存先は自分のサイトの中なので、JSONの場合と同じく、ブラウザの制限(CORS)の問題は起きません。

XML版の手順1:cronでRSSをそのまま保存する

サーバーのcronに、次のコマンドを登録します(1行です)。curlのコマンドを使うので、WP-Cronではなくサーバーのcronで動かします。パスとURLは、自分のものに置き換えてください。

0 * * * * curl -fsSL --max-time 15 -A "Mozilla/5.0 (compatible; MyNoteFeed/1.0)" -o /home/ユーザー名/サイトの公開フォルダ/wp-content/uploads/note-feed.xml.tmp https://note.com/ユーザー名/rss && mv /home/ユーザー名/サイトの公開フォルダ/wp-content/uploads/note-feed.xml.tmp /home/ユーザー名/サイトの公開フォルダ/wp-content/uploads/note-feed.xml
  • -f:取得に失敗したとき(404などのエラー)に、ファイルを作らずにコマンドを失敗させます。
  • -sS:進行状況は表示せず、エラーのときだけメッセージを出します。
  • -L:転送(リダイレクト)があった場合に、転送先までたどって取得します。付けないと、転送のお知らせだけが保存されてしまうことがあります。
  • –max-time 15:15秒で打ち切ります。
  • -A:アクセス元の名前(User-Agent)を指定します。
  • && mv:取得が成功したときだけ、一時ファイル(.tmp)を本番のファイルに置き換えます。失敗したときは、前回のファイルがそのまま残ります。

curlが使えないサーバーでは、ほかの取得コマンドを使うことになります。サーバーの案内を確認してください。

XML版の手順2:JavaScriptでXMLを読み込んで表示する

HTMLは、JSON版と同じものを使います。読み込むJavaScriptのファイル名だけ、note-feed-xml.js に変えます。

<div id="note-feed"></div>
<script src="/wp-content/themes/テーマ名/note-feed-xml.js"></script>

note-feed-xml.js は、次の内容です。

(function () {
  var box = document.getElementById('note-feed');
  if (!box) return;
  fetch('/wp-content/uploads/note-feed.xml')
    .then(function (res) { return res.ok ? res.text() : ''; })
    .then(function (text) {
      if (!text) return;
      var doc = new DOMParser().parseFromString(text, 'application/xml');
      if (doc.querySelector('parsererror')) return;      // XMLとして読めないときは何も出さない
      var items = Array.prototype.slice.call(doc.querySelectorAll('item'), 0, 5);
      if (!items.length) return;
      var ul = document.createElement('ul');
      items.forEach(function (item) {
        var title = item.querySelector('title');
        var link = item.querySelector('link');
        var pub = item.querySelector('pubDate');
        if (!title || !link || !/^https?:\/\//.test(link.textContent)) return;
        var li = document.createElement('li');
        if (pub) {
          var d = document.createElement('time');
          var t = new Date(pub.textContent);
          if (!isNaN(t)) {
            d.textContent = t.toLocaleDateString('sv-SE', { timeZone: 'Asia/Tokyo' }) + ' ';
            li.appendChild(d);
          }
        }
        var a = document.createElement('a');
        a.href = link.textContent;
        a.textContent = title.textContent;
        a.target = '_blank';
        a.rel = 'noopener';
        li.appendChild(a);
        ul.appendChild(li);
      });
      box.appendChild(ul);
    })
    .catch(function () { /* 読み込めなかったときは何も出さない */ });
})();
  • DOMParser:ブラウザに標準で入っている、XMLを読み取る仕組みです。読み取った結果から、item(1記事)ごとにタイトル・リンク・投稿日を取り出しています。
  • 5件だけ表示:RSSには通常25件(note proで独自ドメインの場合は50件)が入っているので、先頭の5件だけを使っています。
  • 安全のための処理:タイトルは textContent で入れ、リンクは http または https で始まるものだけを使います。
  • 日付:pubDate を日本時間の「2026-08-31」の形にしています。

このコマンドとJavaScriptは、ダミーのRSSを使って、次の動きを確認済みです。取得が成功したときにファイルが保存されること、取得が失敗したとき(404)に前回のファイルが残ること、日付つきのリンク一覧が表示されること、XMLが壊れているときは何も表示されないこと。実際のnoteのRSSでは確認していません。

JSON版とXML版の違い

JSON版XML版
PHPのスクリプト必要不要(cronのコマンドだけ)
保存されるデータ必要な5件・必要な項目だけRSSそのまま(通常25件、記事の冒頭の一部も含む)
ファイルの大きさ小さい大きめ
取得に失敗したとき前回のファイルが残る前回のファイルが残る(curlの -f と && を付けた場合)
RSSが0件・中身が壊れていたとき上書きしない(前回のファイルが残る)上書きされる(JavaScript側で何も表示しない)
定期実行の方法サーバーのcron、またはWP-Cronサーバーのcronのみ
向いている人軽さと安全さを重視したいとにかく手軽に済ませたい

JavaScriptを使わない方法:PHPで直接表示する

表示だけならJavaScriptは必須ではありません。WordPressには、RSSを取得するための fetch_feed() という関数があります。取得した結果はキャッシュされ、既定では12時間保持されます。保持する時間は、wp_feed_cache_transient_lifetime というフィルターで変更できます。

テーマのテンプレートから fetch_feed() を呼べば、cronを設定せずに、PHPだけでHTMLを出力できます。ただし、キャッシュが切れたあとの最初の訪問者の表示が、RSSの取得のぶん遅くなります。表示の速さを優先するなら、この記事のようにJSONに保存しておく方法が向いています。

うまく動かないときの確認ポイント

  • XML版で表示されない:保存されたXMLのURL(/wp-content/uploads/note-feed.xml)をブラウザで直接開いて、中身が入っているか確認します。404になる場合は、cronのコマンドか保存先のパスが間違っています。cronの実行結果をメールで受け取る設定にしておくと、curlのエラーメッセージを確認できます。
  • JSONが作られない:RSSのURLが正しいか、ブラウザでRSSのURLを開いて確認します。RSSに記事が1件も入っていない場合、この記事のスクリプトはJSONを作りません(前回のJSONが残ります)。
  • cronは動いているのにJSONが更新されない:保存先のフォルダに、書き込み権限があるか確認します。cronの実行結果をメールで受け取る設定や、ログ出力を有効にすると、原因が見つけやすくなります。
  • JSONを開くと日本語が \uXXXX の形で見える:JSON_UNESCAPED_UNICODE を付けない場合の正しい書き方で、JavaScriptの res.json() が読み込むときに元の日本語に戻るため、表示には影響しません。このスクリプトでは付けているので、日本語のまま保存されます。
  • 表示が古いまま:ブラウザやサーバーのキャッシュが残っていることがあります。JSON(XML版ならXML)のURLを直接開いて、更新されているか確認します。
  • PHPのパスが分からない:cronに登録するPHPのパスは、サーバーごとに違います。各サーバーのマニュアルで確認してください。

よくある質問

RSSをJavaScriptで、ブラウザから直接読めませんか?

noteの公式ヘルプには、RSSを直接埋め込むことはできず、一度サーバー上で取り込む必要があると書かれています。この記事の方法は、その案内に沿ったものです。

JSONにしなくても、XMLのままで読めますか?

読めます。cronのcurlでRSSをそのまま保存し、JavaScriptのDOMParserで読み込む方法です。PHPが要らない代わりに、保存されるデータが大きく、RSSが0件のときも上書きされます。詳しくは「PHPなしで済ませる方法」の項目を見てください。

cronの実行間隔は、どのくらいがよいですか?

noteの更新はそれほど頻繁ではないので、1時間に1回で十分です。短くしすぎると、noteのサーバーに負荷をかけるだけなので、避けましょう。

マガジンの更新情報だけを表示できますか?

できます。noteには、マガジンの更新情報だけを配信する「マガジンRSS」があります。マガジンのトップページで取得できるRSSのURLを、スクリプトの $feedUrl(XML版ならcronのコマンドのURL)に入れてください。

表示できる記事の数に上限はありますか?

RSSに含まれるのは、最新の25件です(note proで独自ドメインを適用している場合は50件)。それより古い記事は、RSSからは取得できません。

※出典:note ヘルプセンター(RSS機能、サイトに貼る機能の案内)、WordPress公式ドキュメント(WP-Cron、wp_schedule_event()、fetch_feed())。仕様は変更される場合があります。

まとめ

noteのRSSは直接は読めないので、サーバーのcronで取得してJSONにし、JavaScriptで表示するのが、確実で軽い方法です。cronが使えるならサーバーのcron、使えないならWP-Cronで定期実行できます。PHPを使いたくない場合は、cronのcurlでXMLをそのまま保存し、JavaScriptで読む方法もあります。どちらの場合も、保存は取得に失敗したときに前回の内容を残す作りにしておくと、noteの側が不調でも、サイトの表示は崩れません。