anthropics / anthropics/claude-plugins-official

imessage: self-chat silently dropped when self-chat handle (phone) differs from Apple ID account (email)

Đang mở
#4,503 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Python
Star
36.3k
Fork
4.1k
Merge trung bình
2 ngày 14 giờ
Pull request đã merge (30 ngày)
539

Mô tả

## Summary

The iMessage plugin silently drops **all** self-chat (Note-to-Self) messages when your self-chat is keyed by your **phone number** but your iMessage `account` identity is an **email** (the normal case for iPhone users). The README promises "self-chat bypasses access control," but in this configuration self-chat never bypasses anything — every message is dropped by the DM gate.

`external_plugins/imessage/server.ts`, v0.1.0, macOS.

## Root cause

`SELF` is built only from the `account` column of your sent messages:

```
// server.ts ~L181
SELECT DISTINCT account AS addr FROM message WHERE is_from_me = 1 AND account IS NOT NULL AND account != '' LIMIT 50
```

The `account` column holds your Apple ID **sending** identity, which for most people is an email (e.g. `E:you@example.com`). But a Note-to-Self chat is very commonly keyed by your **phone number** (`+1XXXXXXXXXX`), and that number never appears in `account`. So:

```
// server.ts L804
const isSelfChat = !isGroup && SELF.has(sender.toLowerCase()) // sender = "+1XXXXXXXXXX", SELF = {"you@example.com"} -> false
```

`isSelfChat` is `false`, so the message falls through to the DM gate, and with the default empty allowlist it is dropped:

```
// server.ts ~L333-335
if (!input.isGroup) {
if (access.allowFrom.includes(input.senderId)) return { action: 'deliver' }
if (access.dmPolicy === 'allowlist') return { action: 'drop' } // <- every self-chat message dies here
```

## Reproduction

1. On an iPhone-linked Mac where your self-chat thread is addressed by phone number (Messages shows a "You" thread keyed to your number) and your Apple ID is an email.
2. Launch with `claude --channels plugin:imessage@claude-plugins-official`.
3. Text yourself anything. It reaches `chat.db` but never injects into the session.

Verified against `chat.db`:
- The received (`is_from_me=0`) self-echo row has `handle_id -> +1XXXXXXXXXX` (phone), while `account = E:you@example.com` (email). These never match after `SELF.has(sender.toLowerCase())`.
- (Separately confirmed the body decodes fine via `parseAttributedBody` — `text` is NULL, content is in `attributedBody`. So decoding is not the problem; identity matching is.)

There is no structural way in `chat.db` to tie the phone-number handle back to "you" via `account`, so the current single-source `SELF` can't self-correct.

## Why a plain allowlist entry is not the fix

Adding your own number to `allowFrom` delivers the messages, but echo suppression (`consumeEcho`, L805) only runs under `isSelfChat`. Since it would still be `false`, the plugin's own outbound replies (which come back as `is_from_me=0` echoes on the self-chat) would loop back in as commands. The correct fix must make `isSelfChat` true.

## Proposed fix (two parts)

**1. Auto-detect self-chat handles (fixes the common case, no config).**
In addition to the `account` query, add to `SELF` the handle of any 1:1 chat that contains a *self-echo* — a message present as **both** `is_from_me=1` and `is_from_me=0` with matching text/`attributedBody` and near-identical timestamp. That duplication is characteristic of Note-to-Self chats and does not occur in normal DMs, so it reliably identifies your own phone/email handles without any configuration. (Can be scoped to recent messages for performance.)

**2. Explicit escape hatch (idiomatic, deterministic).**
Honor an `IMESSAGE_SELF_IDS` env var (comma-separated handles), appended to `SELF`, matching the existing `IMESSAGE_ACCESS_MODE` / `IMESSAGE_ALLOW_SMS` / `IMESSAGE_DB_PATH` convention. Covers multi-number setups, aliases, and CI. Sketch:

```ts
// after the existing SELF-building block
for (const id of (process.env.IMESSAGE_SELF_IDS ?? '')
.split(',')
.map((s) => s.trim().replace(/^[A-Za-z]:/, '').toLowerCase())
.filter(Boolean)) SELF.add(id)
```

Plus a note in README.md / ACCESS.md.

I've been running (2) locally as a patch and it fully resolves it. Happy to help validate a maintainer's implementation of (1).

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Start in external_plugins/imessage/server.ts with the SELF-building query around L181, the DM gate around L333-335, and isSelfChat/consumeEcho around L804-805. Reproduce the phone-versus-email identity mismatch against chat.db, then verify that self-chat handles are recognized, echo suppression still works, and IMESSAGE_SELF_IDS plus the README.md/ACCESS.md documentation cover the explicit configuration path.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
macos, sqlite, typescript
Lĩnh vực
authentication, backend, databases
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.