cz.basketball Schedule Watcher avatar

cz.basketball Schedule Watcher

Pricing

Pay per usage

Go to Apify Store
cz.basketball Schedule Watcher

cz.basketball Schedule Watcher

Watches a cz.basketball team's fixtures for schedule changes (new/moved/cancelled games, time & venue changes) and optionally syncs them to Google Calendar. Sends email and webhook notifications on every change.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Zdeněk Kunčar

Zdeněk Kunčar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

CBF.cz Schedule Watcher

Watches a team's fixtures on cz.basketball and tells you when the schedule changes: a game gets moved, the venue changes, a game is postponed/cancelled, or a brand-new fixture appears. Optionally mirrors the fixtures into a Google Calendar so your team's games just show up — and stay correct — without anyone re-typing anything.

Built for BASKET OPAVA 2010 by default, but works for any team in any Czech basketball league: just change the teamId input.

How it works

cz.basketball doesn't have a stable per-season schedule URL — the competition ID (/soutez/5376) changes every year when the league restarts. What is stable is the team ID (/tym/13093), with the season selected via a ?y= query parameter (?y=2026 = the 2026/27 season).

Each run, the Actor:

  1. Fetches https://cz.basketball/tym/{teamId}?y={year} to get the list of this season's fixtures.
  2. Fetches each fixture's detail page (/zapas/{id}) for the authoritative date, time, and venue.
  3. Diffs the result against the snapshot saved from the previous run.
  4. Reports anything that changed — new games, reschedules, venue changes, postponements/cancellations, and games dropped from the schedule.
  5. Optionally emails you (via Gmail), POSTs a webhook, and/or creates/updates/deletes the matching Google Calendar events.
  6. Saves the new snapshot for next time.

If year is left empty, the Actor auto-detects the current season (it rolls over every August), so it keeps working next year and the year after without any changes to the input.

Finding your team's ID

  1. Go to cz.basketball and open your team's page (via your league's standings/competition page, or search).
  2. The team ID is the number in the URL: https://cz.basketball/tym/13093teamId = "13093".

Input

FieldRequiredDefaultDescription
teamIdyes13093 (BASKET OPAVA 2010)The cz.basketball team ID.
teamNameyesBASKET OPAVA 2010Display name used in calendar events and notifications.
yearnoauto-detectedSeason start year (the ?y= value). Leave empty so the Actor tracks the current season automatically, forever.
skipPastGamesnotrueIgnore fixtures already in the past.
notifyEmailnoGet an email summary when something changes, sent via Gmail from your connected Google account (see setup below). Can be any address.
webhookUrlnoPOST a JSON payload of the changes to your own endpoint, Zapier, Make, a Slack incoming webhook, etc.
notifyOnFirstRunnofalseOn the very first run every fixture looks "new" (no prior snapshot exists). Leave off to seed silently.
dryRunnofalseDetect and report changes but never write to Google Calendar.

Google account (optional)

Connecting a Google account is entirely opt-in. If you leave the fields below empty, the Actor works purely as a change detector: it still diffs the schedule and still sends webhook notifications. The same Google account powers two independent, separately-toggled features:

  • Calendar sync — mirrors fixtures into Google Calendar. Requires enableCalendar to be turned on.
  • Email notifications — sends the change summary via Gmail. Requires notifyEmail to be set.

You only need to do the OAuth setup once even if you use both — a single refresh token authorizes both.

FieldDescription
enableCalendarTurn on to mirror fixtures into Google Calendar.
googleCalendarIdprimary for your main calendar, or a specific calendar's ID. Only used when Calendar sync is on.
googleClientId / googleClientSecretOAuth 2.0 credentials from Google Cloud Console.
googleRefreshTokenA long-lived refresh token (see setup below).
eventDurationMinutesHow long each game event should last (default 120). Calendar sync only.

If enableCalendar is on but any of the three Google credential fields is missing, the Actor logs a warning and skips calendar sync for that run. Likewise, if notifyEmail is set without the Google fields, it logs a warning and skips the email. Neither will crash the run.

One-time Google OAuth setup

  1. In Google Cloud Console, create (or pick) a project and enable the Google Calendar API and the Gmail API.

  2. Under APIs & Services → Credentials, create an OAuth client ID of type Desktop app.

  3. Under OAuth consent screen, add your own Google account as a Test user (unless the app is published/verified).

  4. Clone this repo locally, install dependencies (npm install), then run:

    $GOOGLE_CLIENT_ID=<your client id> GOOGLE_CLIENT_SECRET=<your client secret> npm run get-token

    This opens a consent URL in your terminal — open it in a browser, approve access, and the script prints your googleClientId, googleClientSecret, and googleRefreshToken. The token is authorized for both Calendar and Gmail send access.

  5. Paste those three values into the Actor's input (mark the secret and refresh token fields as secret in Apify Console), then turn on enableCalendar and/or set notifyEmail as needed.

The refresh token doesn't expire under normal use, so this is a one-time setup. If you'd previously generated a refresh token before email notifications used Gmail, re-run npm run get-token to get a new one that also covers the Gmail scope — the old one won't have permission to send email.

Output

Every run that detects changes pushes one dataset row per change, with the change type (added, removed, rescheduled, venue_changed, opponent_changed, status_changed), a human-readable summary, the affected match's details, and (for updates) the previous values.

Scheduling

Run this Actor on a schedule (Apify Console → Schedules) — a few times a day is plenty for a weekly amateur league; tighten it up if your league tends to announce changes close to game time.

Local development

npm install
apify run # reads storage/key_value_stores/default/INPUT.json
npm test # unit tests against saved real HTML fixtures — no network required

Notes on the source site

  • cz.basketball is server-rendered HTML with no public API, so this Actor scrapes it directly with Cheerio (no browser needed — fast and light).
  • The site displays 00:00 as a placeholder when a game's kickoff time hasn't been announced yet; the Actor treats that as "time TBD" rather than a literal midnight game, and will correctly report it as a schedule update once a real time is announced.
  • All crawled HTML is treated as untrusted input and parsed defensively — nothing scraped is ever executed or interpolated into commands.