Skip to content

Add iMessage sync support#224

Open
vanboompow wants to merge 1 commit intowesm:mainfrom
vanboompow:imessage-upstream
Open

Add iMessage sync support#224
vanboompow wants to merge 1 commit intowesm:mainfrom
vanboompow:imessage-upstream

Conversation

@vanboompow
Copy link
Copy Markdown

Summary

  • New sync-imessage command that reads macOS ~/Library/Messages/chat.db and imports messages into msgvault
  • Implements gmail.API interface over SQLite chat.db for plug-and-play integration with existing sync infrastructure
  • Uses existing SourceType field in sync.Options (added by IMAP support)

New files

  • internal/imessage/client.go - gmail.API implementation over chat.db
  • internal/imessage/parser.go - MIME builder, timestamp conversion
  • internal/imessage/models.go - chat.db row types
  • internal/imessage/parser_test.go - tests for parsing utilities
  • cmd/msgvault/cmd/sync_imessage.go - CLI command

Usage

msgvault sync-imessage

Tested against macOS Messages database with ~10k conversations.

Implement a sync-imessage command that reads from macOS's
~/Library/Messages/chat.db and imports messages into the msgvault
archive using the existing sync infrastructure.

New files:
- internal/imessage/client.go: gmail.API implementation over chat.db
- internal/imessage/parser.go: MIME builder, timestamp conversion
- internal/imessage/models.go: chat.db row types
- internal/imessage/parser_test.go: tests for parsing utilities
- cmd/msgvault/cmd/sync_imessage.go: CLI command

Uses existing SourceType field in sync.Options (added by IMAP support).
@roborev-ci
Copy link
Copy Markdown

roborev-ci bot commented Mar 26, 2026

roborev: Combined Review (0508613)

Summary Verdict: Adds a new sync-imessage client but contains high-severity data loss issues regarding missing attachments and attributedBody parsing, alongside bugs
with date filtering and nil pointer dereferences.

High

  • internal/imessage/client.go:266 and 295

    • Problem: The importer only reads message.text. Many Messages DB rows keep the visible text only in
      attributedBody when text is NULL, so those messages will be archived as blank messages with empty snippets.
    • Fix: Select attributedBody and decode it as a fallback whenever message.text is null; add coverage for rows where only attributedBody is populated.
  • internal/imessage/client.go:258 and 301

    • Problem: cache_has_attachments is fetched but never used, and the code never reads the attachment tables or emits MIME parts for them. Messages with photos/
      files/stickers will therefore be imported without their attachments, silently losing data.
    • Fix: Read attachment metadata via the join tables and feed attachment content through the existing archive pipeline, or fail/warn explicitly until attachment support is implemented.

Medium

  • cmd/msgvault/ cmd/sync_imessage.go:80 and 88

    • Problem: --after and --before are parsed with time.Parse, which treats YYYY-MM-DD as midnight UTC. On a local macOS CLI this shifts the intended day boundary
      for non-UTC users, causing messages around midnight local time to be included or excluded incorrectly.
    • Fix: Parse date-only filters with time.ParseInLocation(..., time.Local) so filtering matches the user’s local calendar day.
  • internal/imessage/client .go:340

    • Problem: GetMessagesRawBatch pre-allocates the results slice and continues on errors, leaving nil entries in the slice. This may cause nil pointer dereferences when the caller iterates over the results.
  • Fix: Initialize var results []*gmail.RawMessage and append(results, msg) for successfully fetched messages.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant