See upcoming global rocket launches


I'm somewhat of a space geek, and like to know about what's headed into space. There's a great site called that tracks as many launches as they can find out about.

The site is great, but a friend and I were talking about using Keyboard Maestro to parse their data into something that could be viewed with a couple keystrokes. My buddy found the JSON feed, and extracted a summary blurb about the next launch and used a "Display Text Briefly" to show the summary blurb:

That took a simple one-action Execute Shell Script (Display Text Briefly) action, although you had to have the jq JSON decoder installed:

curl | /full/path/to/jq -c --raw-output  '.result[] | .launch_description'

And while that worked, I didn't like having to do the UTC conversion. I wondered if I could convert the UTC into my local time, and display that instead. One thing led to another, and eventually, the above simple one-action macro turned into something that generates this...

Now I can see that the SpaceX Falcon Heavy launches tonight at 5:14pm my time, as well as info on the next five launches in total, including launch location information. (Five is the limit for the free JSON feed.)

If you hover over any row and click, the selected launch's details (on will open in your browser. The macro also (optionally, on by default) compares the list it just created with the last list it created, and lets you know (via the obvious message in the lower right corner) if there were changes since the last time you looked.

So, yea, I did a bit more than just adjust the time zone :man_shrugging:…I guess I was having too much fun playing around with the JSON data.


Upcoming rocket launches.kmmacros (56 KB)

Macro Screenshot


Change tracking

The "tell me if anything has changed" feature is optional, as it does marginally slow down the macro: In my testing, using live data, the "don't tell me about changes" version runs in about 0.085 seconds. With the change tracking enabled, it takes 0.110 seconds.

For me, that slight delay is worth knowing whether there are new or changed launches on the schedule. If you'd rather not see this, all you have to do is change on variable from TRUE to FALSE (or anything else, actually). Instructions are in the macro.

The image above shows what it looks like when there are changes; here are the other two possible looks:

No changes since last check

Change tracking disabled

How the macro works

The macro grabs the data via JSON from, then just basically creates the HTML formatted results by looping through each of the five items in the JSON data set.

The only real "work" that has to be done is to convert UTC to local time. (I also stick the URL into a variable with its associated HTML, just to make reading the HTML code a bit easier.)

The macro is quite basic, and you could do a lot more with it if you wanted to (reminder of an upcoming launch based on a time check?). But it serves as a nice overview of working with JSON data and creating a table-based HTML form using that data.

If you'd like to play around with the formatting or JSON stuff, please enable the included STATIC TEST DATA group and disable the LIVE DATA FEED group while testingβ€”you don't need to hit their server with requests while testing things out. Once you have it working like you want, swap back to the live data feed.

This is definitely not a productivity-enhancing macro, but it does provide some interesting info if you like watching rocket launches. And from a macro perspective, it taught me a lot about working with JSON data, and how relatively easy it is once I got over the initial "huh, what is this stuff?" reaction.



This is a very cool macro. Thanks for sharing. Hoping to learn some new (for me) methods for JSON manipulation and HTML prompts.

Never say that, because I took those words as a challenge. Here's my attempt to improve things. ("Improve" may be a subjective word here. :slight_smile: )

I did things a little differently from you. I wanted to solve this without downloading "jq" or anything else. And I wanted to figure out how to convert UTC to EST using a cheaper solution. I succeeded, but with the caveat that my program will sometimes output an odd looking time like "-1:00 PM" which means one hour before noon. So if you see a negative time, that means you have to realize what that means. If you live near the prime meridian, you won't see negative times very often, but if you live in Australia, you will see negative numbers more frequently.

There are only 5 actions in this macro that do any work. And that could be reduced to 3 by removing the For Each actions and placing their output directly in the 5th action. But it just felt more intelligent to use those For Each actions.

Rocket Launches Macro (v11.0.1)

Rocket Launches.kmmacros (6.5 KB)

1 Like

OK, I tried but failed to get your macro to do anything, other than output a text block that has the basic info in it. It fails on the last step, trying to run sed on rockets.txt because (obviously) I don't have that file.

The output I do get shows the UTC time, and no pad information, and also some mission information:

I'm intrigued by how this is working, but I don't think it's fully working on my system. It's also way over my head on the processing side :), which may be related to why it's not working.


Let me check. Thanks for the feedback. It should have converted those UTC times to your time zone, but I can see it didn't.

Oh right, the file contains two green-colored blocks. You have to put a temporary file name in those blocks. I thought that would be clear from the title of the two green actions, which said they should be edited.

I noticed a cosmetic bug. Once you make that fix, the output will say EST instead of the three letter acronym for your time zone. For me, EST means local time. For now, just interpret EST as a phrase meaning "local time".

KM has a function called GMTOFFSET(), which this macro uses, but I don't think KM has anything to return the name of the local time zone, like EST, so I just hardcoded EST by mistake. Does anyone know how to retrieve the acronym for the time zone?

If you issue the DATE command in a terminal the timezone is shown at the end of the returned string, which should be fairly easy to split off in KM with a regex or similar.

4 posts were split to a new topic: How do you determine a location?

Here's the problem: I failed to notice the v11 field on your download, and my main Mac still use v10. (Because so many of my macros are distributed, I don't yet want to include any 11-only features, so I develop on the 10.x Mac and test on both it and my 11.x MBP.) So here's what I saw in your macro:

Nothing about a file at all :).


FYI, I have rewritten my version of the macro to work without needing jq installed. Both versions are now linked in the first post.

Both take about the same amount of time to run (under a half second); the second is just a bit harder to follow as it does a fair bit of regex manipulation.


FYI #2:

The macro has now been completely rewritten to simply process the JSON. No more regex (well, one or two small ones to work with the date/time conversion). No more variables. It's much smaller, much much faster, and has a new feature:

Each row will highlight when hovered; click to open the site showing the details for the selected launch.

If you used any of the old versions of this macro, I strongly recommend installing this version instead.

Also, if you're curious about processing JSON in Keyboard Maestro , this is a pretty simple macro to read through. One thing that helped me tremendously was adding a Display Text in Window action, right below the STATIC TEST DATA section (which is what I used to develop, obviously). Set it to display this token:


That will generate a window filled with text like this:

  "count" : 5,
  "last_page" : 27,
  "limit" : 5,
  "result" : [
      "cospar_id" : "",
      "date_str" : "Dec 12",
      "and more stuff, etc." : "etc",

I copied that into a text editor, and used it to figure out the JSON references.

For example, %JSONValue%local_theLaunches.result[3].name% would return the mission name for the third result. Each level of indentation is another field, so to get the fourth launch's launch pad country, you'd use this construct:


You can see all these constructs in the macro; I found it started to make sense to me after some playing around with trying to pull selected results from the JSON in a test macro.



What follows is an esoteric discussion on converting times in the most expedient way possible…added here mainly to document why I did what I did :).

Launch times in the JSON data stream are returned in Coordinated Universal Time (UTC) format, in an ISO8601-formatted string that looks like this: 2023-12-11T10:30:00Z. To convert that to local time, the macro has to split it into its individual parts for use in the TIME function. Up until now, this ugly looking regex did that:

The value from the TIME () function is then used with %ICUDateTimeFor% to get the user's local time, and put in a format that lets me split it into two parts for the final table format:

This struck me as probably the biggest slowdown spot in the macro–that's a lot of text processing it has to do for all five of the launches. So my friend and I spent some time today trying alternatives:

  • Using a one-liner bash script to calculate the unixtime value.
  • Using the Substring action to split the text, instead of a regular expression.
  • Using JavaScript for Automation to calculate the unixtime value.

Somewhat surprisingly, all three of these methods were slower than my original solution. Not dramatically, but multiplied five times, they'd amount to a noticeable change in speed. Then I found this post by @peternlewis in the Convert ICUDateTime to Unixtime discussion.

He showed another method of dealing with the calculations, so I tried a variation on that method.

It still uses regex, but not to split out separate variables. Instead, it just reformats the text into the format needed by the TIME() function, then (as shown in the linked thread) sets a variable to the text of the calculation I need to do, then uses the Filter action to actually do that calculation:

(The same final two steps are used, as shown above, to get it ready for use in the table.) As it turned out, this method saves about 0.05 seconds per loop, or roughly a quarter of a second overall.


It may not sound like much, but when the entire macro runs in just over a second, it's a pretty good improvement:

This version of the macro is now linked in the first article above.


1 Like

What about the comment at the top of the green macro which says "CHOOSE A FILE to save your data"? To me, that says something about a file. I even used CAPS to make sure people would see it.

Right, but what I'm saying is that in KM10, you can't do that:


Versus the same action in KM11:



Oh, I'm very sorry. I had no idea that this was a v11 change. I just use whatever options I see.

1 Like

Knowing now what it should have looked like, I could have just added a step to write it to a file, but I had no idea what was supposed to happen :).

I wish the KM editor offered some way to see what's new in the latest release, i.e. maybe new actions are in green, or optionally you can disable all new features? Not an issue for most people, but given I share a fair number of my macros, I don't want to make them (especially accidentally) only work with 11 just yet.


A new version today adds an (optional, enabled by default) feature:

When enabled, the macro saves a copy of the HTML each time it runs (to /tmp, where it'll be automatically cleaned out every so often if not used). It then runs a diff to find out if anything has changed, and if so, the above box appears on the launch table (see full screenshot in the first post). When done, it moves the 'new' HTML file to the 'old' HTML file, so it's ready for the next run.

I wanted an easy way to know if anything had changed since I last asked for the schedule, and this gets the job done with only a minimal speed hitβ€”it still runs in about a tenth of a second, give or take.

It's linked in the first post. (Hindsight: I guess I should've included my macro updater routine in this macro, but I didn't think I'd be working on it this much :slight_smile: ).


Updated macro linked in the first post. It turns out that sometimes the launch time returns "null," which messed up the table pretty badly. Now such returns are adjusted for: