NYC

automating-messages

SKILL.md

Automating Messages (JXA-first with UI/DB fallbacks)

Contents

Permissions and scope

  • Grants needed: Automation + Accessibility; Full Disk Access for any chat.db reads.
  • Keep automation scoped and auditable; avoid unsolicited sends and DB writes.
  • Pairs with automating-mac-apps for common setup (permissions, osascript invocation, UI scripting basics).

Default workflow (happy path)

  1. Resolve transport: pick serviceType (iMessage or SMS) before targeting a buddy.
  2. Identify recipient: filter buddies by handle (phone/email). Avoid ambiguous names.
  3. Send via app-level send: pass Buddy object to Messages.send().
  4. Verify window context: activate Messages when mixing with UI steps.
  5. Fallbacks: if send/attachments fail, use UI scripting; for history, use SQL.

Quick recipe (defensive send)

const Messages = Application('Messages');
Messages.includeStandardAdditions = true;

function safeSend(text, handle, svcType = 'iMessage') {
  const svc = Messages.services.whose({ serviceType: svcType })[0];
  if (!svc) throw new Error(`Service ${svcType} missing`);
  const buddy = svc.buddies.whose({ handle })[0];
  if (!buddy) throw new Error(`Buddy ${handle} missing on ${svcType}`);
  Messages.send(text, { to: buddy });
}
  • Wrap with try/catch and log; add small delays when activating UI.
  • For groups, target an existing chat by GUID or fall back to UI scripting; array sends are unreliable.

Attachments and UI fallback

  • Messages lacks a stable JXA attachment API; use clipboard + System Events paste/send.
  • Ensure Accessibility permission, bring app forward, paste file, press Enter.
  • See references/ui-scripting-attachments.md for the full flow and ObjC pasteboard snippet.

Data access and forensics

Reading messages limitation: The AppleScript/JXA API for Messages is effectively write-only. While send() works reliably, reading messages via chat.messages() or similar methods is broken/unsupported in modern macOS. The only reliable way to read message history is via direct SQLite access to ~/Library/Messages/chat.db.

Security consideration: Reading chat.db requires Full Disk Access permission, which grants broad filesystem access beyond just Messages. This is a significant security trade-off - granting Full Disk Access to scripts or applications exposes all user data. Consider whether reading message history is truly necessary before enabling this permission.

  • Use SQL against chat.db for history; JXA chat.messages() is unreliable/non-functional.
  • Requires: System Settings > Privacy & Security > Full Disk Access for your terminal/script.
  • Remember Cocoa epoch conversion (nanoseconds since 2001-01-01); use sqlite3 -json for structured results.
  • See references/database-forensics.md for schema notes, typedstream handling, and export tooling.

Example read query (requires Full Disk Access):

sqlite3 ~/Library/Messages/chat.db "SELECT
  CASE WHEN m.is_from_me = 1 THEN 'Me' ELSE 'Them' END as sender,
  m.text,
  datetime(m.date/1000000000 + 978307200, 'unixepoch', 'localtime') as date
FROM message m
JOIN handle h ON m.handle_id = h.rowid
WHERE h.id LIKE '%PHONE_NUMBER%'
ORDER BY m.date DESC LIMIT 10;"

Bots and monitoring

  • Implement polling daemons with launchd now that on-receive handlers are gone.
  • Track rowid, query diffs, dispatch actions, and persist state.
  • See references/monitoring-daemons.md for the polling pattern and plist notes.

Validation Checklist

  • Automation + Accessibility permissions granted
  • Service resolves: Messages.services.whose({ serviceType: 'iMessage' })[0] returns object
  • Buddy lookup works: svc.buddies.whose({ handle })[0] returns target
  • Test send completes without errors
  • Full Disk Access granted if using chat.db reads

When Not to Use

  • For reading message history without Full Disk Access (AppleScript/JXA cannot read messages)
  • For cross-platform messaging (use platform APIs or third-party services)
  • For business SMS automation (use Twilio or similar APIs)
  • When iMessage/SMS features are not available on the target system
  • For bulk messaging (rate limits and security restrictions apply)
  • When security policy prohibits Full Disk Access grants (required for any read operations)

What to load

  • Control plane and send reliability: references/control-plane.md
  • UI scripting + attachments fallback: references/ui-scripting-attachments.md
  • SQL/history access: references/database-forensics.md
  • Polling bots/launchd: references/monitoring-daemons.md
Weekly Installs
4
First Seen
Feb 1, 2026
Installed on
claude-code4
opencode4
openclaw4
cline3
codebuddy3
cursor3