1. はじめに
Qiitaで、MLBの好きなチームによる試合日程をGoogleカレンダーやAppleカレンダーへ自動同期するWebアプリを開発した記事を見つけました。
この記事では、MLBの試合日程を API から取得し、iCalendar(ICS)形式でカレンダーへ連携する仕組みが紹介されています。特に、試合日程の変更・追加も自動的にカレンダーへ反映できる点が良いと思いました。
そこで、
「これ、私が好きなChelseaの試合日程でもやってみたい!」
と思い立ち、Chelsea 版について、自分で作ってみることにしました。
2. 完成形とシステム構成
今回作成するのは、Chelsea FC の試合情報を API から取得し、ICSファイルとして公開する仕組みです。
最終的には、下記のような構成で、football-data.orgか ら取得した Chelsea の試合情報を Apple カレンダーへ連携できるようにしています。
API を実行し Chelsea の試合情報を取得
↓
Python にて必要情報を整形
↓
chelsea.ics を作成
↓
GitHub Actions 実行
↓
GitHub Pages へ公開
↓
Apple カレンダーが chelsea.isc 取得
フットボールの試合は、シーズン開幕時点では日程が決まっていても、キックオフ時刻の変更や試合の延期などが発生することがあります。
このため、単純に試合日程をカレンダーへ手動登録するのではなく、
- 試合情報をAPIから取得する
- 取得した試合情報をカレンダー形式(ICS)へ変換する
- GitHub Actionsで定期的にICSを更新する
- GitHub PagesでICSを公開する
- AppleカレンダーからICSを購読する
という仕組みにすることで、できるだけ手間をかけずに最新の試合日程を確認できるようにしました。
この記事では、この仕組みを実際にどのように作ったのかを、APIからのデータ取得、ICSの生成、GitHub Actionsによる自動化、GitHub Pagesでの公開、Appleカレンダーでの購読まで順番に紹介します。
3. 今回の要件
今回、作成に当たって定義した要件は下記です。
必須
- 無料で作れる
私がお金を払いたいのは Chelsea であって、API提供業者ではないですからね()
なんだかんだ、ここは必須条件で作っていきます。
(単純に、お金払ってまで運用していく気はない点が大きなウェイトを占めています...)
優先度高め
-
Chelsea の全試合をカレンダーに埋め込む
26-27 シーズンにおける Chelsea は、下記の計3コンペティションに参加しています。- Premiere League
- FA Cup
- EFL Cup(Carabao Cup)
UEFA Champiosn League は今季参加していません(悲しい)。
......が、来年こそは参加できると信じて、UEFA Champiosn League も対象に含めます。
このため、これらの大会をできるだけ1つの仕組みで取得できることを、API選定における重要な条件としました。 -
試合時間の変更に対応できる
フットボールの試合日程は、最初に発表された日時から変更されることがあります。
特に、現時点では時間が確定していない TBD の試合についても、後から正式な日時が設定された場合に、カレンダー側へ反映できるようにしたいと考えています。
このため、単に一度試合日程を取得して終わりではなく、定期的に最新の試合情報を取得し、既存のカレンダー情報を更新できる仕組みを目指します。
4. API の調査と選定
要件が決まったので、次は「そもそもフットボールの試合日程を取得できるAPIがあるのか」を調べていきます。
今回必要なのは、少なくとも下記大会です。
- Premier League
- FA Cup
- EFL Cup(Carabao Cup)
- UEFA Champions League
さらに、
- 無料で利用できる
- 試合日程を取得できる
- 試合時間の変更を追従できる
といった条件も満たす必要があります。
そこで、いくつかのフットボール系APIを比較してみました。
4.1 APIの比較
今回調べたAPIは、主に以下です。
- football-data.org
- API-Football
- Sportmonks
- TheSportsDB
| API | 無料運用 | PL | FA Cup | EFL Cup | CL |
|---|---|---|---|---|---|
| football-data.org | ✅ | ✅ | ❌* | ❌* | ✅ |
| API-Football | ✅ | ✅ | ✅ | ✅ | ✅ |
| Sportmonks | ❌ | ✅ | ✅ | ✅ | ✅ |
| TheSportsDB | ✅ | ✅ | ✅ | ✅ | ✅ |
* football-data.orgは大会自体には対応していますが、現在の無料枠(Free Tier)の対象大会には FA Cup, EFL Cupが含まれていません。
https://www.football-data.org/coverage
<不採用>
API-Football
上記表を踏まえ、API-Football の無料プランを確認してみました。
すると、26/27シーズンへアクセスした際に、
Free plans do not have access to this season
となり、2026/27シーズンのデータを取得できませんでした。
今回の目的は、
「2026/27シーズンのChelseaの試合日程をカレンダー化する」
ことなので、ここは致命的でした。
このため、 API-Football は多機能であったものの、今回の目的である2026/27シーズンのデータを無料プランでは取得できない欠点があったため採用しませんでした。
TheSportsDB
次点で、要件似合いそうな TheSportsDB を調べてみました。
すると、今の公式仕様が、「無料版の取得制限が今回の用途に対してかなり厳しい」ことがわかりました。
特に、Free API(無料プラン)は下記の制限があります。
- 多くのAPIがFreeでは取得件数を制限
- eventsseason(シーズン全試合取得)は Free API では15件まで
- TeamのNext/Previous scheduleもFreeでは1件
上記から、Free API の取得件数制限が厳しいことがわかりました。
実際に今回の用途で取得を試したところ、FA CupやEFL CupについてChelseaの試合データを取得できなかったため、採用しませんを見送りました。
<採用>
football-data.org
これまでの調査結果から、今回は football-data.org を採用することにします。
football-data.org は、無料プランでも Premier League の2026/27シーズンの試合情報を取得でき、今回の目的である
「Chelseaの試合日程をICSとしてカレンダーへ連携する」
という用途を満たせることを確認できました。
FA Cup、EFL Cup については無料プランの対象外だったため、今回は対象から外すこととします。
まずは Premier League を中心に実装し、過去シーズンの取得実績から UEFA Champions League についても対応可能な構成にしておくことにしました。
5. 実装
APIの選定が終わったので、ここから実際に実装していきます。
今回の実装では、Pythonを使って以下の処理を行います。
football-data.org
↓
APIからChelseaの試合情報を取得
↓
APIレスポンスから必要な情報を抽出
↓
ICS用のデータへ変換
↓
ICS文字列を生成
↓
chelsea.icsとして出力
まずはGitHub Actionsなどは使わず、ローカル環境でPythonを実行してICSファイルを生成できるところまで作っていきます。
5.1 APIレスポンスからICS用データへ変換
football-data.orgから取得した試合情報には、チーム名や試合日時、試合状態など、さまざまな情報が含まれます。
例えば、APIレスポンスには下記のような情報があります。
{
"id": 560920,
"utcDate": "2027-05-30T15:00:00Z",
"status": "TIMED",
"homeTeam": {
"name": "Chelsea FC",
"shortName": "Chelsea"
},
"awayTeam": {
"name": "Brentford FC",
"shortName": "Brentford"
},
"competition": {
"name": "Premier League"
},
"matchday": 38
}
これをこのままICSへ変換してもいいのですが、不要なデータもあります。
このため、そのまま出力するのではなく、カレンダーに必要な情報だけを取り出して、ICS生成用のデータへ変換していきます。
今回使用する主な情報は下記です。
| APIの項目 | ICSでの用途 |
|---|---|
id |
UID |
utcDate |
DTSTART |
utcDate |
DTEND |
homeTeam.shortName |
対戦相手・ホーム/アウェイ判定 |
awayTeam.shortName |
対戦相手・ホーム/アウェイ判定 |
competition.name |
DESCRIPTION |
matchday |
DESCRIPTION |
venue |
LOCATION |
status |
試合の状態 |
例えば、
Chelsea FC
Brentford FC
という表記ではなく、
Chelsea
Brentford
としてCalendarに表示することもできます。
また、試合IDについてはICSのUIDとして利用します。
"uid": f'{match["id"]}@chelsea-calendar'
UIDには試合ごとに一意となる値を設定します。
今回は football-data.org が持つ試合IDを利用することで、同じ試合には常に同じ UID が設定されるようにしました。
このため、試合日時が変更された場合でも、次回の ICS 生成時に同じ試合を同じイベントとして識別できる構成になっています。
最終的には、下記のようなデータへ変換します。
{
"uid": "560920@chelsea-calendar",
"dtstamp": ...,
"dtstart": ...,
"dtend": ...,
"summary": "⚽ Chelsea vs Brentford",
"description": "Premier League\nMatchday 38",
"status": "CONFIRMED",
"sequence": 0,
"venue": "Stamford Bridge"
}
これで、API固有のレスポンスから、ICS生成に必要なデータを切り離すことができました。
5.2 ICSファイルを生成
次に、先ほど作成した ICS 用データから、実際の ICS 文字列を生成します。
ICS は、iCalendar 形式で記述されたテキストファイルです。
基本的には、
BEGIN:VCALENDAR
...
BEGIN:VEVENT
...
END:VEVENT
END:VCALENDAR
という構造になっています。
今回のカレンダーでは、例えば下記のような形式で生成します。
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Chelsea Calendar//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Chelsea Matches
X-WR-CALDESC:Chelsea FC match schedule
X-WR-TIMEZONE:Asia/Tokyo
BEGIN:VEVENT
UID:560920@chelsea-calendar
DTSTAMP:...
DTSTART:20270530T150000Z
DTEND:20270530T170000Z
SUMMARY:⚽ Chelsea vs Brentford
LOCATION:...
DESCRIPTION:Premier League\nMatchday 38
STATUS:CONFIRMED
SEQUENCE:0
END:VEVENT
...
END:VCALENDAR
ICSの日時について
ICSでは日時を、20270530T150000Z のような形式で記述します。
例えば、
2027-05-30T15:00:00Z
上記記載は、下記となります。
20270530T150000Z
今回、football-data.org から取得した utcDate は UTC で提供されるため、UTC のまま ICS へ出力することにしました。
カレンダー側では、この UTC の日時を端末のタイムゾーンに合わせて表示します。
このため、日本のタイムゾーンを設定している端末では、下記のように表示されます。
UTC 15:00
↓
JST 00:00(翌日)
今回は日時の変換を Python では行わず、UTC のまま ICS へ渡し、カレンダー側でローカル時刻として表示させる方針としています。
また、試合終了時刻については、現時点では試合時間を2時間と仮定して、下記のように実装しています。
dtend = utc_date + timedelta(hours=2)
フットボールにおいて、試合は前後半90分に加えて、ハーフタイムやアディショナルタイムがあります。
これらを加えると、大体は2時間強となるため、今回は区切りがいい「2時間」と設定しています。
ICS文字列のエスケープ
ICSでは、カンマやセミコロン、改行などをそのまま記述すると正しく解釈されない場合があります。
このため、ICS の TEXT として使用する文字列については、専用のエスケープ処理を入れています。
def escape_ics_text(text):
return (
str(text)
.replace("\\", "\\\\")
.replace(";", "\\;")
.replace(",", "\\,")
.replace("\n", "\\n")
)
こうして生成した文字列を、最終的に chelsea.ics としてファイルへ出力します。
5.3 ローカルで動作確認
ここまで実装できたら、まずは GitHub Actions や GitHub Pages を使わず、ローカル環境で動作確認します。
Pythonを実行します。正常に処理できれば、
Status: 200
URL: https://api.football-data.org/v4/teams/61/matches?season=2026
試合数: 38
chelsea.ics を作成しました。
イベント数: 38
のように表示され、カレントディレクトリに chelsea.ics が生成されます。
生成された ICS の内容も確認します。
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Chelsea Calendar//EN
...
BEGIN:VEVENT
UID:...
DTSTART:...
DTEND:...
SUMMARY:⚽ Fulham vs Chelsea
DESCRIPTION:Premier League\nMatchday 1
LOCATION:...
...
END:VEVENT
...
END:VCALENDAR
ここで、
- 試合数が想定通りか
- Home / Away が正しいか
- 対戦相手が正しく表示されるか
- 試合日時が正しいか
- スタジアム情報が入っているか
- ICS として正しい形式になっているか
を確認します。
この時点では、まだGitHub Actionsによる自動化は行いません。
まずローカルで、
「APIからChelseaの試合情報を取得して、正しいICSを生成できる」
ところまで確認します。
6. GitHub Actionsで自動化
ローカル環境で、API から試合情報を取得して chelsea.ics を生成できることを確認しました。
次は、この処理を GitHub Actions 上で実行できるようにします。
GitHub Actionsを利用することで、ローカルPCを起動して Python を実行しなくても、GitHub 上で自動的にICSファイルを生成できるようにします。
今回の GitHub Actions では、下記の流れで Python プログラムを実行します。
GitHub Actions 起動
↓
リポジトリをチェックアウト
↓
Python 環境をセットアップ
↓
必要なライブラリをインストール
↓
API Key を取得
↓
main.py を実行
↓
chelsea.ics を生成
6.1 GitHub Actionsの設定
まず、リポジトリにGitHub ActionsのWorkflowを作成します。
今回は、
.github/
└── workflows/
└── update.yml
という構成にしました。
Workflow では、Python のセットアップや依存ライブラリのインストールを行った後、main.py を実行します。
今回は下記設定を記載しています。
name: Update Chelsea Calendar
on:
workflow_dispatch:
permissions:
contents: read
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run main.py
env:
FOOTBALL_DATA_API_KEY: ${{ secrets.FOOTBALL_DATA_API_KEY }}
run: python main.py
まずは workflow_dispatch を設定し、GitHub Actions の画面から手動実行できるようにしました。
いきなり定期実行するのではなく、まずは GitHub Actions 上で正常に Python プログラムが動作することを確認する方針です。
6.2 API KeyをGitHub Secretsで管理
ここで1つ問題があります。
ローカルで実行していたときは、Python から football-data.org の API を呼び出すために API Key が必要でした。
しかし、API Key をそのまま Python のソースコードに記述してしまうと、API Keyをソースコードへ直接記述した状態でPublicリポジトリへpushすると、API Keyが公開されてしまいます。
そこで、API Key はソースコードから切り離し、GitHub Secrets で管理することにしました。
GitHubリポジトリの、下記順序で Repository Secret を追加します。
- Settings
↓ - Secrets and variables
↓ - Actions
今回は、
- Name:
FOOTBALL_DATA_API_KEY - Secret:
football-data.orgから取得した API Key
Workflow 側では、登録した Secret を環境変数として Python へ渡します。
これによって、下記の形となり、API Key をソースコードに直書きせず、環境変数から取得できるようになりました。
API Key
↓
GitHub Secrets
↓
GitHub Actions
↓
環境変数
↓
Python
6.3 GitHub Actions 上で ICS ファイルを生成
ここまで設定できたら、GitHub Actionsを手動実行して動作を確認します。
GitHub の Actions から、Update Chelsea Calendar を選択し、 Run workflow から Workflow を手動実行します。
正常に処理が完了すると、 GitHub Actions のログに、下記のような結果が出力されます。
Status: 200
URL: https://api.football-data.org/v4/teams/61/matches?season=2026
試合数: 38
chelsea.ics を作成しました。
イベント数: 38
これにより、
ローカル
↓
python main.py
↓
chelsea.ics
だった処理を、
GitHub Actions
↓
python main.py
↓
chelsea.ics
といった形で、GitHub 上でも実行できるようになりました。
ただし、この時点では生成された chelsea.ics を GitHub リポジトリへコミットすることはしていません。
今回の構成では、後ほど GitHub Pages へ ICS を公開する仕組みを構築するため、生成した ICS をGitHub Pages へデプロイする方式を採用します。
このため、次は GitHub Actions で生成した chelsea.ics を、外部からアクセスできるようにする方法を考えます。
7. GitHub PagesでICSを公開
前章までで、GitHub Actions 上から chelsea.ics を生成できるようになりました。
ただし、この時点では生成した ICS ファイルは GitHub Actions の実行環境内に存在するだけで、外部からアクセスすることはできません。
Apple Calendar から ICS を購読するためには、Apple Calendar がアクセスできる URL 上に ICS ファイルを公開する必要があります。
そこで今回は、GitHub Pages を利用して chelsea.ics を公開することにしました。
最終的には、以下のような流れになります。
GitHub Actions
↓
chelsea.ics を生成
↓
GitHub Pages 用の Artifact を作成
↓
GitHub Pages へデプロイ
↓
https://xxxxx.github.io/chelsea-calendar/chelsea.ics
↓
Apple Calendar から参照
7.1 GitHub Pagesの設定
まず、GitHub Pagesを利用できるようにリポジトリ側の設定を行います。
GitHubリポジトリの以下の画面を開きます。
- Settings
↓ - Pages
GitHub Pages のBuild and deploymentから、Source を以下のように設定します。
今回はGitHub Actions から生成した ICS ファイルをそのままデプロイするため、ブランチから公開する方式ではなく、GitHub Actions を選択します。
これで、GitHub Actions から GitHub Pages へファイルを公開する準備が完了です。
7.2 GitHub Actions から GitHub Pages へデプロイ
次に、前章で作成したWorkflowへ GitHub Pages へのデプロイ処理を追加します。
まず、生成した chelsea.ics を GitHub Pages へ公開するため、public ディレクトリへ配置します。
- name: Generate ICS
env:
FOOTBALL_DATA_API_KEY: ${{ secrets.FOOTBALL_DATA_API_KEY }}
run: |
mkdir -p public
python main.py
mv chelsea.ics public/chelsea.ics
これにより、GitHub Actions上では以下のような構成になります。
public/
└── chelsea.ics
続いて、このpublicディレクトリを GitHub Pages 用の Artifact としてアップロードします。
- name: Setup GitHub Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: "public"
最後に、Artifact を GitHub Pages へデプロイします。
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
また、GitHub Pages へのデプロイには権限が必要となるため、Workflow には以下の設定も追加します。
permissions:
contents: read
pages: write
id-token: write
そして、デプロイ先として、 github-pages Environment を指定します。
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
まとめると、Workflowは以下のような構成になります。
name: Update Chelsea Calendar
on:
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
update:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Generate ICS
env:
FOOTBALL_DATA_API_KEY: ${{ secrets.FOOTBALL_DATA_API_KEY }}
run: |
mkdir -p public
python main.py
mv chelsea.ics public/chelsea.ics
- name: Setup GitHub Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: "public"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Workflow を実行し、GitHub Pages へのデプロイが正常に完了すると、ICS ファイルへURLからアクセスできるようになります。
今回作成したリポジトリでは、以下のURLにアクセス可能です。
ブラウザからこの URL へアクセスし、chelsea.ics を取得できれば、GitHub Pagesへの公開は完了です。
今回はWebページを公開することが目的ではないため、index.html は配置していません。
このため、
https://fcf-kando.github.io/chelsea-calendar/
へアクセスすると404になりますが、
https://fcf-kando.github.io/chelsea-calendar/chelsea.ics
へアクセスできれば問題ありません。
ここまでで、下記流れまで構築できました。
football-data.org
↓
Python
↓
chelsea.ics
↓
GitHub Actions
↓
GitHub Pages
次は、公開した ICS の URLを Apple Calendar へ登録し、実際に Chelsea の試合日程をカレンダーから確認できるようにします。
8. Apple Calendarから購読
前章までで、GitHub Pages 上に chelsea.ics を公開し、外部からアクセスできるようになりました。
次は、このICSファイルを Apple Calendar から購読する形に整えます。
ここで重要なのは、ICS ファイルを単発インポートする形式ではなく、URL を指定して「照会カレンダー」として追加することです。
照会カレンダーとして登録することで、GitHub Pages 上の chelsea.ics が更新された際に、Apple Calendar 側でも更新された予定を取得できるようになります。
今回の流れは下記です。
GitHub Pages
↓
chelsea.ics
↓
ICSのURLをApple Calendarへ登録
↓
照会カレンダーとして購読
↓
Chelseaの試合日程を表示
8.1 ICSのURLを確認
まず、前章でGitHub Pagesへ公開したICSファイルのURLを確認します。
今回の場合は、以下のURLです。
ここで確認しているのは、Apple Calendar からもアクセスできる状態で ICS ファイルが公開されているかどうかです。
上記URLに正常にアクセスできていれば問題ありません。
8.2 Apple Calendarで購読
ICSファイルへアクセスできることを確認したら、Apple Calendar へ登録します。
今回は手元のiPhoneから設定します。念のため、検証時の環境も記載しておきます。
- iPhone:16
- iOS:26.6.1
カレンダーアプリから、以下の順番で照会カレンダーを追加します。
カレンダーアプリの下部からカレンダーアイコンをクリック
画面下部の「カレンダーを追加」をクリック
「照会カレンダーを追加」をクリック
「照会URL」に、先ほど確認した GitHub PagesのURLを入力
実際に、Apple Calendar で、「Chelsea Matches」として試合情報が表示されていることが確認できました!!


