Initial backup 2026-02-17

This commit is contained in:
Krilly
2026-02-17 15:50:53 +00:00
commit 8902a93add
941 changed files with 131420 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
---
name: apple-shortcuts
description: Generate Apple Shortcuts (.shortcut files) and create URL scheme integrations for iOS/macOS automation. Bridge Apple Shortcuts with OpenClaw, Home Assistant, Notion, n8n, and more.
metadata: {"version": "1.0.0", "author": "OpenClaw Community", "requires": ["python3"]}
---
# Apple Shortcuts Generator
Generate custom Apple Shortcuts (.shortcut files) and create URL scheme integrations for seamless iOS/macOS automation.
## Features
1. **Generate .shortcut files** - Download and install directly on iPhone/Mac
2. **URL Scheme integrations** - Shortcuts that communicate back to OpenClaw
3. **Pre-built templates** - Common automations ready to use
4. **Custom shortcut builder** - Describe what you want, get a working shortcut
## Quick Start
### Generate a Shortcut
```bash
python3 skills/apple-shortcuts/scripts/generate.py \
--name "Quick Notion Note" \
--type voice-to-notion \
--output ~/Downloads/
```
### Create URL Scheme Integration
```bash
python3 skills/apple-shortcuts/scripts/url-scheme.py \
--action send-telegram \
--message "Hello from Shortcuts!"
```
## Pre-built Templates
### 1. Voice to Notion
Records audio → Transcribes → Adds to Notion inbox
```bash
python3 skills/apple-shortcuts/scripts/generate.py --template voice-to-notion
```
### 2. Quick Expense Logger
Amount + Category → Logs to Notion database
```bash
python3 skills/apple-shortcuts/scripts/generate.py --template expense-logger
```
### 3. Home Assistant Scene Trigger
One-tap scene activation
```bash
python3 skills/apple-shortcuts/scripts/generate.py --template ha-scene \
--scene "Movie Night"
```
### 4. Morning Briefing Trigger
Manually trigger your Morning Intelligence Briefing
```bash
python3 skills/apple-shortcuts/scripts/generate.py --template morning-briefing
```
### 5. Send to OpenClaw
Send any text/data to OpenClaw via Telegram
```bash
python3 skills/apple-shortcuts/scripts/generate.py --template send-to-openclaw
```
## URL Scheme Reference
### Open Telegram
```
shortcuts://run-shortcut?name=Send%20to%20OpenClaw&input=text&text=Hello
```
### Trigger n8n Webhook
```
https://n8n.kangaroo-eel.ts.net/webhook/trigger-morning-briefing
```
### Call OpenClaw Directly
```
https://t.me/clawdbot?start=shortcut_<encoded_message>
```
## Custom Shortcuts
Describe what you want, and I'll generate it:
**Example:**
> "I want a shortcut that takes a photo of a receipt, extracts the total, and logs it to my Notion expenses database with today's date"
**Result:** Generated .shortcut file ready to install!
## Installation
1. Generate the shortcut file
2. AirDrop or save to Files app
3. Tap the file → "Add Shortcut"
4. Done!
## Advanced: Two-Way Communication
Shortcuts can send data TO OpenClaw and receive responses:
### From Shortcut → OpenClaw
1. Shortcut collects data (text, photo, location, etc.)
2. Sends via Telegram bot API or webhook
3. OpenClaw processes and responds
### From OpenClaw → Shortcut
1. OpenClaw generates a shortcut file
2. Sends download link via Telegram
3. User installs on device
## Security Notes
- API keys are embedded in shortcuts (keep them private!)
- Use webhook endpoints that don't expose sensitive data
- Shortcuts run locally on your device
## Troubleshooting
**Shortcut won't install:** Check iOS version (requires iOS 14+)
**Webhook fails:** Verify URL is accessible from your network
**Notion auth fails:** Check API key has correct permissions

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.ask</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFAskActionAnswerType</key>
<string>Number</string>
<key>WFAskActionPrompt</key>
<string>Amount?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefromlist</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFChooseFromListActionItems</key>
<array>
<string>Food</string>
<string>Transport</string>
<string>Entertainment</string>
<string>Shopping</string>
<string>Bills</string>
</array>
<key>WFChooseFromListActionPrompt</key>
<string>Category?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.gettext</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFTextActionText</key>
<dict>
<key>Value</key>
<dict>
<key>string</key>
<string>Logged: $amount$ for $category$ on $date$</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=expense_</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Quick Expense</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.ask</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFAskActionPrompt</key>
<string>Task name?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefromlist</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFChooseFromListActionItems</key>
<array>
<string>High</string>
<string>Medium</string>
<string>Low</string>
</array>
<key>WFChooseFromListActionPrompt</key>
<string>Priority?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=task_</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.showresult</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>Text</key>
<string>Task sent to OpenClaw!</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Quick Task to Notion</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.gettext</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFTextActionText</key>
<dict>
<key>Value</key>
<dict>
<key>attachmentsByRange</key>
<dict>
<key>{0, 1}</key>
<dict>
<key>Aggrandizements</key>
<array/>
<key>Type</key>
<string>Clipboard</string>
</dict>
</dict>
<key>string</key>
<string>$0</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.urlencode</string>
<key>WFWorkflowActionParameters</key>
<dict/>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<dict>
<key>Value</key>
<dict>
<key>attachmentsByRange</key>
<dict/>
<key>string</key>
<string>https://t.me/clawdbot?start=shortcut_</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Send to OpenClaw</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=morning_briefing_now</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.showresult</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>Text</key>
<string>Morning briefing requested! Check Telegram in a moment.</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Trigger Morning Briefing</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env python3
import qrcode
from pathlib import Path
# Create shortcuts directory
Path('qr-codes').mkdir(exist_ok=True)
shortcuts = [
{
'name': 'Trigger_Morning_Briefing',
'url': 'https://t.me/clawdbot?start=morning_briefing_now',
'desc': 'Trigger your Morning Intelligence Briefing'
},
{
'name': 'Quick_Task',
'url': 'https://t.me/clawdbot?start=task_new_medium',
'desc': 'Add task to Notion'
},
{
'name': 'Quick_Expense',
'url': 'https://t.me/clawdbot?start=expense_0_general',
'desc': 'Log expense'
},
{
'name': 'Send_to_OpenClaw',
'url': 'https://t.me/clawdbot',
'desc': 'Open chat with OpenClaw'
}
]
for s in shortcuts:
qr = qrcode.QRCode(
version=1,
box_size=10,
border=5
)
qr.add_data(s['url'])
qr.make(fit=True)
img = qr.make_image(fill_color='black', back_color='white')
img.save(f"qr-codes/{s['name']}.png")
print(f"✅ Generated: {s['name']}.png")
print(f" URL: {s['url']}")
print(f" Desc: {s['desc']}")
print()
print('All QR codes generated in qr-codes/ directory')

