それでもはてなブログを自分のホームページに埋め込みたい
2021/1/31に、CORS制限回避のために使っていた https://github.com/Rob--W/cors-anywhere が悪用が多すぎるために利用を制限したようです。 ※教えてくださった読者さんありがとうございます
この関係で、前回の方法ではRSSの取得ができなくなってしまいました。 t-n-clark.hatenadiary.jp
下記記事にも書かれている通り、本来、フロントエンドから直接外部サービスのAPIを呼ぶのは邪道であって、自前でAPIを立てるのが正攻法のようです。 medium.com career.levtech.jp
そこで、はてなブログのAPIを叩くバックエンドのAPIを用意して、それをフロントエンドから呼びに行くようにすることにしました。
※ちなみにフロントエンド(React)から直接はてブのAPIを呼び出そうともしてみましたが、同じくCORSエラーに遭遇しました。 そりゃそうですよね。
APIはGCPやAWS、Herokuなど好きな場所に立てればいいのですが、サーバの管理が不要でデプロイが簡単なGoogle Apps Script(以下、GAS)で作ることにしました。
※GASの使い方などについては、さまざまな記事で紹介されているので、ここでは割愛します。
はてブのAPIは使用用途別にいろいろな種類が用意されているので、用途に合ったものを選択します。 developer.hatena.ne.jp 使用する際は、利用規約に気を付けましょう。 developer.hatena.ne.jp
今回はお試しなので、一番認証が簡単なBasic認証を選びました。 developer.hatena.ne.jp
Basic認証はDeveloper登録不要で使えます。
より強力なセキュリティ認証であるOAuth認証を使う場合はDeveloper登録が必要です。 登録方法は下記を参考にしてください。 developer.hatena.ne.jp
Basic認証のAPIキーはブログの管理画面から調べられます。 合わせてルートエンドポイントも確認しておきます。 http://blog.hatena.ne.jp/my/config/detail
はてブAPIの使い方がわかったので、続いて、GASではてブAPIを叩いて必要情報を返却する自前APIの実装をしていきます。
GASから取得するサンプルはこの記事が参考になります。
といってもただ単純にfetch
しているだけです。
www.kotanin0.work
取得結果の細かい仕様は下記の記事が参考になります。 korosuke613.hatenablog.com
例えば、こんな感じで取ってこれます。
your_root_endpoint
とyour_api_key
のところには先ほど管理画面で確認したルートエンドポイントとAPIキーが入ります。
function fetchHatenaFeeds() { const url = "your_root_endpoint/entry"; const username = "your_username" const apiKey = "your_api_key" const options = { "method": "GET", 'headers' : {'Authorization' : 'Basic ' + Utilities.base64Encode(username + ':' + apiKey)} } var xml = UrlFetchApp.fetch(url,options).getContentText(); return xml; }
変数名からわかるようにはてブAPIから取得できる情報はXML形式になっています。 このままだと扱いにくいので、必要な情報だけ抜き出しでJSON形式に変換してしまいましょう。
function parseXmlContent(xml){ var contentList = []; var entries = xmlToJson(xml).feed.entry; entries.map((entry)=>{ if(entry.control.draft.Text === "no"){ contentList.push({ "title": entry.title.Text, "pubDate": entry.published.Text, "link": entry.link[1].href, }) } }) return contentList }
こんな感じでxmlToJson()
でエントリーを変換して、所望のカラムを取り出して連想配列に格納します。
この例では、
title
pubDate
link
を最終的に返す仕様になっています。
xmlToJson()
の中身は以下の通りです。
こちらのサンプルコードをそのまま使わせてもらいます。
gist.github.com
データ取得~返却用の連想配列に変換までの流れをまとめて1つの関数にしてしまいましょう。
function getHatenaFeeds(){ var xml = fetchHatenaFeeds(); var contentList = parseXmlContent(xml); return contentList; }
最後にGETリクエストの受け付け関数を用意します。
GASの場合はdoGet
という名前の関数がエンドポイントになります。
GASではあらかじめ登録された名前の関数を作ることで、 イベントをトリガーにスクリプトを実行できる シンプルトリガーという仕組みがあります。
今回の場合は、フロントエンドからのGETリクエストがイベントになります。
上記で作ったgetHatenaFeeds()
で取得した情報をJSON形式に変換して返しています。
function doGet(e){ var data = getHatenaFeeds(); var payload = JSON.stringify(data); var output = ContentService.createTextOutput(); output.setMimeType(ContentService.MimeType.JSON); output.setContent(payload); return output; }
これら一連のスクリプトをデプロイして公開すれば、自分のはてブのRSS情報が取得できるAPIが完成です。
あとは、前回の実装でRSSParserを使っていたところをaxiosに取り替えてやれば、OKです。
前回
urls.map((url) => { rssParser.parseURL(url) .then((feed) => { // 新たに取得したfeedを取り出す
今回
urls.map((url) => { axios.get(url) .then((feed) => { // 新たに取得したfeedを取り出す
これで同じ状態に復旧できました。やった~!
※ホームページお引越ししました。 sashimimochi.netlify.app