画像の通り、今回生成した ICS では、例えば以下のような情報を確認することが可能です。
⚽ Chelsea vs Brentford
日時:
2027/05/31 00:00~
場所:
Stamford Bridge
詳細:
Premier League
Matchday 38
API から取得した UTC の試合日時についても、端末側のタイムゾーンに合わせて日本時間として表示されます。
これで、下記一連の流れが完成しました。
football-data.org
↓
Python
↓
chelsea.ics
↓
GitHub Actions
↓
GitHub Pages
↓
Apple Calendar
今回は ICS ファイルを直接読み込むのではなく、GitHub Pages 上の ICS を照会カレンダーとして購読している点がポイントです。
そのため、今後 GitHub Actions によって chelsea.ics の内容を更新すれば、同じURLを維持したまま最新の試合情報を公開できます。
ただし、現時点では GitHub Actions を手動で実行しているため、ICS ファイルの更新自体は自動化されていません。
そこで次は、GitHub Actions を定期実行するように設定し、試合日程の変更を自動的に取得できるようにしていきます。
9. GitHub Actionsで定期更新
前章までで、GitHub Pages 上に公開したICSファイルを Apple Calendar から購読できるようになりました。
ただし、ここまでの GitHub Actions は workflow_dispatch による手動実行です。
このままでは、試合日時の変更などが発生するたびに、手動で GitHub Actions を実行する必要があります。
そこで、GitHub Actions の schedule を利用して、定期的に football-data.org から最新の試合情報を取得し、chelsea.ics を更新するようにします。
最終的には、以下の処理を定期的に実行します。
GitHub Actions
↓
football-data.orgから
最新の試合情報を取得
↓
chelsea.icsを再生成
↓
GitHub Pagesへデプロイ
↓
Apple Calendarから照会
これにより、一度 Apple Calendar へ ICS の URL を登録しておけば、試合日時が変更された場合でも、同じ URL の chelsea.ics を更新し続けることができます。
9.1 scheduleの設定
GitHub Actions を定期実行するため、Workflow の on へ schedule を追加します。
on:
workflow_dispatch:
schedule:
- cron: "20 * * * *"
workflow_dispatch も残しているため、「必要に応じた手動実行」、「scheduleによる定期実行」の両方が可能です。
今回設定した、schedule の設定は、毎時20分に Workflow を実行する設定です。
※cronは左から、分 時 日 月 曜日 を表しています
9.2 定期実行の確認
schedule を追加してから、GitHub Actions の実行履歴を確認します。
Actions 画面を見ると、手動実行時とは異なり、Scheduled として Workflow が実行されることを確認できました。