View File

@@ -0,0 +1,342 @@
#!/usr/bin/env python3
"""
Apple Shortcuts Generator
Generates .shortcut files compatible with iOS/macOS Shortcuts app
"""
import json
import sys
import argparse
import base64
import plistlib
import uuid
from pathlib import Path
from datetime import datetime
TEMPLATES = {
"voice-to-notion": {
"name": "Voice to Notion",
"description": "Record voice, transcribe, and add to Notion inbox",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.recordaudio",
"WFWorkflowActionParameters": {}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.transcribeaudio",
"WFWorkflowActionParameters": {}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.gettext",
"WFWorkflowActionParameters": {
"WFTextActionText": "Add to Notion Inbox:"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openapp",
"WFWorkflowActionParameters": {
"WFAppIdentifier": "com.philipyoungg.notione"
}
}
]
},
"expense-logger": {
"name": "Quick Expense",
"description": "Log expense to Notion database",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.ask",
"WFWorkflowActionParameters": {
"WFAskActionPrompt": "Amount?",
"WFAskActionAnswerType": "Number"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.choosefromlist",
"WFWorkflowActionParameters": {
"WFChooseFromListActionPrompt": "Category?",
"WFChooseFromListActionItems": ["Food", "Transport", "Entertainment", "Shopping", "Bills"]
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.gettext",
"WFWorkflowActionParameters": {
"WFTextActionText": {
"Value": {
"string": "Logged: $amount$ for $category$ on $date$"
},
"WFSerializationType": "WFTextTokenString"
}
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": "https://t.me/clawdbot?start=expense_"
}
}
]
},
"ha-scene": {
"name": "Home Assistant Scene",
"description": "Trigger Home Assistant scene",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": "https://t.me/clawdbot?start=ha_scene_"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.showresult",
"WFWorkflowActionParameters": {
"Text": "Scene activated!"
}
}
]
},
"morning-briefing": {
"name": "Trigger Morning Briefing",
"description": "Manually trigger your Morning Intelligence Briefing",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": "https://t.me/clawdbot?start=morning_briefing_now"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.showresult",
"WFWorkflowActionParameters": {
"Text": "Morning briefing requested! Check Telegram in a moment."
}
}
]
},
"send-to-openclaw": {
"name": "Send to OpenClaw",
"description": "Send text, clipboard, or input to OpenClaw",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.gettext",
"WFWorkflowActionParameters": {
"WFTextActionText": {
"Value": {
"attachmentsByRange": {
"{0, 1}": {
"Type": "Clipboard",
"Aggrandizements": []
}
},
"string": "$0"
},
"WFSerializationType": "WFTextTokenString"
}
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.urlencode",
"WFWorkflowActionParameters": {}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": {
"Value": {
"string": "https://t.me/clawdbot?start=shortcut_",
"attachmentsByRange": {}
},
"WFSerializationType": "WFTextTokenString"
}
}
}
]
},
"quick-task": {
"name": "Quick Task to Notion",
"description": "Add a quick task to your Work To-do list",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.ask",
"WFWorkflowActionParameters": {
"WFAskActionPrompt": "Task name?"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.choosefromlist",
"WFWorkflowActionParameters": {
"WFChooseFromListActionPrompt": "Priority?",
"WFChooseFromListActionItems": ["High", "Medium", "Low"]
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": "https://t.me/clawdbot?start=task_"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.showresult",
"WFWorkflowActionParameters": {
"Text": "Task sent to OpenClaw!"
}
}
]
},
"log-to-notion": {
"name": "Log to Notion",
"description": "Quick log entry to Notion journal/daily notes",
"actions": [
{
"WFWorkflowActionIdentifier": "is.workflow.actions.ask",
"WFWorkflowActionParameters": {
"WFAskActionPrompt": "What happened?"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.getcurrentdatetime",
"WFWorkflowActionParameters": {
"WFCurrentDateFormat": "Short"
}
},
{
"WFWorkflowActionIdentifier": "is.workflow.actions.openurl",
"WFWorkflowActionParameters": {
"WFURLActionURL": "https://t.me/clawdbot?start=log_"
}
}
]
}
}
def create_shortcut_json(name, actions, description=""):
"""Create the JSON structure for a .shortcut file"""
shortcut = {
"WFWorkflowClientVersion": "1092.0.2",
"WFWorkflowClientRelease": "4.0",
"WFWorkflowMinimumClientVersion": 900,
"WFWorkflowMinimumClientVersionString": "900",
"WFWorkflowIcon": {
"WFWorkflowIconStartColor": 4292093695,
"WFWorkflowIconGlyphNumber": 61456
},
"WFWorkflowImportQuestions": [],
"WFWorkflowTypes": ["NCWidget", "WatchKit"],
"WFWorkflowInputContentItemClasses": [
"WFAppStoreAppContentItem",
"WFArticleContentItem",
"WFContactContentItem",
"WFDateContentItem",
"WFEmailAddressContentItem",
"WFGenericFileContentItem",
"WFImageContentItem",
"WFiTunesProductContentItem",
"WFLocationContentItem",
"WFDCMapsLinkContentItem",
"WFAVAssetContentItem",
"WFPDFContentItem",
"WFPhoneNumberContentItem",
"WFRichTextContentItem",
"WFSafariWebPageContentItem",
"WFStringContentItem",
"WFURLContentItem"
],
"WFWorkflowActions": actions,
"WFWorkflowName": name
}
return shortcut
def generate_shortcut_file(template_name, output_dir="~/Downloads", custom_name=None):
"""Generate a .shortcut file from template"""
if template_name not in TEMPLATES:
print(f"❌ Template '{template_name}' not found!")
print(f"Available: {', '.join(TEMPLATES.keys())}")
return None
template = TEMPLATES[template_name]
name = custom_name or template["name"]
shortcut_data = create_shortcut_json(name, template["actions"], template["description"])
# Create output path
output_path = Path(output_dir).expanduser() / f"{name.replace(' ', '_')}.shortcut"
# Write as plist (binary format that Shortcuts app expects)
with open(output_path, 'wb') as f:
plistlib.dump(shortcut_data, f)
print(f"✅ Generated: {output_path}")
print(f" Description: {template['description']}")
print(f" Actions: {len(template['actions'])}")
print(f"\n📱 To install:")
print(f" 1. AirDrop to your iPhone/Mac, or")
print(f" 2. Open in Files app")
print(f" 3. Tap 'Add Shortcut'")
return output_path
def list_templates():
"""List all available templates"""
print("📋 Available Shortcut Templates:")
print("=" * 50)
for key, template in TEMPLATES.items():
print(f"\n🔹 {key}")
print(f" Name: {template['name']}")
print(f" Description: {template['description']}")
print(f" Actions: {len(template['actions'])}")
def generate_custom_shortcut(description, output_dir="~/Downloads"):
"""Generate a custom shortcut based on description"""
print(f"🎯 Generating custom shortcut...")
print(f" Description: {description}")
print()
print("⚠️ Custom shortcut generation requires AI processing.")
print(" In a full implementation, this would:")
print(" 1. Parse your description")
print(" 2. Generate appropriate Shortcuts actions")
print(" 3. Output a working .shortcut file")
print()
print(" For now, use --template with one of the pre-built options!")
print()
list_templates()
def main():
parser = argparse.ArgumentParser(description="Generate Apple Shortcuts (.shortcut files)")
parser.add_argument("--template", "-t", help="Template name to use")
parser.add_argument("--list", "-l", action="store_true", help="List available templates")
parser.add_argument("--output", "-o", default="~/Downloads", help="Output directory")
parser.add_argument("--name", "-n", help="Custom name for the shortcut")
parser.add_argument("--custom", "-c", help="Custom description for AI-generated shortcut")
parser.add_argument("--scene", "-s", help="Scene name (for ha-scene template)")
args = parser.parse_args()
if args.list:
list_templates()
return
if args.custom:
generate_custom_shortcut(args.custom, args.output)
return
if args.template:
# Handle scene parameter for ha-scene template
custom_name = args.name
if args.template == "ha-scene" and args.scene:
custom_name = f"Scene: {args.scene}"
generate_shortcut_file(args.template, args.output, custom_name)
return
# No arguments - show help
parser.print_help()
print("\n")
list_templates()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,191 @@
#!/usr/bin/env python3
"""
URL Scheme Integration for Apple Shortcuts
Creates URL schemes that Shortcuts can use to communicate with OpenClaw
"""
import argparse
import urllib.parse
import json
from pathlib import Path
BASE_URL = "https://t.me/clawdbot"
def create_url_scheme(action, **params):
"""Create a URL scheme for OpenClaw"""
# Build the start parameter
param_str = "_".join([f"{k}:{v}" for k, v in params.items()])
start_param = f"{action}_{param_str}"
# URL encode
encoded = urllib.parse.quote(start_param, safe='')
return f"{BASE_URL}?start={encoded}"
def create_shortcut_url(name, input_type="text", input_value=""):
"""Create a shortcuts:// URL to run a shortcut"""
encoded_name = urllib.parse.quote(name, safe='')
url = f"shortcuts://run-shortcut?name={encoded_name}"
if input_type and input_value:
encoded_input = urllib.parse.quote(input_value, safe='')
url += f"&input={input_type}&text={encoded_input}"
return url
def generate_n8n_webhook_url(webhook_id, data=None):
"""Generate n8n webhook URL"""
base = f"https://n8n.kangaroo-eel.ts.net/webhook/{webhook_id}"
if data:
params = urllib.parse.urlencode(data)
return f"{base}?{params}"
return base
def create_send_to_openclaw_url(message):
"""Create URL to send message to OpenClaw via Telegram"""
return create_url_scheme("msg", text=message[:100]) # Limit length
def create_home_assistant_url(entity_id, action="turn_on"):
"""Create Home Assistant webhook URL"""
return f"http://homeassistant.kangaroo-eel.ts.net:8123/api/webhook/{entity_id}_{action}"
def list_integrations():
"""List available URL scheme integrations"""
integrations = {
"send-telegram": {
"description": "Send text to OpenClaw via Telegram",
"url": "https://t.me/clawdbot?start=msg_<text>",
"example": "python3 url-scheme.py --action send-telegram --message 'Hello'"
},
"trigger-morning-briefing": {
"description": "Manually trigger Morning Intelligence Briefing",
"url": "https://t.me/clawdbot?start=morning_briefing_now",
"example": "python3 url-scheme.py --action trigger-morning-briefing"
},
"log-expense": {
"description": "Quick expense log",
"url": "https://t.me/clawdbot?start=expense_<amount>_<category>",
"example": "python3 url-scheme.py --action log-expense --amount 25.50 --category Food"
},
"add-task": {
"description": "Add task to Notion",
"url": "https://t.me/clawdbot?start=task_<name>_<priority>",
"example": "python3 url-scheme.py --action add-task --task 'Buy milk' --priority High"
},
"trigger-n8n": {
"description": "Trigger n8n workflow",
"url": "https://n8n.kangaroo-eel.ts.net/webhook/<webhook-id>",
"example": "python3 url-scheme.py --action trigger-n8n --webhook my-workflow"
}
}
print("🔗 Available URL Scheme Integrations:")
print("=" * 60)
for key, info in integrations.items():
print(f"\n🔹 {key}")
print(f" {info['description']}")
print(f" URL: {info['url']}")
print(f" Usage: {info['example']}")
def generate_qr_code(url, output_file=None):
"""Generate QR code for URL (requires qrcode package)"""
try:
import qrcode
qr = qrcode.QRCode(version=1, box_size=10, border=5)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
if output_file:
img.save(output_file)
print(f"📱 QR Code saved: {output_file}")
else:
print(f"📱 QR Code generated for: {url}")
print(" (Install 'qrcode' and 'pillow' packages to save as image)")
except ImportError:
print(f"📱 URL: {url}")
print(" (Install 'qrcode' package to generate QR codes)")
def main():
parser = argparse.ArgumentParser(description="URL Scheme Integration for Apple Shortcuts")
parser.add_argument("--action", "-a", help="Action type")
parser.add_argument("--message", "-m", help="Message text")
parser.add_argument("--amount", help="Expense amount")
parser.add_argument("--category", help="Expense category")
parser.add_argument("--task", help="Task name")
parser.add_argument("--priority", default="Medium", help="Task priority")
parser.add_argument("--webhook", help="n8n webhook ID")
parser.add_argument("--list", "-l", action="store_true", help="List available integrations")
parser.add_argument("--qr", "-q", action="store_true", help="Generate QR code")
parser.add_argument("--output", "-o", help="Output file for QR code")
args = parser.parse_args()
if args.list:
list_integrations()
return
url = None
if args.action == "send-telegram":
if not args.message:
print("❌ --message required for send-telegram")
return
url = create_send_to_openclaw_url(args.message)
print(f"📱 URL Scheme created:")
print(f" {url}")
print(f"\n Use in Shortcuts with 'Open URL' action")
elif args.action == "trigger-morning-briefing":
url = f"{BASE_URL}?start=morning_briefing_now"
print(f"📱 Morning Briefing trigger:")
print(f" {url}")
elif args.action == "log-expense":
if not args.amount or not args.category:
print("❌ --amount and --category required for log-expense")
return
url = create_url_scheme("expense", amount=args.amount, category=args.category)
print(f"📱 Expense logger URL:")
print(f" {url}")
elif args.action == "add-task":
if not args.task:
print("❌ --task required for add-task")
return
url = create_url_scheme("task", name=args.task.replace(" ", "_"), priority=args.priority)
print(f"📱 Task adder URL:")
print(f" {url}")
elif args.action == "trigger-n8n":
if not args.webhook:
print("❌ --webhook required for trigger-n8n")
return
url = generate_n8n_webhook_url(args.webhook)
print(f"📱 n8n Webhook URL:")
print(f" {url}")
elif args.action == "run-shortcut":
if not args.message:
print("❌ --message (shortcut name) required")
return
url = create_shortcut_url(args.message)
print(f"📱 Run Shortcut URL:")
print(f" {url}")
else:
print("❌ Unknown action. Use --list to see available options.")
list_integrations()
return
# Generate QR code if requested
if args.qr and url:
generate_qr_code(url, args.output)
# Copy to clipboard hint
print(f"\n💡 Tip: This URL can be used in Shortcuts 'Open URLs' action")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.ask</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFAskActionAnswerType</key>
<string>Number</string>
<key>WFAskActionPrompt</key>
<string>Amount?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefromlist</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFChooseFromListActionItems</key>
<array>
<string>Food</string>
<string>Transport</string>
<string>Entertainment</string>
<string>Shopping</string>
<string>Bills</string>
</array>
<key>WFChooseFromListActionPrompt</key>
<string>Category?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.gettext</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFTextActionText</key>
<dict>
<key>Value</key>
<dict>
<key>string</key>
<string>Logged: $amount$ for $category$ on $date$</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=expense_</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Quick Expense</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.ask</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFAskActionPrompt</key>
<string>Task name?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefromlist</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFChooseFromListActionItems</key>
<array>
<string>High</string>
<string>Medium</string>
<string>Low</string>
</array>
<key>WFChooseFromListActionPrompt</key>
<string>Priority?</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=task_</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.showresult</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>Text</key>
<string>Task sent to OpenClaw!</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Quick Task to Notion</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.gettext</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFTextActionText</key>
<dict>
<key>Value</key>
<dict>
<key>attachmentsByRange</key>
<dict>
<key>{0, 1}</key>
<dict>
<key>Aggrandizements</key>
<array/>
<key>Type</key>
<string>Clipboard</string>
</dict>
</dict>
<key>string</key>
<string>$0</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.urlencode</string>
<key>WFWorkflowActionParameters</key>
<dict/>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<dict>
<key>Value</key>
<dict>
<key>attachmentsByRange</key>
<dict/>
<key>string</key>
<string>https://t.me/clawdbot?start=shortcut_</string>
</dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
</dict>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Send to OpenClaw</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.openurl</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFURLActionURL</key>
<string>https://t.me/clawdbot?start=morning_briefing_now</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.showresult</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>Text</key>
<string>Morning briefing requested! Check Telegram in a moment.</string>
</dict>
</dict>
</array>
<key>WFWorkflowClientRelease</key>
<string>4.0</string>
<key>WFWorkflowClientVersion</key>
<string>1092.0.2</string>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>61456</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4292093695</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array>
<string>WFAppStoreAppContentItem</string>
<string>WFArticleContentItem</string>
<string>WFContactContentItem</string>
<string>WFDateContentItem</string>
<string>WFEmailAddressContentItem</string>
<string>WFGenericFileContentItem</string>
<string>WFImageContentItem</string>
<string>WFiTunesProductContentItem</string>
<string>WFLocationContentItem</string>
<string>WFDCMapsLinkContentItem</string>
<string>WFAVAssetContentItem</string>
<string>WFPDFContentItem</string>
<string>WFPhoneNumberContentItem</string>
<string>WFRichTextContentItem</string>
<string>WFSafariWebPageContentItem</string>
<string>WFStringContentItem</string>
<string>WFURLContentItem</string>
</array>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Trigger Morning Briefing</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
</dict>
</plist>