RSSジェネレータを作った

こんな感じにいろいろできました。InstagramとTwitterはdisneyとかnasaとかを書き換えたら、公開アカウントはぜんぶ取得できます。

追記: AtCoder向け以外はちゃんと動作しません。

技術的なこと

やっていることはただのスクレイピングですが、インフラまわりを避けたかったので、サーバレスで構築しました。

firebaseは何度か使ったことがありますが、Node.jsでスクレイピングは重たすぎるので却下しました。(外部へのリクエストが有料なのも厳しい)

最近はまっているRustでできないかと思ったところ、WebAssemblyをサーバ側で動かせるCloudflare Workersを見つけたので、使ってみました。(外部へのリクエストが無料なのも◎)

Rustインストール済みの環境では、下のコマンドでテンプレートプロジェクトが出来上がります。

$ cargo install wrangler
$ wrangler generate myapp https://github.com/cloudflare/rustwasm-worker-template/

WebAssemblyを使うときは、JavaScriptから呼び出すようになっているようで、最初は以下のようなコードが用意されています。(いくつか変えています)

// 1. リクエストを処理するFetchEventリスナーを登録
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
})

// 2. リクエストに応じて処理
async function handleRequest(request) {
  // WebAssemblyから関数をインポート
  const { greet } = wasm_bindgen;
  await wasm_bindgen(wasm);

  // いろいろする関数
  const greeting = greet();

  // Responseオブジェクトを返す
  return new Response(greeting, {status: 200});
}

Cloudflare Workersを使うのは初めてでしたが、仕様にあまり癖がなく、ドキュメントもしっかりしていたので、それほど困ることはありませんでした。

ちなみに、WebAssemblyで調べると、データのやり取りに整数と小数しか使えないとか書いてある記事もありますが、Cloudflare Workersではwasm-bindgenが文字列もやり取りできるようにしているので安心です。

また、外部との通信がしたい場合は、イベントリスナー内でFetch APIを使うと、簡単にできました。(まだ試していませんが、WebAssemblyからFetch APIを叩くことも、多分できると思います…)

const res = await fetch("https://example.com/");
if (res.ok) { 
  console.log(await res.text());
}

今回は、なぜか知られていないCloudflare WorkersでRSSジェネレータを作ってみましたが、ドメインも要らず、一日10万リクエストまで可という太っ腹だったので、これからも使っていこうと思います。

今回書いたコードはGitHubにあるので、こちらもどうぞ。

参考リンク