# Photo Inbox macOS HTTP receiver for sending JPEG uploads into a local photo inbox. Clients can be iPhone Shortcuts, curl, another phone, a script, or any system that can POST a JPEG file. The server currently supports macOS only because clipboard, Finder reveal, and notifications use macOS APIs/tools. By default, each upload is saved locally and the current batch is copied to the macOS clipboard as native file URLs. ## Behavior - Saves photos to `~/Pictures/Photo Inbox` by default. - Groups consecutive uploads into a batch. - Every new photo extends the batch by `5s`. - Every new photo immediately refreshes the clipboard with the full batch. - When no new photo arrives before debounce expires, a summary notification is shown. This uses a small Swift helper and `NSPasteboard.writeObjects`, which matches Finder-style file clipboard behavior. ## Start the receiver Recommended: ```bash cp scripts/iphone-photo-inbox/.env.example scripts/iphone-photo-inbox/.env scripts/iphone-photo-inbox/run.sh ``` `.env` is loaded automatically and does not override variables already exported in the shell. `run.sh` compiles the native pasteboard helper when it is missing or older than the Swift source. 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 ``` ## Generic client contract Send a JPEG request body: ```bash curl --request POST \ --data-binary @photo.jpg \ "http://MAC_IP:8787/upload?token=choose-a-token" ``` Successful response body is the saved local file path. ## iPhone Shortcuts guide Use a Dictionary near the top of the Shortcut: ```text mac_ip: 192.168.11.186 port: 8787 token: choose-a-token ``` Build the URL from the dictionary: ```text http://[mac_ip]:[port]/upload?token=[token] ``` Camera Shortcut: ```text Dictionary mac_ip: 192.168.11.186 port: 8787 token: choose-a-token Text http://[mac_ip]:[port]/upload?token=[token] Take Photo Show Camera Preview: On Get Contents of URL URL: Text Method: POST Request Body: File File: Photo Show Notification Sent to photo inbox ``` On the tested iPhone flow, `Take Photo` already produces a JPEG, so no conversion step is needed. Existing Photos Shortcut: ```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] Method: POST Request Body: File File: Converted Image End Repeat Show Notification Sent to photo inbox ``` ## Configuration Common `.env` values: ```bash PHOTO_INBOX_TOKEN=choose-a-token PHOTO_INBOX_HOST=0.0.0.0 PHOTO_INBOX_PORT=8787 PHOTO_INBOX_DIR=/Users/david/Pictures/Photo Inbox PHOTO_INBOX_DEBOUNCE_SECONDS=5 PHOTO_INBOX_CLIPBOARD=1 PHOTO_INBOX_NOTIFY=1 ``` Other useful options: ```bash scripts/iphone-photo-inbox/run.sh --no-clipboard scripts/iphone-photo-inbox/run.sh --no-notify scripts/iphone-photo-inbox/run.sh --reveal PHOTO_INBOX_DEBUG=1 scripts/iphone-photo-inbox/run.sh ``` ## Project integration Keep this utility as an isolated image mailbox. If a project wants easy access, link the project inbox to the mailbox instead of making this utility know about the project. Example: ```bash mkdir -p ai/inbox ln -s "$HOME/Pictures/Photo Inbox" ai/inbox/photos ``` Or point the receiver at a project-owned folder from `.env`: ```bash PHOTO_INBOX_DIR=/absolute/path/to/project/ai/inbox/photos ``` The symlink approach keeps this utility reusable across projects and devices. ## Troubleshooting Startup should print: ```text saving to: ... debounce seconds: 5 clipboard: True notify: True ``` After each upload, expect: ```text clipboard updated count=2 saved ... batch_count=2 ``` After the debounce window closes, expect: ```text batch notification sent count=2 batch finalized count=2 dir=... ``` With `PHOTO_INBOX_DEBUG=1`, a two-photo batch should report: ```text pasteboard files=2 items=2 ``` The native file clipboard helper lives at: ```text scripts/iphone-photo-inbox/copy_files_to_clipboard.swift ``` The compiled binary is ignored by git and generated by `run.sh`: ```text scripts/iphone-photo-inbox/copy_files_to_clipboard ```