Building a Local SMS Sync Agent: Bridging Samsung Messages to macOS Without Twilio
This post documents the engineering decisions and implementation details behind building a standalone SMS synchronization tool that aggregates messages from multiple sources—including a Samsung device—without relying on external SMS gateways like Twilio.
Problem Statement
The existing SMS infrastructure in our codebase relied on Twilio credentials for message retrieval and sending. However, we needed to:
- Read historical SMS from a Samsung device without Twilio API calls
- Aggregate SMS across multiple phone numbers and sources
- Run as a background daemon on macOS using launchd
- Export conversations in a queryable format for digest generation
- Minimize external service dependencies
The existing SMS export at /Users/cb/Library/Mobile\ Documents/com\~apple\~CloudDocs/Documents/jada_sms_export.txt provided conversation history but lacked real-time sync capability and automation.
Technical Architecture
File Structure & Components
We created two primary artifacts:
/Users/cb/Documents/repos/tools/samsung_sms_sync.py— The main synchronization engine/Users/cb/Library/LaunchAgents/com.cb.samsung-sms-sync.plist— The launchd daemon configuration
The Python script handles:
- Reading the static SMS export file as the source of truth
- Parsing conversation threads with phone numbers and timestamps
- Filtering messages by date range (e.g., April 25-29)
- Extracting specific conversation threads (e.g., +15302623442, Sergio's number)
- Generating structured digest emails via AWS SES
Integration Points with Existing Infrastructure
Rather than building a full Android bridge, we leveraged existing resources:
- SMS Export File: Static file containing historical Samsung messages previously exported and stored in iCloud Drive
- Twilio Credentials: Located in
.secrets/repos.env(referenced but not required for this implementation) - AWS SES: Used for sending digest emails via existing voice agent infrastructure
- Voice Agent SMS Handlers:
phone_agent.pycontains SMS capability logic we could reference
Implementation Details
SMS Export Parsing
The export file uses a structured format with conversation headers and message entries:
Phone: +15302623442
Name: Hostess Name
---
[timestamp] Your text here
[timestamp] Their response
---
Phone: +16194164690
Name: Another Contact
---
[timestamp] Message content
Our parser extracts these sections using regex and structured line parsing, handling:
- Multi-line message bodies
- Variable timestamp formats
- Contact name inconsistencies
- Chronological ordering within threads
Conversation Filtering & Digesting
We implemented hierarchical filtering:
- Date Range Filter: Extract messages within April 25-29 window (parameterized)
- Contact-Specific Filter: Isolate Sergio's full thread for deep analysis
- Context Preservation: Include conversation headers (phone, name, last activity)
- Digest Generation: Summarize key themes, action items, and financial data
The digest email identifies:
- High-priority items requiring immediate response
- Financial transactions and amounts
- Equipment/operational issues
- Schedule-critical events
- Contact-specific action items
Daemon Configuration
The launchd plist at /Users/cb/Library/LaunchAgents/com.cb.samsung-sms-sync.plist defines:
<?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>StandardErrorPath</key>
<string>/var/log/samsung-sms-sync.err</string>
<key>StandardOutPath</key>
<string>/var/log/samsung-sms-sync.out</string>
</dict>
</plist>
Key design decisions:
- StartInterval: 3600 — Runs hourly; can be reduced for more frequent sync
- Log files: Standard output/error to
/var/log/for operational visibility - No RunAtLoad: Launches on schedule, not at boot, reducing startup load
AWS SES Integration
Email delivery uses the existing SES client from the voice agent infrastructure:
- Sender: Configured identity verified in AWS SES console
- Recipients: Default to
c.b.ladd@gmail.com(configurable) - HTML Body: Formatted digest with headers, bullet points, and structured data
- Plain Text Fallback: Readable plaintext version for compatibility
The script constructs email via boto3 client:
client.send_email(
Source='noreply@sailjada.com',
Destination={'ToAddresses': ['c.b.ladd@gmail.com']},
Message={
'Subject': {'Data': 'SMS Digest: April 25-29'},
'Body': {'Html': {'Data': html_body}, 'Text': {'Data': text_body}}
}
)
Key Engineering Decisions
Why Not Use Twilio for This?
Twilio would add API call overhead, rate