Writing on Tablets Tech stuff from @yeltzland

Getting Daily Alerts for MLB Condensed Games

Keep up to date on the travails of the Mets without needing an MLB TV subscription

Citi Field

30 years ago I spent a couple of summers working in New Jersey, and got drawn into the crazy world of New York Mets baseball.

Back then, keeping in touch when back home meant scouring the International Herald Tribune for any baseball news, but for the last decade I’ve been a subscriber to MLB TV which has been fantastic.

When considering renewing this year’s subscription, I realised I hardly watch any live games any more. Most games are played in the evening US Eastern Time or later, so what I generally do is wait until the next morning and try to watch the condensed game - around 5 minutes of “Match Of The Day” style highlights - without knowing the score.

Accessing MLB Condensed Games for free

MLB are a lot less precious with their highlights packages than the Premier League (surprise, surprise!), and make a lot of content available for free on both YouTube and within the MLB TV app for free.

However within the MLB TV app you can’t get notifications for when new condensed games are available without a paid subscription (which is fair enough!), and it’s really hard to check when a the video is ready without finding out the score, or some information about the game via the other videos already published.

However, the excellent Baseball Theater had figured out that the configuration for the mobile apps is held in the open, so that gave me the idea of hacking together a similar solution to send alerts as soon as there is a new condensed game is ready for viewing.

My MLB Condensed Games alert system

It’s all a bit Heath-Robinson, but my system works as below. Note the code is all avaialble on GitHub, and the below is copied from the readme.md of the repo:

There are 2 main entry points - designed to be run from AWS Lambda:

  1. lambdaCondensedGame,js - Checks whether a condensed game stream is available for a given team on a given day
  2. lambdaMonitor.js - Will see if a condensed game has been added, and if so sends a Slack message saying a new game is ready, plus a link to the stream

Condensed Game function

This function reads from the POSTed JSON formatted like:

{
	gameDate: "2019-04-26",
	team: "nym"
}

You must also send a HTTP header of MLBAPIRequest with a value set as an environment variable of the same name.

This will then:

  1. Build URL like http://gd2.mlb.com/components/game/mlb/year_2018/month_06/day_26/master_scoreboard.xml (using the incoming date)
  2. Look for <game> node where home_file_code=”nym” or away_file_code=”nym” (using the incoming team)
  3. Pick up game_pk attribute to get the URL e.g. “https://statsapi.mlb.com/api/v1/game/530594/content?language=en”
  4. Find in the media.epgAlternate nodes the “Extended Highlights” section, and then find the item that is the condensed game video (if it exists)
  5. Pick the correct URL node - the video that has a value that ends in .mp4

Assuming that a condensed game is found, the function then returns JSON like:

{
	"opponent": "pit",
	"date": "2019-04-26",
	"url": "http://mediadownloads.mlb.com/mlbam/mp4/2018/06/27/2202032583/1530076464641/asset_1200K.mp4",
	"mediaType": "Extended Highlights" 
}

Note:

  • The opponent attribute can null if no game has been found
  • The url attribute can null if no condensed game stream has been found for the game
  • The mediaType attribute can null or “Extended Highlights” (I experimented with also getting the “Recap” for a while)

Configuration - Environment variables

  • MLBAPIRequest: The value to be sent in the header of any request

Monitoring function

This function saves the last found game data in an S3 bucket, and then is designed to run on a schedule to do the following:

  • Looks at date in saved game data JSON from the last successful run
  • If date is today, we’re done (we don’t cope with double-headers yet!)
  • Otherwise, call the condensed game function for either yesterday or today (if the last game was yesterday), and if the result has a url attribute
    • Save the latest game data JSON to S3
    • Call Slack sending the url attribute in a mesage
    • Call an IFTTT web hook that sends an iOS notification, clicking on which opens the viedo URL

You can setup a schedule in Cloudwatch to run every N minutes.

Configuration - Environment variables

  • S3ACCESSKEYID: Access Key for the S3 bucket to save game data
  • S3DATABUCKET: Name of the S3 bucket to save game data
  • S3DATAFILE: Name of the file to save game data in
  • S3SECRETACCESSKEY: Access Secret for the S3 bucket to save game data
  • SLACK_WEBHOOK_URL: URL of the webhook to send the Slack message to
  • TEAM: Team abbreviation to monitor e.g. nym
  • IFTTT_EVENT_NAME: Name of the IFTTT event to send the notification call to
  • IFTTT_MAKER_KEY: Name of the IFTTT maker key to enable IFTTT calls

Summary

Everything is working really well so far, and I’m getting exactly what I need. Very happy! I may still subscribe to MLB TV later in the season if I’m missing the weekend live games - or indeed if the Mets get in a playoff race - but for now I can keep wtaching the highlights without it.

The MLB “API” was a bit in flux for the first few weeks of the season. It’s not a public API so that’s to be expected, but hopefully it will be stable for a while now.

I also built an iOS Shortcut to call the API directly, so if for some reason the video URL changed, or I missed/deleted the notification by accident.

If you want to set something similar up for yourself and if the GitHub instructions aren’t clear, let me know and I’ll try to help you out!

MLB AWS Lambda