Per-feature pages (install, quickstart, permissions, chats, history, watch, send, groups, attachments, json, rpc, completions, advanced-imcore, troubleshooting) plus an Apple-styled static-site builder rendering them to dist/docs-site. GitHub Pages workflow deploys on every docs/ change to imsg.sh.
3.5 KiB
| title | description |
|---|---|
| Attachments | Attachment metadata, resolved paths, and optional model-friendly conversion for CAF audio and GIF images. |
imsg reports attachment metadata only. It never copies, modifies, or uploads the underlying files. Optional conversion exposes cached, model-friendly variants for CAF audio and GIF images.
Reading attachments
imsg history --chat-id 42 --attachments --json
imsg watch --chat-id 42 --attachments --json
Each message gains an attachments array. Per-attachment fields:
| Field | Type | Notes |
|---|---|---|
filename |
string | Stored filename inside Messages' attachments dir. |
transfer_name |
string | Original filename as sent. |
uti |
string | Apple Uniform Type Identifier. |
mime_type |
string | Best-effort MIME from UTI. |
byte_size |
int | Size in bytes. |
is_sticker |
bool | True for sticker-pack attachments. |
missing |
bool | True when the file couldn't be located on disk. |
path |
string | Resolved absolute path under ~/Library/Messages/Attachments/. |
converted_path |
string | Set only with --convert-attachments; see below. |
converted_mime_type |
string | Set only with --convert-attachments. |
When an attachment is referenced in chat.db but the underlying file has been pruned (Messages can age out big files), missing is true and path may be empty.
Converted variants
imsg history --chat-id 42 --attachments --convert-attachments --json
imsg watch --chat-id 42 --attachments --convert-attachments --json
This adds converted_path and converted_mime_type to attachments where conversion is supported:
- CAF audio → M4A. Messages' on-device voice memos are stored as CAF; most LLMs and downstream tools want M4A.
- GIF image → first-frame PNG. Useful when a static thumbnail is enough for downstream models.
Originals are never modified. Converted files live alongside in a cache directory and are reused on subsequent reads.
--convert-attachments requires ffmpeg on PATH. If ffmpeg is missing, the command still succeeds — converted_path is simply omitted from the output and the original metadata is unchanged.
brew install ffmpeg to enable.
Sending attachments
imsg send --to "+14155551212" --file ~/Desktop/photo.jpg
imsg send --to "Jane Appleseed" --file ~/Desktop/voice.m4a
imsg send --chat-id 42 --file ~/Desktop/note.pdf
--file accepts any regular file. Audio files (.m4a, .caf, .aiff, …) ride the same code path as images and documents.
Before invoking AppleScript, imsg stages the file under ~/Library/Messages/Attachments/imsg/. Messages reads attachments from inside its own attachments directory more reliably than from ~/Desktop or ~/Downloads, particularly under newer macOS sandboxing.
The staged copies live under imsg/, distinct from Messages' own subdirectories, and are not pruned automatically. Clear them periodically if disk space matters.
Why not just copy or upload?
The CLI's contract is "read what's there, send what you give it." Anything beyond that — bulk archival, cloud upload, format conversion at rest — is left to callers, who know their retention and privacy requirements. The conversion feature is the one exception, and only because some receive-side formats (CAF, animated GIF) are awkward for downstream tools to handle.
If you want a full archive workflow, pipe --attachments --json through your own scripts and copy the files out of ~/Library/Messages/Attachments/ yourself.