はじめに
MLB(メジャー・リーグ・ベースボール)の試合日程をGoogleカレンダー・Appleカレンダーに自動同期するWebアプリを作成しました。
その感想を書いていきます。
開発理由
最近、大谷翔平選手の所属するドジャースの試合にめちゃくちゃどハマりしています!
ただ、毎日のように試合開始時間や大谷選手らの先発日を検索して確認するのが地味に手間でした…。
「カレンダーに自動同期されたらめちゃくちゃ楽なのに」と思い、既存のスポーツアプリや公式カレンダーも探してみたのですが、以下のような不満がありました。
- ほとんどカレンダー連携対応していない
- 連携できたとしても「大谷翔平選手や山本由伸選手の先発日だけ」を絞り込んで登録できない
「ないなら自分で作ってしまおう!」ということで、普段使っているGoogleカレンダーやiPhoneカレンダーに試合予定を自動同期できるWebアプリ 「SportsCal Sync」 を開発しました!
作成したアプリの概要
できること
- ドジャース全試合の試合日程・放送情報をカレンダーに同期
- 大谷翔平・山本由伸・佐々木朗希(ドジャース所属日本人投手)の先発予定のみを絞り込んでカレンダーに同期
- GoogleカレンダーおよびAppleカレンダー(iPhone / Mac)に対応
- 一度登録すれば、日程変更・追加が自動でカレンダーに反映される(手動更新不要)
⚾ SportsCal Sync(アプリはこちら)↓
使い方
Step 1: 同期したい対象を選ぶ
- 複数同時には選べないので、追加したい対象ごとに1つずつ登録します
Step 2: 試合プレビューで内容を確認する
- 選んだ対象に応じて、カレンダーに追加される試合一覧が表示されます
- リストは自動的に「今日の試合」付近にスクロールされるので、現在の登録内容を確認しやすくなっています
Step 3: カレンダーに同期する
- デバイスに合わせて選択します
Googleカレンダーに同期する場合(Android / PC)
- モーダルが開きます
- 表示された手順に沿って同期を開始します
GoogleカレンダーアプリはスマートフォンではURLからのカレンダー追加に対応していません。PCのブラウザから操作してください。
iPhone / Mac のカレンダーに追加する場合
- モーダルが開きます
- 表示された手順に沿って同期を開始します
登録後のカレンダーの見た目
Googleカレンダー
Appleカレンダー
それぞれ一度登録すると、以降は何もしなくてもカレンダーが自動更新されます。試合日程が変更・追加された場合も自動的に反映されます。
技術スタック
| 領域 | 技術 | 用途 |
|---|---|---|
| フロントエンド | React 19 + TypeScript + Vite | SPA構築 |
| UIコンポーネント | Chakra UI v3 | ダークテーマUI |
| バックエンド | Firebase Functions v2 | ICSファイルの動的生成 |
| ホスティング | Firebase Hosting | SPAの配信 + ICSルーティング |
| 外部API | MLB Stats API | 試合スケジュール・先発投手情報(無料・認証不要) |
| CI/CD | GitHub Actions | mainマージで本番自動デプロイ、PRプレビュー環境の自動生成 |
カレンダーが「自動更新」される仕組み
このアプリの核心部分なので、iCalendarの仕組みを少し説明します。
iCalendar(.ics)とは
iCalendar(.ics形式)はRFC 5545で定められたカレンダーデータの標準フォーマットです。Google Calendar・Apple Calendar・Outlookなど主要カレンダーアプリがすべて対応しています。
カレンダーアプリにURLを登録すると、カレンダーアプリ側が定期的にそのURLへアクセスして最新データを自動取得し続けます。サーバー側がプッシュするのではなく、カレンダーアプリ側がプルする仕組みです。
BEGIN:VCALENDAR
VERSION:2.0
REFRESH-INTERVAL;VALUE=DURATION:PT6H ← 「6時間ごとに更新してください」という指示
X-WR-CALNAME:ドジャース 試合日程
X-APPLE-CALENDAR-COLOR:#005A9C
BEGIN:VEVENT
UID:mlb-123456@sportscal-sync.com
DTSTART:20260407T021000Z
DTEND:20260407T051000Z
SUMMARY:ドジャース vs ヤンキース
LOCATION:Dodger Stadium
DESCRIPTION:放送: NHK-BS
END:VEVENT
END:VCALENDAR
REFRESH-INTERVAL;VALUE=DURATION:PT6H がポイントです。これはRFC 7986で定義されたプロパティで、「6時間ごとにこのURLを再取得してください」とカレンダーアプリへ指示します。これによりユーザーは何もしなくてもカレンダーが更新され続けます。
Firebase HostingのリライトでICSエンドポイントを実現する
このアプリでは firebase.json のURLリライト機能を使い、/ical/dodgers.ics というURLへのアクセスをFirebase Functions(サーバー側で処理を実行できるサービス)に転送しています。
{
"hosting": {
"rewrites": [
{ "source": "/ical/dodgers.ics", "function": "icalFeed" },
{ "source": "/ical/ohtani.ics", "function": "icalOhtaniFeed" },
{ "source": "/ical/yamamoto.ics", "function": "icalYamamotoFeed" },
{ "source": "/ical/sasaki.ics", "function": "icalSasakiFeed" }
]
}
}
カレンダーアプリがアクセスするたびにFunctionsがMLB APIから最新データを取得してICSを動的に生成して返します。これが「自動更新」の正体です。
大変だったこと・工夫したこと
初めてのiCalendar実装
今回、iCalendar(.ics)を扱うのは初めてだったため、仕様や実装方法の調査には少し苦労しました。
単純に.icsファイルを生成すればよいわけではなく、カレンダーをURLで「購読」してもらう仕組みや、Google Calendar / Apple Calendarでの登録方法の違い、更新がどのタイミングで反映されるのかなど、実際に調べてみて初めて分かることが多くありました。
初めて扱う技術でも、まず仕組みを理解してから「今回の要件ではどこまで必要なのか」を整理して実装することの大切さを学びました!
MVP(実用最小限)として必要な機能に絞る
今回は最速で価値を届けるため、MVP構成を徹底的に意識しました。現段階ではユーザーログイン機能やデータベース管理などは不要と判断し、徹底的に機能を削ぎ落としています。結果として保守コストを抑えつつ、シンプルな構成でリリースまで持っていくことができました!
事前設計と実装における柔軟な方向転換をする
実装に入る前に、UI設計、ユースケース定義、ドメイン設計、API設計、ディレクトリ構成までしっかり落とし込んでから開発を進めました。
ですが、実際に手を動かしていく中で「この設計よりも、こちらのアーキテクチャやデータフローの方がユーザー体験(UX)や保守性が上がる」と気づく場面が何度もありました。初期設計に固執しすぎず、実装段階での気づきに合わせて柔軟にリファクタリングを重ねたことも良い学びになりました!
おわりに
今、AIが発展して開発の効率化できる一方で、
「どの技術を選ぶのか」「どのような設計にするのか」「AIが提案した実装が本当に適切なのか」 を判断する力は、これまで以上に重要になると思っています。
自分自身が技術や設計を理解したうえで、状況に応じて適切な判断ができるよう、今後も知識と経験を積み重ねていきます!また、今回得たiCalendarやFirebase、設計・技術選定に関する学びも、今後の開発にも活かしていきたいと思います!
参考
- ChakraUI 公式ドキュメント
- Cloud Functions公式ドキュメント
- その他参考記事
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼









