< Back to list of posts

I Built a Mac Shortcut to Parse School Flyers

This weekend project started when my wife asked me if I could help her build something to manage the constant flood of emails and flyers she was getting daily. Between school announcements, sports schedules, and after-school activities, she was drowning in event notifications. Every day brought another handful of dates and times that needed to get onto our family calendar, and she was spending way too much time manually entering everything.

Turns out there is a better way, and it involves a little automation.

The Problem

Schools love paper flyers. Picture days, bake sales, field trips, parent-teacher conferences. They all come home as crumpled pieces of paper in a backpack. Add to that the emails with attached PDFs and image files of event announcements, and you've got an overwhelming amount of information to process. My wife got in the habit of photographing the paper ones, which is smart, but then someone still had to actually put these events on the calendar. She'd carved out time each evening just to go through everything and manually create calendar entries, and it was eating up her day.

The Solution

I figured if I could take a photo of a flyer and have it automatically create a calendar event, that would solve everything. Mac Shortcuts can do this, but it took some trial and error to get it working properly.

PicCalConvert Shortcut Screenshot showing the PicCalConvert shortcut

Here's what I built:

Step 1: Getting the Photo In

First thing was adding a way to grab photos. I used the Select Photos action in Shortcuts because we already had pictures of most flyers. You could use Take Photo if you wanted to capture them on the spot, but honestly, the photo library route made more sense for us.

Step 2: Reading the Text

This part was easier than I expected. There's a built-in Extract text from photo action that uses OCR to pull all the text out of an image. I just dragged it into the workflow and connected it to the photo input. Mac's text recognition is actually pretty solid these days. It handled different fonts and even slightly blurry photos better than I thought it would.

Step 3: The ChatGPT Integration (Where Things Got Interesting)

Here's where I had to get creative. Raw text from a flyer is a mess. Dates are written as Mon 3/15 or March 15th at 2pm or sometimes just next Friday. I needed something that could look at that jumble and figure out what was actually important.

I decided to use ChatGPT's API because it's pretty good at understanding context. The setup was more involved than I'd like:

I added a Get Contents of URL action and pointed it at OpenAI's API endpoint.

The configuration looked like this:

  • URL: https://api.openai.com/v1/chat/completions
  • Method: POST
  • Headers: One for Content-Type: application/json, another for Authorization: Bearer [my-api-key]
  • Request Body: This is where it got fiddly

API Configuration Screenshot showing ChatGPT API configuration in Shortcuts

Step 4: Crafting the JSON Request

The Request Body uses a visual dictionary editor now, which is both better and worse than raw JSON. Better because it's less likely to have syntax errors, worse because it crashes sometimes when you're building complex structures.

I basically told ChatGPT: Here's a bunch of text from an event flyer. Give me back structured data in this exact format. The system prompt was important. I had to emphasize that it should ONLY return JSON, no extra commentary, and to use reasonable defaults if information was missing.

The hardest part was handling dates. Flyers write dates in every format imaginable. I told ChatGPT to be flexible with formats and default to tomorrow's date if nothing was clear, which worked surprisingly well.

Step 5: Parsing the Response

ChatGPT sends back a nested JSON structure, so I had to chain together four Get Dictionary Value actions to drill down through: choices0messagecontent. This gave me the actual JSON string with the event details.

Then I used Get Dictionary from Input to convert that JSON text back into something Shortcuts could work with.

Step 6: Extracting Individual Fields

At this point I had structured data, so I added six more Get Dictionary Value actions to pull out:

- Title
- Date
- Time
- Location
- Duration
- Notes

Each one grabs its specific piece of information from the parsed response.

Step 7: The Date/Time Problem

This was honestly the most annoying part. Shortcuts wants a proper date object, but I had separate date and time strings. I ended up using a Text action to combine them (date + space + time + space + AM/PM), then Get Dates from Input to parse that into an actual date object.

Step 8: Creating the Calendar Event

Finally, the payoff. I added "Event" and mapped all my variables to the appropriate fields: title, location, start date, notes. Duration gets set from what ChatGPT parsed (defaulting to 60 minutes).

Step 9: Confirmation

Threw in a Show Notification at the end so we'd know it worked. Nothing fancy, just Event created: [event title] so there's immediate feedback.

What I Learned

The OCR is better than I expected. Even with mediocre photo quality, it pulls out text reliably.

ChatGPT is overkill but worth it. I could've written a bunch of regex patterns to parse dates and times, but honestly, that would've taken forever and broken constantly. Paying a few cents per API call to have ChatGPT figure it out was way easier.

Shortcuts crashes sometimes. Particularly when editing complex JSON in the Request Body. If you run into this, build your JSON in a separate Text action and pass that as the body instead.

Date handling is always the hard part. Every time. Always.

Does It Actually Work?

Yeah, surprisingly well. My wife now just runs the shortcut when she photographs a flyer or saves an image from an email, and the event shows up on our shared family calendar. What used to take her 20-30 minutes each evening now takes seconds. She's gotten that time back to actually, you know, relax after dealing with everything else.

The only gotcha is you need an OpenAI API key, which requires an account and costs a tiny bit per request. I've probably spent $2 total over three months of use. Worth it to give my wife back her evenings.

Shortcut flow{:class="gif"} Screen recording showing Shortcut flow

The Code (Sort of)

I can't paste the actual Shortcut file here, but if you're trying to build this yourself, the key is structuring your ChatGPT prompt correctly. Tell it exactly what JSON format you want back, emphasize that it should ONLY return JSON (no explanatory text), and give it rules for handling missing information.

The system prompt I used was something like: "You're an expert at parsing event information. Always respond with ONLY valid JSON. If info is missing, use reasonable defaults. Dates should be YYYY-MM-DD, times should be HH:MM with separate AM/PM field."

And the user prompt was: Extract event details from this text and respond ONLY with valid JSON in this exact format: {title, date, time, ampm, location, duration, notes}. Rules: [various rules for handling edge cases]. Text: [the extracted text]

Would I Recommend This?

If you're drowning in school event flyers and you're comfortable with basic API setup, absolutely. It took me an afternoon to build and debug, but it's saved way more time than that already.

Plus, there's something deeply satisfying about pointing your phone at a piece of paper and watching a calendar event magically appear. My wife was skeptical at first about whether it would actually work reliably, but now she uses it for everything. Not just school events, but community stuff, kids' sports schedules, you name it.

Technology should make life easier. This actually does.

Buy Me A Coffee