You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(adr): add @mention parsing details and group chat limitations
- Add §6.1 explaining how mentions are stored in attributedBody blob
- Compare mention detection across platforms (Discord/LINE/Slack/iMessage)
- Clarify implications for Phase 1 (1:1) vs Phase 5 (group)
- Update open question #3 with recommendation to defer group chat
- Add @mention parsing to Phase 5 scope
Copy file name to clipboardExpand all lines: docs/adr/imessage-integration.md
+29-2Lines changed: 29 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -220,6 +220,33 @@ impl ChatAdapter for IMessageAdapter {
220
220
- No threading (conversations are flat)
221
221
- Reactions map to tapbacks (❤️, 👍, 👎, 😂, ‼️, ❓) — only 6 options
222
222
- No typing indicators via AppleScript (Spectrum Cloud supports this)
223
+
- No structured @mention field (see §6.1 below)
224
+
225
+
### 6.1 @Mention Detection (Group Chat)
226
+
227
+
iMessage supports @mentions (iOS 14+, displayed as bold blue text), but `chat.db` does **not** expose them as a structured column. The mention data is embedded inside the `attributedBody` blob — a serialized `NSAttributedString` (NSKeyedArchiver / typedstream format).
228
+
229
+
**To extract mentions, the bridge must:**
230
+
231
+
1. Read `message.attributedBody` (binary blob)
232
+
2. Decode NSKeyedArchiver binary plist
233
+
3. Locate ranges where `__kIMMessagePartAttributeName` = 1 (indicates a mention)
234
+
4. Extract the mentioned handle ID from `__kIMMentionConfirmedMention`
235
+
236
+
**Comparison with other platforms:**
237
+
238
+
| Platform | Mention detection | Complexity |
239
+
|----------|-------------------|-----------|
240
+
| Discord |`message.mentions` array | Trivial — structured field |
241
+
| LINE |`mentionees` in webhook payload | Trivial — structured field |
242
+
| Slack |`<@BOT_ID>` in text + `app_mention` event type | Easy — text pattern |
243
+
| iMessage | Parse binary `attributedBody` blob | Hard — undocumented binary format |
244
+
245
+
**Implications for group chat:**
246
+
-**1:1 conversations (Phase 1):** No mention detection needed — all messages are directed at the bot
247
+
-**Group chat (Phase 5):** Bridge must parse `attributedBody` to know when the bot is mentioned, or fall back to keyword-prefix trigger (e.g. `/ask ...`)
248
+
- The `attributedBody` format is undocumented and may change across macOS versions — Rust `plist` crate can decode the binary plist, but the internal schema requires reverse-engineering
249
+
-**Outbound:** AppleScript `send` does not support sending @mentions — bot replies are plain text only
@@ -321,7 +348,7 @@ Apple does not provide an official iMessage API. All known approaches rely on:
321
348
|---|----------|---------|-------|
322
349
| 1 | Bridge language | Rust (consistent with OAB) vs TypeScript (reuse imessage-kit) | Rust preferred for single-binary deployment |
323
350
| 2 | Poll interval default | 100ms vs 200ms vs 500ms | Tradeoff: latency vs CPU. agy-acp uses 100ms |
324
-
| 3 | Group chat support in Phase 1? | Yes / defer to Phase 5 |Groups add complexity (participant tracking)|
351
+
| 3 | Group chat support in Phase 1? | Yes / defer to Phase 5 |Recommend defer — no structured @mention field means bot can't reliably detect when addressed. 1:1 is the sweet spot.|
325
352
| 4 | Should bridge run as launchd service? | Yes (auto-restart) / manual | launchd is macOS best practice for daemons |
0 commit comments