Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】I built a 176-country trends aggregator that runs entirely on GitHub Actions

2026年11月04日に「Dev.to」が公開したITニュース「I built a 176-country trends aggregator that runs entirely on GitHub Actions」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

GitHub Actionsを使い、サーバーなしで176カ国のトレンド情報を集約するツールを構築した。開発では、アクセス制限、意図しない404、セキュリティ設定による分析ブロックなど多様な課題を解決。サーバーレス環境でのシステム構築の注意点や具体的な解決策を実践的に学んだ事例だ。

ITニュース解説

このニュース記事は、世界中の検索トレンドを集約するWebサイトを、サーバーを一切持たずに構築した開発者の体験談について解説している。具体的には、GitHub ActionsとCloudflare Pagesという二つのサービスを組み合わせることで、VPS(仮想プライベートサーバー)やコンテナ、常に稼働し続けるマシンといった一般的なサーバーを必要としない「サーバーレス」なシステムを実現した点が特徴的だ。開発の動機は、別の国のトレンドを知りたいときに、地域ブロックに遭遇したり、機械翻訳されたニュースサイトを読まなければならなかったりする不便さを解消したいというものだった。自分が開発したツールは、176の国と地域からトレンドトピックを収集し、それらを一つの地図上に表示する。各トピックは元の情報源へのリンクが貼られている。開発者は「もし何かを常に稼働させておく必要があるなら、いずれは維持を止めてしまうだろう」と考え、サーバーレスという制約を自らに課した。

システム全体の構造はシンプルだ。まず、GitHub Actionsというサービスが、設定したスケジュール(この場合は3時間ごと)で自動的に処理を実行する。このGitHub ActionsがNode.jsで書かれたクローラーツールを実行する。クローラーは、Google Trendsなどから176カ国分のトレンドデータを収集し、約90秒かけて処理する。収集したデータは、静的なJSONファイルとして合計約2.7MBにまとめられる。その後、この静的なJSONファイルとWebサイトのHTMLファイルが、wrangler pages deployというコマンドを使ってCloudflare Pagesにデプロイされる。Cloudflare Pagesは、デプロイされたHTMLやJSONといった静的なファイルを高速に配信するサービスだ。これにより、ユーザーがWebサイトにアクセスすると、Cloudflare PagesがHTMLとJSONを提供し、ブラウザ側で地図上にトレンドが表示される仕組みになっている。クローラーは依存ライブラリをほとんど使わず、非常にシンプルなNode.jsスクリプトで、フロントエンドもVanilla JS(特定のフレームワークを使わない純粋なJavaScript)で動作し、地図もGeoJSONファイルからSVGで描画されるため、余計な外部サービスに依存しない設計になっている。データ量も小さく、サーバーを持たないという判断は妥当だった。

開発の過程では、いくつかの予期せぬ問題に直面し、その解決策が語られている。 一つ目の問題は、Googleからのアクセス制限だ。Google Trendsは国ごとに日次のトレンドRSSフィードを提供しているが、短時間に多くのリクエストを送信すると、Googleから「リクエストが多すぎるので少し待ってください」という警告(302リダイレクトによる/sorry/indexへの誘導)が表示され、データ取得ができなくなることが判明した。開発者は、同時に実行するリクエスト数を3つに制限し、リクエスト間に260〜480ミリ秒のランダムな遅延(ジッター)を入れることで、この問題を回避した。さらに、302リダイレクトが返された場合にはすぐに諦めず、短い時間でリトライする処理を追加した。結果として、176カ国すべてのデータを90秒程度でエラーなく取得できるようになった。興味深いことに、自宅の回線と比べて、データセンターのIPアドレスを持つGitHub Actionsの実行環境からでも同じように動作し、特別なプロキシ対策は必要なかったという。API連携を行う際、事前に測定せずに特定のネットワークからのアクセスがブロックされると思い込むべきではないという教訓が得られた。

二つ目の問題は、Cloudflare Pagesにおける「ソフト404」という現象だ。Webサイト上に存在しないURLにアクセスした場合、通常は「404 Not Found」というエラーページが表示されるべきだが、Cloudflare Pagesでは、ルートにindex.htmlがあり、かつ404.htmlがない場合、存在しないパスへのアクセスに対してもホームページの内容をHTTPステータスコード200 OKで返してしまうことがあった。これは見た目上はページが表示されるため問題がないように見えるが、実際には深刻な影響を及ぼす。例えば、検索エンジンは無限に存在する異なるURLを重複コンテンツとして扱ってしまう可能性があり、本来存在しないページが「発見された」と報告され、デバッグも困難になる。この問題は、public/404.htmlというファイルを明示的に作成しデプロイすることで解決された。これにより、存在しないパスへのアクセスは適切に404エラーを返すようになった。

