What You'll Build

I'm a huge basketball fan. But I can't watch every game or refresh Twitter all day. I miss trade announcements, injury reports, and signing news. So I built a little Python script that does the watching for me.

Every morning at 8 AM, my script fetches the latest NBA headlines from a free ESPN feed. It scans each headline for keywords I care about — "injury", "trade", "extension", "signing" — and if there's a match, it pushes a message straight to my Telegram app. I wake up, check my phone, and I'm caught up in five seconds.

The best part? It's completely free. No server costs. No API keys. You can run it on your laptop, a Raspberry Pi, or any machine that can run Python. And with a simple cron job, it runs automatically every day.

Let me show you how to build your own sports alert bot with Python and Telegram.

Create Your Telegram Bot (3 Minutes)

First, you need a bot on Telegram. This is the account that will send you messages. Telegram makes this ridiculously easy through a bot called... BotFather. Yes, that's its real name.

Open Telegram on your phone or desktop. Search for @BotFather in the search bar. It's the official bot that creates other bots.

Start a chat with BotFather and type:

/newbot

It'll ask you for a name. This is the display name — something like "NBA Alert Bot". Then it asks for a username. This must end with "bot" — for example, nba_alert_bot.

Once you confirm, BotFather replies with a message that includes your bot token. It looks like this:

1234567890:ABCdefGHIjklMNOpqrsTUVwxyz

Treat this token like a password. Anyone with this token can control your bot. Don't share it, don't paste it into a public GitHub repo, and don't email it.

Save it somewhere safe. We'll use it in our Python script in a moment.

Find Your Chat ID

Your bot needs to know where to send messages. That's your Chat ID — a unique identifier for your Telegram account or group.

Here's how to get it:

  1. Open Telegram and send any message to your new bot. Just type "hello" or "test".
  2. Open your browser and visit this URL, replacing YOUR_BOT_TOKEN with the token you got from BotFather:
https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates

You'll see a JSON response. Look for "chat":{"id":123456789}. That number is your Chat ID.

You can also grab it from the command line with curl:

# Replace YOUR_BOT_TOKEN with your actual token
curl "https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates"

Scroll through the output until you find "chat":{"id":...}. Copy that number.

Fetch NBA News with Python

Now for the fun part. We'll use Python to grab the latest NBA headlines from ESPN's free, unofficial API — the same hidden endpoint ESPN's own website calls in your browser (if you're new to this, my guide to calling hidden APIs with Python explains how they work). This endpoint doesn't require any authentication. It just returns JSON data.

Create a new file called nba_alert.py:

import requests

# ESPN's hidden API for NBA news (no key required)
url = "https://site.api.espn.com/apis/site/v2/sports/basketball/nba/news"

try:
    # Fetch the data with a 10-second timeout
    response = requests.get(url, timeout=10)
    response.raise_for_status()

    # Parse the JSON response
    data = response.json()

    # Extract the articles list
    articles = data.get("articles", [])

    # If no articles found, print a message
    if not articles:
        print("No NBA news found.")
    else:
        # Loop through articles and print headlines
        for article in articles:
            headline = article.get("headline", "No headline")
            published = article.get("published", "Unknown date")
            print(f"{headline} (Published: {published})")

except requests.exceptions.Timeout:
    print("The request timed out. Try again later.")
