Skip to content

drewburchfield/shortcuts-toolkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Shortcuts Toolkit πŸ› οΈ

Comprehensive toolkit for generating Apple Shortcuts programmatically

This repository documents the reverse-engineered process of creating Apple Shortcuts files (.shortcut) that can be imported into the Shortcuts app across iOS, iPadOS, and macOS.

πŸ€” The Problem

Apple's Shortcuts app is incredibly powerful, but there's no official API or documentation for creating shortcut files programmatically. The official methods are:

  • Manual creation in the Shortcuts app
  • Sharing via iCloud links
  • Using the Shortcuts URL scheme (limited)

This leaves developers unable to generate shortcuts dynamically for their users.

🎯 The Solution

Through reverse engineering and testing, we've discovered the file format and structure requirements for creating importable .shortcut files.

πŸ“ File Format

iOS Shortcuts are stored as binary property list (bplist) files with a specific structure:

.shortcut file
β”œβ”€β”€ WFWorkflow (Dictionary)
β”‚   β”œβ”€β”€ WFWorkflowClientRelease (String): iOS version
β”‚   β”œβ”€β”€ WFWorkflowClientVersion (String): Shortcuts app version
β”‚   β”œβ”€β”€ WFWorkflowIcon (Dictionary): Icon configuration
β”‚   β”œβ”€β”€ WFWorkflowImportQuestions (Array): Import-time questions
β”‚   β”œβ”€β”€ WFWorkflowInputContentItemClasses (Array): Accepted inputs
β”‚   β”œβ”€β”€ WFWorkflowMinimumClientVersion (Integer): Min supported version
β”‚   β”œβ”€β”€ WFWorkflowMinimumClientVersionString (String): Min version string
β”‚   β”œβ”€β”€ WFWorkflowOutputContentItemClasses (Array): Output types
β”‚   β”œβ”€β”€ WFWorkflowHasOutputFallback (Boolean): Fallback behavior
β”‚   β”œβ”€β”€ WFWorkflowTypes (Array): Shortcut types
β”‚   β”œβ”€β”€ WFWorkflowHasShortcutInputVariables (Boolean): Input variables
β”‚   └── WFWorkflowActions (Array): The actual actions

πŸ” The Format Secret

The key discovery: Shortcuts files must use a specific binary format to be recognized as valid by iOS:

// The magic format header that makes it work
const SHORTCUT_FILE_HEADER = Buffer.from([
  0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30  // "bplist00"
]);

This is the standard binary property list header (bplist00). The entire file must be properly structured as a binary plist with the correct WFWorkflow hierarchy for iOS to accept it. There's no cryptographic signing involved - just following Apple's undocumented format requirements.

πŸ’» Implementation

Node.js Example

const bplist = require('bplist-creator');
const fs = require('fs');

function createShortcut(name, url, apiKey) {
  const shortcut = {
    WFWorkflow: {
      WFWorkflowClientRelease: "18.0",
      WFWorkflowClientVersion: "1302.1.3",
      WFWorkflowIcon: {
        WFWorkflowIconStartColor: 4282601983,
        WFWorkflowIconGlyphNumber: 61440
      },
      WFWorkflowImportQuestions: [],
      WFWorkflowInputContentItemClasses: [
        "WFURLContentItem",
        "WFTextContentItem"
      ],
      WFWorkflowMinimumClientVersion: 1300,
      WFWorkflowMinimumClientVersionString: "1300",
      WFWorkflowOutputContentItemClasses: [],
      WFWorkflowHasOutputFallback: false,
      WFWorkflowTypes: ["ActionExtension", "MenuBar"],
      WFWorkflowHasShortcutInputVariables: true,
      WFWorkflowActions: [
        {
          WFWorkflowActionIdentifier: "is.workflow.actions.url",
          WFWorkflowActionParameters: {
            WFURLActionURL: url
          }
        },
        {
          WFWorkflowActionIdentifier: "is.workflow.actions.downloadurl",
          WFWorkflowActionParameters: {
            WFHTTPMethod: "POST",
            WFHTTPHeaders: {
              "X-API-Key": apiKey,
              "Content-Type": "application/json"
            },
            WFHTTPBodyType: "JSON",
            WFJSONBody: {
              url: "{ShortcutInput}",
              source: "shortcut"
            }
          }
        }
      ]
    }
  };

  // Convert to binary plist
  const buffer = bplist(shortcut);
  
  // Save as .shortcut file
  fs.writeFileSync(`${name}.shortcut`, buffer);
}

Python Example

import plistlib
import struct