三つ目の問題は、Cloudflare Pagesの「クリーンURL」機能がGoogle Search Consoleのサイト認証を妨げたことだ。Google Search ConsoleでWebサイトを認証する方法の一つに、特定の名前のHTMLファイルをWebサイトのルートに置き、そこから特定のテキストが200 OKで返されることを確認するというものがある。しかし、Cloudflare Pagesは.htmlで終わるURLを自動的に拡張子のないパスにリダイレクトしてしまう仕様があった(例: /googleXXXX.htmlが/googleXXXXに308リダイレクトされる)。Googleの認証システムがこのリダイレクトを追跡するかどうかは不確かであり、「ファイルが見つからない」という曖昧なエラーの原因となっていた。開発者は、_redirectsファイルにリライトルールを追加し、特定のHTMLファイルへのアクセスに対してはリダイレクトせずに200 OKでファイルの内容を返すように設定することで、この問題を回避した。ただし、最終的には、ホームページのHTMLに特定の<meta>タグを埋め込むことで認証する別の方法に切り替え、この問題から解放された。

四つ目の問題は、Content-Security-Policy(CSP)というセキュリティ設定が、Webサイトのアクセス解析ツールの動作を阻害したことだ。開発者はCloudflare Web Analyticsを有効にしたが、ダッシュボードには何もデータが表示されなかった。原因は、以前設定していたCSPヘッダーにあった。CSPは、Webサイトが読み込むスクリプトや接続先を制限するセキュリティ機能だが、script-src 'self'(自サイトからのスクリプトのみ許可)とconnect-src 'self'(自サイトへの接続のみ許可)という設定では、Cloudflare Web Analyticsが利用するstatic.cloudflareinsights.comなどのドメインからのスクリプト読み込みやデータ送信がブロックされてしまっていたのだ。この問題を解決するには、CSPの設定にhttps://static.cloudflareinsights.comなどのドメインを明示的に許可する必要があった。この経験から、CSPはセキュリティ向上に有効だが、後から追加するサードパーティサービスはCSPの設定を再確認し、必要なドメインを許可しなければならないこと、そして問題が発生してもエラーが表示されずに「何も起こらない」というサイレントな失敗に陥りがちだという教訓が得られた。

もし次に同じようなシステムを構築するなら、開発者はいくつかの点を異なる方法で実装するだろうと述べている。一つは、データソースの多様性に関するものだ。176カ国のうちGoogle Trendsが利用できるのは122カ国で、残りはWikipediaのページビュー数やBing Newsなどを代替ソースとして利用している。これは、それぞれの国で「検索トレンド」と「ニュースの関心」が異なる情報源から来ていることを意味し、読者がラベルを無視して情報を解釈すると誤った結論を導きかねないため、データソースの違いをより明確に伝える必要があると感じた。もう一つは、Webサイトのルーティング方法に関する重大な反省点だ。当初、各国のトレンド表示を/#!/JPのようにハッシュルーティングで実装していた。これは、一つのURLで176カ国分のコンテンツを表示できるが、コンテンツがブラウザのJavaScriptによってクライアントサイドで描画されるため、JavaScriptを実行しないWebクローラー(検索エンジンのクローラーなど)にはコンテンツが全く見えないという問題があった。その結果、せっかくのコンテンツが検索エンジンにインデックスされず、Webサイトの価値が失われていた。この問題を解決するため、JSONデータを書き出す際に、同時に/country/us/や/country/jp/といった静的なHTMLページも生成するビルドステップを追加した。これにより、Webクローラーもコンテンツを直接読み取れるようになり、検索エンジンからの評価も改善される。これは、「ページの価値がそのコンテンツにあるのなら、クローラーにプログラムを実行させてコンテンツを読ませるべきではない」という普遍的な教訓を示している。

最後に、このデータ収集の過程で偶然発見された興味深い洞察についても触れている。集めたトレンドデータを国ごとに並べるだけでなく、ヘッドラインの類似性に基づいてクラスター(グループ)化してみたところ、同じニュースが複数の国で同時にトップトレンドになることが頻繁にあると判明した。例えば、あるNBAの試合が9カ国で同時期にトップトレンドになったり、西アフリカの5カ国でサッカーの試合が同時にトレンド入りしたりしたという。これは、「自分の国のトレンドフィードが世界について語っていると思っても、実際には自分自身について語っていることが多い」という示唆を与えている。開発者は、クラスタリングのロジックはあえてシンプルにし、類似しすぎるものを無理に統合しない方針をとった。これは、世界に関する主張として公開されるデータであるため、誤って統合してしまうよりも、統合不足の方が好ましいと考えたからだ。

このプロジェクト全体を通して、サーバーレスアーキテクチャの具体的な実現方法、外部APIとの連携における配慮、モダンなWeb開発で遭遇しうる落とし穴(ソフト404、CSPの問題など)とその解決策、そしてWebサイトの設計におけるSEOの重要性といった、システムエンジニアを目指す初心者にとって非常に実践的で貴重な学びが得られる内容となっている。特に、問題に直面した際の具体的なデバッグと解決のプロセスは、実践的な課題解決能力を養う上で参考になるだろう。

関連コンテンツ

関連IT用語

関連ITニュース