# iPhone Photo Inbox Local HTTP receiver for sending JPEGs from iPhone Shortcuts into Mac inboxes. The Shortcut sends a `profile`, and the Mac decides the destination folder and clipboard behavior. ## Profiles `opencode` - Saves to `ai/inbox/photos/` - Copies terminal-safe paths to the clipboard - Best for pasting into OpenCode running in a terminal `mattermost` - Saves to `~/Pictures/iPhone Inbox` - Copies native macOS file URLs to the clipboard - Best effort for pasting one or more files directly into Mattermost `general` - Saves to `~/Pictures/iPhone Inbox` - Does not modify the clipboard - Useful for plain capture All profiles show a macOS notification by default. ## Batch debounce Uploads are grouped by profile. Every new photo extends the active profile batch by 10 seconds and immediately refreshes the clipboard with the full batch. Example for `opencode`: ```text photo 1 arrives -> clipboard has photo 1 path photo 2 arrives within 10s -> clipboard has photo 1 + photo 2 paths photo 3 arrives within 10s -> clipboard has photo 1 + photo 2 + photo 3 paths 10s pass with no new photo -> notification says the batch is ready ``` This keeps the Shortcut simple while still making the clipboard usable before the final notification appears. For `mattermost`, each upload rewrites the clipboard with the full batch using a small Swift helper and `NSPasteboard.writeObjects`. This is closer to Finder's file-copy behavior than the older AppleScript alias approach. If the native helper fails, the receiver falls back to AppleScript and logs the fallback. ## Start the receiver Recommended: ```bash IPHONE_PHOTO_TOKEN="choose-a-token" python3 scripts/iphone-photo-inbox/receiver.py ``` The receiver listens on: ```text http://MAC_IP:8787/upload ``` Find the Mac IP address on the current network: ```bash ipconfig getifaddr en0 ``` If that does not return an IP, use: ```bash ifconfig ``` ## Shortcut config Use a Dictionary near the top of the Shortcut: ```text mac_ip: 192.168.11.186 port: 8787 token: choose-a-token profile: opencode ``` Build the URL from the dictionary: ```text http://[mac_ip]:[port]/upload?token=[token]&profile=[profile] ``` Use `profile: opencode` when the next paste target is OpenCode. Use `profile: mattermost` when the next paste target is Mattermost. ## Camera shortcut ```text Dictionary mac_ip: 192.168.11.186 port: 8787 token: choose-a-token profile: opencode Text http://[mac_ip]:[port]/upload?token=[token]&profile=[profile] Take Photo Show Camera Preview: On Get Contents of URL URL: Text Method: POST Request Body: File File: Photo Show Notification Sent to [profile] ``` On the tested iPhone flow, `Take Photo` already produces a JPEG, so no conversion step is needed. ## Existing photos shortcut Use this when sending existing images from Photos: ```text Receive Images and Media from Share Sheet Repeat with Each Item in Shortcut Input Convert Image Image: Repeat Item Format: JPEG Get Contents of URL URL: http://[mac_ip]:[port]/upload?token=[token]&profile=[profile] Method: POST Request Body: File File: Converted Image End Repeat Show Notification Sent to [profile] ``` ## Overrides Profile folders: ```bash IPHONE_PHOTO_OPENCODE_DIR="/path/to/opencode/photos" IPHONE_PHOTO_MATTERMOST_DIR="$HOME/Pictures/iPhone Inbox" IPHONE_PHOTO_GENERAL_DIR="$HOME/Pictures/iPhone Inbox" ``` Global folder override for all profiles: ```bash IPHONE_PHOTO_OUTPUT_DIR="$HOME/Pictures/iPhone Inbox" \ IPHONE_PHOTO_TOKEN="choose-a-token" \ python3 scripts/iphone-photo-inbox/receiver.py ``` Default profile when the URL does not include `profile=`: ```bash IPHONE_PHOTO_PROFILE=mattermost \ IPHONE_PHOTO_TOKEN="choose-a-token" \ python3 scripts/iphone-photo-inbox/receiver.py ``` Clipboard override for all profiles: ```bash IPHONE_PHOTO_CLIPBOARD=image IPHONE_PHOTO_CLIPBOARD=files IPHONE_PHOTO_CLIPBOARD=terminal-path IPHONE_PHOTO_CLIPBOARD=path IPHONE_PHOTO_CLIPBOARD=file IPHONE_PHOTO_CLIPBOARD=none ``` Debounce override: ```bash IPHONE_PHOTO_DEBOUNCE_SECONDS=5 ``` Other useful options: ```bash python3 scripts/iphone-photo-inbox/receiver.py --no-notify python3 scripts/iphone-photo-inbox/receiver.py --reveal IPHONE_PHOTO_DEBUG=1 python3 scripts/iphone-photo-inbox/receiver.py ``` ## Troubleshooting Startup should print each active profile: ```text profile opencode: dir=... clipboard=terminal-path notify=True reveal=False profile mattermost: dir=... clipboard=files notify=True reveal=False ``` After each upload, expect: ```text clipboard mode applied: terminal-path profile=opencode count=2 saved ... profile=opencode batch_count=2 ``` After the debounce window closes, expect: ```text batch notification sent profile=opencode count=2 batch finalized profile=opencode count=2 dir=... ``` The native file clipboard helper lives at: ```text scripts/iphone-photo-inbox/copy_files_to_clipboard.swift ``` For faster multi-file clipboard updates during debounce, compile it once: ```bash swiftc scripts/iphone-photo-inbox/copy_files_to_clipboard.swift \ -o scripts/iphone-photo-inbox/copy_files_to_clipboard ``` The compiled binary is ignored by git. If it is not present, the receiver can run the Swift script directly, but that is slower on first use. If files arrive but clipboard/notifications do not behave as expected, check: - The Shortcut URL includes the intended `profile=`. - The receiver log shows the expected profile. - With `IPHONE_PHOTO_DEBUG=1`, the Mattermost profile should report `pasteboard files=2 items=2` after the second photo in a two-photo batch. - macOS Focus/Do Not Disturb is not hiding notifications. - Terminal/Codex has permission for AppleScript automation if macOS prompts.