-
Notifications
You must be signed in to change notification settings - Fork 94
Description
Summary
When using imsg history --json or imsg watch --json, messages from group chats do not include an is_group field. This makes it impossible for consumers to distinguish group messages from direct messages based on the JSON output alone.
Current Behavior
{
"id": 1234,
"chat_id": 4,
"sender": "user@example.com",
"text": "Hello",
"is_from_me": false,
"guid": "ABC-123",
"created_at": "2026-02-16T12:00:00.000Z",
"attachments": [],
"reactions": []
}No is_group field is present, regardless of whether the message is from a group chat or a DM.
Expected Behavior
Messages should include is_group: true for group chats and is_group: false for DMs:
{
"id": 1234,
"chat_id": 4,
"sender": "user@example.com",
"text": "Hello",
"is_from_me": false,
"is_group": true,
"guid": "ABC-123",
"created_at": "2026-02-16T12:00:00.000Z",
"attachments": [],
"reactions": []
}Root Cause
The macOS Messages SQLite database (chat.db) stores chat type in the chat.style column:
- Style 43 = group chat (multi-party)
- Style 45 = direct message (1:1)
This information is available via a JOIN between the message, chat_message_join, and chat tables, but imsg does not currently expose it in the JSON output.
Suggested Fix
When building the JSON output for a message, JOIN against the chat table and set is_group based on chat.style:
SELECT
m.*,
CASE WHEN c.style = 43 THEN 1 ELSE 0 END AS is_group
FROM message m
JOIN chat_message_join cmj ON m.ROWID = cmj.message_id
JOIN chat c ON cmj.chat_id = c.ROWIDThen include "is_group": true/false in the JSON output.
Impact
Downstream consumers (automation tools, bots, AI gateways) that process iMessage via imsg cannot reliably determine if a message came from a group chat. They must resort to workarounds like maintaining a separate config-based allowlist of known group chat IDs.
Environment
- imsg version: 0.4.0
- macOS: 15.x (Sequoia)
- Architecture: arm64 (Apple Silicon)