これで、下記流れとして自動化することができました。
GitHub Actionsを定期実行
↓
football-data.orgから試合情報を再取得
↓
chelsea.icsを再生成
↓
GitHub Pagesへ再デプロイ
schedule が毎時20分に実行されない?
ここで、実際に動かしてみて1つ気になった点がありました。
今回、下記を設定したため、当初は毎時20分にほぼ正確に実行されるものだと思っていました。
schedule:
- cron: "20 * * * *"
しかし、上記キャプチャの通り、実際の実行履歴を確認すると、必ずしも毎時20分に Workflow が開始されるわけではありませんでした。
実行間隔にもばらつきがあり、毎時間必ず実行されているわけではありません。
GitHub Actions の schedule は、指定した時刻を基準に実行されますが、GitHub公式ドキュメントによると、GitHub Actions の schedule イベントは、
GitHub Actions の実行負荷が高い場合に遅延する可能性があります。
また、負荷が十分に高い場合には、一部のキュー済みジョブが削除される可能性もあると記載されています。
このため、上記設定を追加した場合でも、
「毎時20分ちょうどに必ず実行される」ことを保証するものではないようです。
(それでいいのか?はさておきましょう...)
今回の用途では、試合日程を数秒・数分単位で同期する必要はなく、定期的に最新の試合情報を取得できれば十分です。
このため、多少の実行遅延については許容することにしました。
これで、当初想定していた一連の仕組みが完成しました。
以降は、football-data.org 側で試合情報が更新されれば、GitHub Actions の定期実行によって ICS ファイルも更新される構成になります。
10. 実装中にハマったポイント
ここまでで一通りの仕組みを構築できましたが、実装中にはいくつかハマったポイントがありました。
特に印象に残ったものをまとめておきます。
10.1 season には Season ID ではなく「シーズン開始年」を指定する
football-data.org から Chelsea の試合情報を取得する際、最初にハマったのが season パラメータでした。
Premier League の情報を取得すると、シーズン情報として以下のような Season ID を確認できます。
Season ID: 2502
Start Date: 2026-08-21
End Date: 2027-05-30
このため、当初は試合取得APIにもこの Season ID を指定すればよいと考え、以下のようにリクエストしていました。
/v4/teams/61/matches?season=2502
しかし、API 自体は HTTP 200 で正常終了するものの、取得できる試合数は0件でした。
エラーにならず正常終了するため、最初は原因が分からず少しハマりました。
調べてみると、この API の season に指定するのは Season ID ではなく、シーズンの開始年でした。
そのため、2026/27シーズンの場合は、下記を指定することで、
/v4/teams/61/matches?season=2026
Premier League 38試合を正常に取得できました。
Status: 200
試合数: 38
また、シーズンが変わるたびに、 SEASON = 2026 のように、ハードコーディングとして記載を変更するのも嫌だったので、最終的には Premier League の情報を取得するようにしました。
currentSeason
↓
startDate
↓
2026-08-21
↓
2026
これにより、新しいシーズンへ移行した場合でも、シーズンをハードコードしていないため、プログラム側でシーズンを管理する必要がなくなり、プログラム側で毎年値を変更しなくてもよい状態になりました。
10.2 GitHub Pagesのトップページが404になる
GitHub Pages へのデプロイが完了した後、下記へアクセスしてみると、404が表示されました。
一瞬、GitHub Pages へのデプロイに失敗したかと思いましたが、今回GitHub Pagesへ配置しているのは、public 配下の chelsea.ics であるため、ルーツURLへアクセスすると404になる挙動は正常な動作でした。
ここを少し勘違いしていたため、想定よりも少し時間がかかってしまいました。
11. 完成したシステム
ここまでの実装で、Chelsea の試合日程を取得し、Apple Calendar へ連携する仕組みが完成しました。
改めて、今回作成したシステム全体を整理すると、以下の構成になります。
football-data.org
↓
Chelseaの試合情報を取得
↓
Python
↓
ICS用データへ変換
↓
chelsea.ics
↓
GitHub Actions
(定期実行)
↓
GitHub Pages
↓
Apple Calendar
(照会カレンダー)
それぞれの役割は以下の通りです。
| 要素 | 役割 |
|---|---|
| football-data.org | Chelsea の試合情報を取得 |
| Python | APIレスポンスを整形し、ICSファイルを生成 |
| GitHub Actions | Python の実行と定期更新 |
| GitHub Pages |
chelsea.ics を外部へ公開 |
| Apple Calendar | 公開されたICSを照会し、試合日程を表示 |
Apple Calendar には、GitHub Pages 上に公開した以下のURLを照会カレンダーとして登録しています。
一度このURLを登録しておけば、基本的には手動で試合予定を追加する必要はありません。
GitHub Actions が定期的に football-data.org から最新の試合情報を取得し、
「試合情報を取得 → chelsea.ics を再生成 → GitHub Pages へ再デプロイ」
とすることで、同じ URL のまま最新の ICS ファイルを公開し続けることが可能となりました。
また、各試合の UID には football-data.org の試合IDを利用しているため、試合日時が変更された場合でも同一の試合イベントとして扱える構成にしました。
これにより、
- API から Chelsea の試合情報を取得
- API レスポンスを ICS 形式へ変換
- GitHub Actions 上で ICS を生成
- GitHub Pages へ公開
- Apple Calendar から照会
- GitHub Actions による定期更新
という一連の処理を、すべて無料で構築することができました!🎉👏
当初の目的であった、
「Chelsea の試合日程を、自分の Apple Calendar に自動で反映したい!」
という仕組みは、これでひとまず完成です!
……と、ここまで記事をご覧いただいた方の中には、
「あれ、Premier League って公式でカレンダー追加できなかったっけ?」
と思った方もいるかもしれません。
12. 悲しい現実
はい、その通りです。知ってました。
Premier League 公式サイトでは、クラブを選択して試合日程を Apple Calendar へ追加する仕組みがすでに用意されています。
また、UEFA Champions League についても、公式からカレンダーへ試合日程を追加する仕組みが提供されています。
つまり、
football-data.org
↓
Python
↓
chelsea.ics
↓
GitHub Actions
↓
GitHub Pages
↓
Apple Calendar
なんてものを作らなくても、
Premier League と UEFA Champions League だけであれば、公式の仕組みを使えば済みます。
(/(^o^)\ナンテコッタ)
……いや、知ってました。知ってましたよ。ええ。
むしろ、当初 FA Cup や EFL Cup も含めて Chelsea の主要大会をまとめてカレンダーへ登録したかったのは、この点も理由の1つです。
Premier League や UEFA Champions League については公式のカレンダー連携が用意されていますが、FA Cup や EFL Cup については同じように簡単に登録できる仕組みを確認できませんでした。
だからこそ、
「それなら Chelsea の試合日程をまとめて自分で管理できる仕組みを作ってみよう」
というのが、今回の裏テーマでもありました。
……結果として、今回は API の無料枠の都合から FA Cup、EFL Cup を対象外としたため、
「最終的に実装できた範囲だけを見ると、公式の仕組みでほぼ事足りる」
という、なんとも言えない着地になりました。しょうがないですね。
Premier League 公式サイトでのカレンダー登録自体は非常に簡単です。
公式サイト

また、公式から提供されるカレンダーの方が情報量も多く、表示もきれいにまとまっています。(当たり前)

13. まとめ
では、今回作ったものは無駄だったのかというと、個人的にはそうでもありません。
API の調査・比較から始まり、ICS の生成、GitHub Actions による自動実行、GitHub Pages への公開、Apple Calendar からの購読まで、一連の仕組みを実際に構築することができました。
実用面だけで見れば公式を使う方が圧倒的に楽ですが、
「公式でできることを、あえて自分で作ってみる」
というのも、個人開発の楽しみ方の1つなのかなと思います。
また、普段何気なく利用しているカレンダーの裏側で、ICS がどのように予定を表現しているのかを知れたことも、個人的には大きな収穫でした。
今後また「これ、自分でも作れそうだな」と思うものを見つけたら、たとえ既に公式機能が存在していたとしても、懲りずに作ってみようと思います。








