AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Automating Messages

skill-spillwavesolutions-automating-mac-apps-plugin-automating-messages · by SpillwaveSolutions

Automates macOS Messages (iMessage/SMS) via JXA with reliable service→buddy resolution. Use when asked to "automate iMessage", "send Messages via script", "JXA Messages automation", or "read Messages history". Covers send-bug workarounds, UI scripting for attachments, chat.db forensics, and launchd polling bots.

No reviews yet
0 installs
34 views
0.0% view→install

Install

$ agentstack add skill-spillwavesolutions-automating-mac-apps-plugin-automating-messages

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-spillwavesolutions-automating-mac-apps-plugin-automating-messages)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
8mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Automating Messages? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

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

Contents

  • [Permissions and scope](#permissions-and-scope)
  • [Default workflow](#default-workflow-happy-path)
  • [Quick recipe](#quick-recipe-defensive-send)
  • [Attachments and UI fallback](#attachments-and-ui-fallback)
  • [Data access and forensics](#data-access-and-forensics)
  • [Validation Checklist](#validation-checklist)
  • [When Not to Use](#when-not-to-use)
  • [What to load](#what-to-load)

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

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.