Connect apps and files
Build a Shortcut with a contract
Create a Shortcuts workflow that accepts files, transforms them, and returns output without depending on hidden prompts.
10 minute lesson
Time to build this module’s real workflow. Create a shortcut that accepts image files as input. Add actions to convert them to JPEG and save copies in a chosen test folder.
Open Shortcuts, create a new shortcut, and wire it like this:
receives: Images (from Quick Actions and the share sheet)
if there is no input: Stop and Respond ("no images received")
actions:
1. Convert Image -> to JPEG
2. Save File -> to ~/Pictures/prepared/, "Ask Where to Save" off
3. Stop and Output -> the saved files
Two of those settings are the contract, and both live in the input header at the top of the editor.
Set the accepted input type to images only. Everything else gets rejected at the door instead of failing halfway through the actions.
Then define what happens when no input arrives. Stop and Respond is the honest choice for automation: it fails loudly instead of opening a file picker. A shortcut that quietly waits for a human defeats the point of automating.
Finish with Stop and Output so another process can receive the result. Without it the shortcut still works when you click it, but it returns nothing useful to a caller — and in the next lesson we call it from the terminal.
Now test it. Use disposable images first. Keep the originals and choose a destination that cannot overwrite them. Run it with one image, then run it with the same image again: the second run reveals whether your Save File settings duplicate, overwrite, or rename on collision.
Verify each run two ways: the destination folder contains the JPEG copies you expected, and the output preview at the bottom of the editor shows the files the shortcut returned. If the destination is somewhere protected, the first run also triggers a permission prompt — approve it once, deliberately.
Rename the shortcut only after the workflow passes the same input twice. The name is part of the interface: scripts will call it by that exact string, so renaming it later is a breaking change for everything built on top.
Lesson completed