def create_shortcut(name, url, api_key):
    shortcut = {
        'WFWorkflow': {
            'WFWorkflowClientRelease': '18.0',
            'WFWorkflowClientVersion': '1302.1.3',
            'WFWorkflowIcon': {
                'WFWorkflowIconStartColor': 4282601983,
                'WFWorkflowIconGlyphNumber': 61440
            },
            'WFWorkflowImportQuestions': [],
            'WFWorkflowInputContentItemClasses': [
                'WFURLContentItem',
                'WFTextContentItem'
            ],
            'WFWorkflowMinimumClientVersion': 1300,
            'WFWorkflowMinimumClientVersionString': '1300',
            'WFWorkflowOutputContentItemClasses': [],
            'WFWorkflowHasOutputFallback': False,
            'WFWorkflowTypes': ['ActionExtension', 'MenuBar'],
            'WFWorkflowHasShortcutInputVariables': True,
            'WFWorkflowActions': [
                {
                    'WFWorkflowActionIdentifier': 'is.workflow.actions.url',
                    'WFWorkflowActionParameters': {
                        'WFURLActionURL': url
                    }
                },
                {
                    'WFWorkflowActionIdentifier': 'is.workflow.actions.downloadurl',
                    'WFWorkflowActionParameters': {
                        'WFHTTPMethod': 'POST',
                        'WFHTTPHeaders': {
                            'X-API-Key': api_key,
                            'Content-Type': 'application/json'
                        },
                        'WFHTTPBodyType': 'JSON',
                        'WFJSONBody': {
                            'url': '{ShortcutInput}',
                            'source': 'shortcut'
                        }
                    }
                }
            ]
        }
    }
    
    # Write as binary plist
    with open(f'{name}.shortcut', 'wb') as f:
        plistlib.dump(shortcut, f, fmt=plistlib.FMT_BINARY)

🎨 Key Components

Action Identifiers

Common Shortcuts action identifiers:

  • is.workflow.actions.url - Get URL
  • is.workflow.actions.downloadurl - Download URL content
  • is.workflow.actions.openurl - Open URL
  • is.workflow.actions.text - Text action
  • is.workflow.actions.getclipboard - Get clipboard
  • is.workflow.actions.setclipboard - Set clipboard
  • is.workflow.actions.notification - Show notification
  • is.workflow.actions.runworkflow - Run another shortcut

Variables

Shortcuts support variables using special syntax:

  • {ShortcutInput} - Input passed to shortcut
  • {Clipboard} - Current clipboard content
  • {CurrentDate} - Current date/time

Input/Output Types

Content item classes for inputs/outputs:

  • WFURLContentItem - URLs
  • WFTextContentItem - Plain text
  • WFImageContentItem - Images
  • WFPDFContentItem - PDFs
  • WFWebPageContentItem - Web pages

πŸš€ Advanced Features

Import Questions

You can prompt users for configuration during import:

WFWorkflowImportQuestions: [
  {
    WFWorkflowImportQuestionType: "Text",
    WFWorkflowImportQuestionPrompt: "Enter your API key:",
    WFWorkflowImportQuestionDefaultValue: "",
    WFWorkflowImportQuestionVariable: "apiKey"
  }
]

Conditional Actions

Add if/else logic:

{
  WFWorkflowActionIdentifier: "is.workflow.actions.conditional",
  WFWorkflowActionParameters: {
    WFCondition: "Contains",
    WFConditionalIfTrueActions: [...],
    WFConditionalIfFalseActions: [...]
  }
}

Menu Actions

Create interactive menus:

{
  WFWorkflowActionIdentifier: "is.workflow.actions.menu",
  WFWorkflowActionParameters: {
    WFMenuItems: ["Option 1", "Option 2"],
    WFMenuItemActions: {
      "Option 1": [...],
      "Option 2": [...]
    }
  }
}

πŸ“± Distribution

Once generated, shortcuts can be distributed via:

  1. Direct download - Host .shortcut files on your server
  2. Base64 encoding - Embed in web pages
  3. Data URLs - Create downloadable links
  4. Email attachments - Send directly to users

Web Distribution Example

<!-- Create download link -->
<a href="data:application/x-shortcut;base64,YnBsaXN0MDDC..." 
   download="MyShortcut.shortcut">
  Download Shortcut
</a>

<!-- Or use JavaScript -->
<script>
function downloadShortcut(base64Data, filename) {
  const link = document.createElement('a');
  link.href = `data:application/x-shortcut;base64,${base64Data}`;
  link.download = filename;
  link.click();
}
</script>

πŸ” Reverse Engineering Notes

The format was discovered through:

  1. Exporting shortcuts from the Shortcuts app
  2. Analyzing the binary plist structure
  3. Testing various modifications
  4. Identifying required vs optional fields

Key findings:

  • Files must be valid binary plists
  • The WFWorkflow root key is required
  • Version strings affect compatibility
  • Some fields are validated, others ignored
  • The format has remained stable across iOS versions

⚠️ Limitations

  • No official documentation (may break in future iOS versions)
  • Cannot access all Shortcuts actions (some are private)
  • Cannot programmatically install (user must manually import)
  • No way to update existing shortcuts
  • Limited debugging capabilities

πŸ› οΈ Tools & Libraries

Node.js

  • bplist-creator - Create binary plists
  • bplist-parser - Parse binary plists

Python

  • plistlib - Built-in plist support
  • biplist - Advanced binary plist features

Online Tools

πŸ“š References

🀝 Contributing

This is community-driven documentation. If you discover new features or techniques, please contribute!

βš–οΈ Legal

This documentation is for educational purposes. Apple, iOS, and Shortcuts are trademarks of Apple Inc. This project is not affiliated with or endorsed by Apple.

πŸ™ Credits

Created through reverse engineering and community research to unlock the undocumented iOS Shortcuts file format.


Remember: This is unofficial and undocumented. Use at your own risk, and always test thoroughly before distributing shortcuts to users.

About

Comprehensive toolkit for generating Apple Shortcuts programmatically using reverse-engineered binary plist format.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors