Building a Local SMS Sync Bridge: Integrating Samsung Messages with macOS LaunchAgent Automation
Over the past development session, I built out a local SMS synchronization system that bridges Samsung device messages with macOS automation, eliminating the need for external SMS services like Twilio for certain workflows. This post covers the architecture, implementation decisions, and operational patterns we discovered.
What Was Done
The core objective was simple: read SMS messages from a Samsung device and make them queryable on a macOS development machine without relying on cloud-based SMS APIs. This required:
- Creating a Python sync script at
/Users/cb/Documents/repos/tools/samsung_sms_sync.py - Setting up a macOS LaunchAgent at
/Users/cb/Library/LaunchAgents/com.cb.samsung-sms-sync.plist - Understanding existing SMS infrastructure (Twilio integrations, voice agent SMS capabilities)
- Discovering and leveraging a pre-existing JADA SMS export file as the canonical message source
- Building digest workflows to summarize conversations by contact
Technical Architecture
SMS Data Sources
The investigation revealed three potential SMS data paths:
- Twilio API: Referenced in
phone_agent.pyand voice agent infrastructure, but credentials not available in local.envfiles - macOS Messages.app: Available via AppleScript and the
chat.dbSQLite database, but limited to iMessage/SMS received on the development machine - Local SMS Export File: Pre-existing export from the Samsung device, regularly updated and accessible as a canonical message log
The key insight was recognizing that a local export file already existed and was being maintained. Rather than adding complexity through ADB (Android Debug Bridge) connections or Twilio API calls, we leveraged this existing data source.
Python Sync Script Design
The samsung_sms_sync.py script handles three primary functions:
- Message Parsing: Read the exported SMS file and parse individual conversations by phone number
- State Management: Track which messages have been processed and when (to avoid duplicate digests)
- Digest Generation: Summarize recent conversations and deliver via email using AWS SES
#!/usr/bin/env python3
# Core workflow pattern:
# 1. Read SMS export file
# 2. Parse conversations by phone number
# 3. Filter messages by date range (e.g., last 24 hours)
# 4. Extract key conversation threads
# 5. Format digest and send via SES
LaunchAgent Configuration
The com.cb.samsung-sms-sync.plist file implements daemon automation:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.cb.samsung-sms-sync</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/Users/cb/Documents/repos/tools/samsung_sms_sync.py</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
<key>StandardOutPath</key>
<string>/var/log/samsung_sms_sync.log</string>
<key>StandardErrorPath</key>
<string>/var/log/samsung_sms_sync_error.log</string>
</dict>
</plist>
The StartInterval of 3600 seconds (1 hour) balances freshness with system load. This runs the sync script hourly in the background.
Key Technical Decisions
Why Not Use Twilio Directly?
The voice agent infrastructure uses Twilio for SMS capabilities, but integrating it into local development workflows required credentials that weren't readily available in the development environment. The existing export file provided a more reliable local source of truth without external API dependencies, network latency, or rate limits.
Why Not Use ADB / Android Debug Bridge?
Initial investigation into ADB connectivity (android-platform-tools via Homebrew) revealed additional complexity: USB connection stability, permissions configuration, and device-specific SMS database formats. The local export file was already normalized and regularly updated, making it a lower-friction option for development and testing.
Why LaunchAgent Over Cron?
macOS LaunchAgent provides better integration with system logging, environment variables, and error handling compared to traditional cron jobs. It also respects macOS security frameworks and system sleep states more gracefully.
Operational Patterns Discovered
During the session, we built out several operational patterns:
- Conversation Querying: Extract messages by phone number and date range to build contact-specific digests
- Email Delivery: Use AWS SES to send formatted digests to
c.b.ladd@gmail.comwhen output exceeds 30 lines (operational threshold) - Thread Extraction: Parse multi-day conversations and identify action items (payments, equipment needs, confirmations)
- State Tracking: Maintain a last-processed timestamp to avoid re-sending identical digests
Infrastructure Integration Points
The sync system integrates with existing infrastructure:
- AWS SES: Used for digest delivery (credentials configured in
.secrets/repos.env) - Local repos structure: SMS export file lives alongside other tools in
/Users/cb/Documents/repos/tools/ - Existing voice agent code: Can reference processed SMS data without rebuilding the ingestion layer
- System logging: Output routed to
/var/log/samsung_sms_sync*.logfor debugging
What's Next
Future refinements could include:
- Real-time sync: Move from hourly polling to file-watch triggers when the export file updates
- SQLite integration: Store parsed messages in a local database for more complex querying and historical analysis
- Conversation context enrichment