Building a Local SMS Sync Daemon for Samsung Devices: Architecture & Implementation

Over the past development session, I implemented a local SMS synchronization system that bridges Samsung Android devices with a macOS daemon, eliminating the need for cloud SMS providers like Twilio for certain use cases. This post details the technical architecture, implementation decisions, and lessons learned.

Problem Statement

The existing SMS infrastructure relied on Twilio credentials stored server-side, creating operational friction: credentials weren't in the development environment, SMS workflows required external API calls, and there was no local fallback for SMS access. The goal was to create a self-contained, daemon-based SMS reader that could query local Android backup data or direct device connections.

Technical Architecture

The solution consists of three core components:

  • SMS Extraction Script: /Users/cb/Documents/repos/tools/samsung_sms_sync.py — Python script that queries SMS data sources and exports structured message threads
  • LaunchAgent Daemon: /Users/cb/Library/LaunchAgents/com.cb.samsung-sms-sync.plist — macOS system daemon configuration for scheduled or triggered SMS syncs
  • Integration Layer: Hooks into existing email (SES), conversation tracking, and digest systems

Implementation Details

Samsung SMS Data Sources

During development, I investigated three potential SMS data sources:

  • Mac Messages Database: ~/Library/Messages/chat.db — SQLite database containing iMessage threads, but limited to Apple ecosystem
  • Android Backup Files: Samsung backup containers stored locally or in cloud sync folders
  • ADB (Android Debug Bridge): Direct connection to Samsung devices via USB to query the telephony.db database
  • KDE Connect / Similar Bridges: Linux-based tools for Android-macOS message synchronization

The investigation revealed that a local JADA SMS export file already existed in the repository, suggesting previous SMS export infrastructure. The script was designed to read from this source first, then fallback to direct device queries if available.

Daemon Configuration (LaunchAgent)

The LaunchAgent plist was configured with the following structure:

<?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>300</integer>
  <key>StandardOutPath</key>
  <string>/var/log/samsung-sms-sync.log</string>
  <key>StandardErrorPath</key>
  <string>/var/log/samsung-sms-sync.err</string>
</dict>
</plist>

Key decisions:

  • StartInterval: 300 seconds — 5-minute sync cycle balances freshness with system load. Adjustable based on message volume
  • StandardOutPath/StandardErrorPath — Logs written to /var/log/ for system-level monitoring and debugging
  • User vs. System LaunchAgent — Placed in ~/Library/LaunchAgents/ (user scope) rather than /Library/LaunchDaemons/ (system scope) to avoid permission elevation while maintaining access to user files

SMS Script Workflow

The samsung_sms_sync.py script implements the following workflow:

  • Source Detection: Check for local SMS export file, then ADB device connection, with fallback error handling
  • Message Parsing: Extract phone numbers, timestamps, message content, and thread grouping from raw database or export format
  • Deduplication: Compare against existing message store (via local cache or database) to avoid duplicate syncs
  • Filtering & Digest Generation: Extract conversations matching date ranges or phone number patterns (e.g., recent SMS from specific contacts like Sergio)
  • Email Dispatch: Use existing SES integration to send formatted digests to configured recipients

Integration with Existing Infrastructure

Rather than building isolated SMS infrastructure, the solution plugged into existing systems:

  • SES Email Integration: Reused the SES client already configured in voice agent scripts to send SMS digests
  • Conversation Headers: Extracted from existing active handoffs file to maintain context (e.g., who was contacted, when, for what purpose)
  • Notes Directory: Cross-referenced with notes/ directory structure to associate SMS with business context (clients, projects, dates)

Key Decisions & Trade-offs

Local-First Over Cloud SMS: Twilio credentials weren't readily available in development, but local device data was. This approach trades cloud reliability for operational simplicity and zero API costs.

Daemon-Based vs. Manual Export: LaunchAgent automation eliminates manual SMS export steps and enables near-real-time digest updates. The 5-minute interval was chosen to balance responsiveness with avoiding SMS database locks during active phone use.

Python Implementation: Chosen for rapid prototyping and compatibility with existing SES/email infrastructure already written in Python. Could be rewritten in Go or Rust for production if performance becomes critical.

File-Based SMS Export Fallback: Rather than requiring live ADB connection, the script defaults to reading the existing local SMS export file, removing the dependency on physical device connection or driver installation.

What's Next

Future enhancements include:

  • Database Persistence: Move from file-based message tracking to SQLite to improve deduplication and enable historical queries
  • Multi-Device Support: Extend script to sync multiple phone numbers or Android devices simultaneously
  • Webhook Triggers: Instead of fixed intervals, trigger syncs on phone USB connection or webhook from mobile app
  • Message Search: Build CLI interface to query SMS by phone number, date range, or keyword without full digest output
  • Encryption: Add encrypted storage for SMS messages at