except requests.exceptions.HTTPError as e:
    print(f"HTTP error: {e}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Run it:

# Execute the script
python nba_alert.py

You'll see a list of recent NBA headlines with timestamps:

2026 NBA buzz: Latest free agency and trade updates (Published: 2026-08-22T00:33:34Z)
Denver Nuggets offseason recap, early 2026-27 season preview (Published: 2026-08-22T04:55:25Z)
2026 NBA free agency: Grades for offseason signings, extensions (Published: 2026-08-21T22:41:07Z)
Nuggets signing 6-time All-Star DeMar DeRozan to 1-year deal (Published: 2026-08-21T22:54:03Z)
Klay Thompson to sign 2-year deal with Heat after Mavs buyout (Published: 2026-08-21T23:57:38Z)

That's a real run from August 2026 — your headlines will differ depending on the news of the day. If it works, you're ready for the next step.

Send Your First Telegram Message

Now let's connect the news feed to your Telegram bot. We'll send the headlines directly to your chat.

Update your script to include the Telegram sendMessage endpoint:

import requests

# --- CONFIGURATION (replace these with your real values) ---
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"   # From BotFather
CHAT_ID = "YOUR_CHAT_ID_HERE"       # From getUpdates
# -----------------------------------------------------------

# ESPN hidden API
news_url = "https://site.api.espn.com/apis/site/v2/sports/basketball/nba/news"

try:
    # Fetch NBA news
    response = requests.get(news_url, timeout=10)
    response.raise_for_status()
    data = response.json()
    articles = data.get("articles", [])

    if not articles:
        print("No news found.")
    else:
        # Build a message with the latest headlines
        # Limit to first 5 articles to avoid sending a wall of text
        headlines = []
        for article in articles[:5]:
            headline = article.get("headline", "No headline")
            description = article.get("description", "")
            if description:
                headlines.append(f"{headline}\n{description[:100]}...")
            else:
                headlines.append(headline)

        message_text = "Good morning! Here are your NBA updates:\n\n"
        message_text += "\n\n".join(headlines)

        # Send the message to Telegram
        telegram_url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
        payload = {
            "chat_id": CHAT_ID,
            "text": message_text
        }

        send_response = requests.post(telegram_url, data=payload, timeout=10)
        send_response.raise_for_status()

        print("Alert sent successfully!")

except requests.exceptions.Timeout:
    print("The request timed out.")
except requests.exceptions.HTTPError as e:
    print(f"HTTP error: {e}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Replace YOUR_BOT_TOKEN_HERE and YOUR_CHAT_ID_HERE with your actual token and chat ID. Then run the script:

# Execute the script
python nba_alert.py

If everything is configured correctly, you'll see "Alert sent successfully!" and a message from your bot in Telegram with the latest NBA headlines.

Filter Alerts for What You Care About

You don't need every headline. You only care about specific stories — injuries, trades, contract extensions. Let's add a filter.

Modify the script to only send messages when a headline or description contains keywords you care about:

import requests

# --- CONFIGURATION ---
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"
CHAT_ID = "YOUR_CHAT_ID_HERE"

# Keywords to watch for (case-insensitive)
KEYWORDS = ["injury", "trade", "extension", "signing", "deal", "contract", "out"]
# ---------------------

news_url = "https://site.api.espn.com/apis/site/v2/sports/basketball/nba/news"

try:
    response = requests.get(news_url, timeout=10)
    response.raise_for_status()
    data = response.json()
    articles = data.get("articles", [])

    if not articles:
        print("No news found.")
    else:
        # Filter articles that contain any keyword
        matched_articles = []
        for article in articles:
            headline = article.get("headline", "")
            description = article.get("description", "")
            combined_text = (headline + " " + description).lower()

            # Check if any keyword appears in the text
            for keyword in KEYWORDS:
                if keyword.lower() in combined_text:
                    matched_articles.append(article)
                    break  # Stop checking keywords for this article

        if not matched_articles:
            print("No matching news today.")
        else:
            # Build message from matched articles
            message_lines = ["NBA Alert - Matching Stories:"]
            for article in matched_articles[:5]:
                headline = article.get("headline", "No headline")
                message_lines.append("- " + headline)

            message_text = "\n".join(message_lines)

            # Send alert
            telegram_url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
            payload = {"chat_id": CHAT_ID, "text": message_text}
            send_response = requests.post(telegram_url, data=payload, timeout=10)
            send_response.raise_for_status()

            print(f"Alert sent! {len(matched_articles)} matching articles found.")

except requests.exceptions.Timeout:
    print("The request timed out.")
except requests.exceptions.HTTPError as e:
    print(f"HTTP error: {e}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Now you'll only get notified when something interesting happens. You can add more keywords — "playoff", "MVP", "suspension" — or even team names like "Lakers" or "Celtics".

Run It Every Morning with cron

Running the script manually defeats the purpose. We want it to run automatically every morning so we wake up to fresh news.

On Linux or macOS, we use cron. It's a time-based job scheduler built into every Unix system.

Open your terminal and edit your crontab:

# Open your cron job list for editing
crontab -e

If it's your first time, you'll be asked to choose an editor. Pick nano or vim.

Add this line to the bottom:

0 8 * * * cd /home/yourname/nba-bot && /usr/bin/python3 nba_alert.py >> /home/yourname/nba-bot/log.txt 2>&1

Let me break that down:

Part Meaning
0 8 * * * Run at 8:00 AM every day (minute, hour, day, month, weekday)
cd /home/yourname/nba-bot Change to the folder where your script lives
&& Only run the next command if the first succeeds
/usr/bin/python3 nba_alert.py Run the script with Python
>> log.txt 2>&1 Save output and errors to a log file

Replace /home/yourname/nba-bot with the actual path to your script. To find your Python path, run which python3 in the terminal.

Time zone matters. Cron runs on your system's default time zone. If you're on the East Coast like me (America/New_York), 8 AM is 8 AM. If you're somewhere else, adjust accordingly. You can change your system time zone or modify the cron hour to match your local time.

For Windows users, use Task Scheduler. Create a Basic Task, set the trigger to daily at 8:00 AM, and set the action to run python.exe with your script path as the argument.

Comparing Notification Methods

Method Cost Ease of Setup Reliability
Telegram bot Free Easy (5 mins) Very reliable
Email (SMTP) Free Moderate Spam filters
SMS (Twilio) ~$0.0075 per msg Moderate Pay per use
Push notifications (Pushover) $5 one-time Easy Good

Telegram wins for this project because it's free, quick to set up, and works on both phone and desktop.

FAQ

Is Telegram free?

Yes. Telegram is completely free for personal use. There are no paid plans for standard users. The bot API is also free — you can create as many bots as you want without paying anything.

Do I need a server or domain to run this?

No. You can run the Python script on your personal computer, a Raspberry Pi, or any machine that stays powered on. You don't need a domain, web hosting, or a cloud server. The script makes outbound HTTP requests — it doesn't need to be publicly accessible.

Can I get alerts for other sports or teams?

Yes. ESPN has similar endpoints for other sports:

  • NFL: https://site.api.espn.com/apis/site/v2/sports/football/nfl/news
  • MLB: https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/news
  • NHL: https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/news

All three respond with the same article format as the NBA endpoint. You can also filter by team by adding team names to your keyword list.

How often should the script run?

Once a day is usually enough for news alerts. Running it more frequently (every hour) can flood your inbox with the same stories. I run mine at 8 AM so I see the morning recap before starting my day. If there's breaking news, you'll catch it the next morning.

Is the ESPN API free to use?

The endpoint we're using is a hidden API — it's the same one ESPN's own website uses to load news. It's free to access and doesn't require a key. However, it's not a public, documented API. ESPN could change or remove it without notice. For a personal project, it's perfectly fine. For a commercial product, you'd want an official source.

Next Steps

You've got a working NBA alert bot. Here's how to take it further:

Now go build your bot. And when you get that first alert in your Telegram, you'll know you built it yourself — no expensive tools, no complicated setup. Just Python, a free bot, and your morning coffee.

All code in this article was tested and runs successfully on Python 3.8.10 (Ubuntu 20.04) with requests 2.32.4. The ESPN news fetch was verified against the live API — NBA, NFL, MLB, and NHL endpoints all return 200 with the article fields used here. The Telegram sendMessage request was verified with a mocked API call (no real bot token was used; replace the placeholders with your own). The cron line was syntax-validated. — verified August 2026.