2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PR: 株式会社フューチャークリエーションファクトリー
F.C.Fでは、一緒に成長していくエンジニアを募集しています 🌱

【個人開発】Chelseaの試合日程をApple Calendarへ自動反映する仕組み作ってみた!

2
Last updated at Posted at 2026-09-08

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 を追加します。

  1. Settings
    ↓
  2. Secrets and variables
    ↓
  3. Actions

image.png

今回は、

  • Name:FOOTBALL_DATA_API_KEY
  • Secret:football-data.org から取得した API Key

として登録しました。
image.png

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リポジトリの以下の画面を開きます。

  1. Settings
    ↓
  2. Pages
    GitHub Pages の Build and deployment から、Source を以下のように設定します。
  • Source:GitHub Actions
    image.png

今回は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にアクセス可能です。

https://fcf-kando.github.io/chelsea-calendar/chelsea.ics

ブラウザからこの 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です。

https://fcf-kando.github.io/chelsea-calendar/chelsea.ics

ここで確認しているのは、Apple Calendar からもアクセスできる状態で ICS ファイルが公開されているかどうかです。
上記URLに正常にアクセスできていれば問題ありません。

8.2 Apple Calendarで購読

ICSファイルへアクセスできることを確認したら、Apple Calendar へ登録します。
今回は手元のiPhoneから設定します。念のため、検証時の環境も記載しておきます。

  • iPhone:16
  • iOS:26.6.1
    カレンダーアプリから、以下の順番で照会カレンダーを追加します。

カレンダーアプリの下部からカレンダーアイコンをクリック
IMG_5423.jpeg
画面下部の「カレンダーを追加」をクリック
IMG_5424.jpeg
「照会カレンダーを追加」をクリック
IMG_5425.jpeg
「照会URL」に、先ほど確認した GitHub PagesのURLを入力

https://fcf-kando.github.io/chelsea-calendar/chelsea.ics

IMG_5426.jpeg
IMG_5436.jpeg

実際に、Apple Calendar で、「Chelsea Matches」として試合情報が表示されていることが確認できました!!
IMG_5437.jpeg
IMG_5438.jpeg

画像の通り、今回生成した 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 が実行されることを確認できました。
image.png

これで、下記流れとして自動化することができました。

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分ちょうどに必ず実行される」ことを保証するものではないようです。
(それでいいのか?はさておきましょう...)

参考:【GitHubドキュメント】ワークフローをトリガーするイベント

今回の用途では、試合日程を数秒・数分単位で同期する必要はなく、定期的に最新の試合情報を取得できれば十分です。

このため、多少の実行遅延については許容することにしました。

これで、当初想定していた一連の仕組みが完成しました。
以降は、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が表示されました。

https://fcf-kando.github.io/chelsea-calendar/

一瞬、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を照会カレンダーとして登録しています。

https://fcf-kando.github.io/chelsea-calendar/chelsea.ics

一度この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 公式サイトでのカレンダー登録自体は非常に簡単です。
公式サイト
IMG_5434.jpeg

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

13. まとめ

では、今回作ったものは無駄だったのかというと、個人的にはそうでもありません。

API の調査・比較から始まり、ICS の生成、GitHub Actions による自動実行、GitHub Pages への公開、Apple Calendar からの購読まで、一連の仕組みを実際に構築することができました。

実用面だけで見れば公式を使う方が圧倒的に楽ですが、

「公式でできることを、あえて自分で作ってみる」

というのも、個人開発の楽しみ方の1つなのかなと思います。

また、普段何気なく利用しているカレンダーの裏側で、ICS がどのように予定を表現しているのかを知れたことも、個人的には大きな収穫でした。

今後また「これ、自分でも作れそうだな」と思うものを見つけたら、たとえ既に公式機能が存在していたとしても、懲りずに作ってみようと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?