> ## Documentation Index
> Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Inbound iMessage group events

> Handle iMessage membership and group metadata changes from other participants.

Inbound group events require a dedicated cloud line, available on the Business
plan. Group changes made by other members then arrive as inbound messages on
`app.messages`, carrying the same content types you send:

<Warning>
  Shared-pool cloud lines and `@spectrum-ts/imessage-local` do not subscribe to
  the group-event stream. Your app will not receive membership or
  group-metadata changes through `app.messages` in either case. Calling
  `space.get(chatGuid)` does not enable group events.
</Warning>

| Someone…          | `content.type`                                                     | `message.sender` |
| ----------------- | ------------------------------------------------------------------ | ---------------- |
| adds a member     | `"addMember"` (`members` = who was added)                          | who added them   |
| removes a member  | `"removeMember"` (`members` = who was removed)                     | who removed them |
| leaves the group  | `"leaveSpace"`                                                     | the leaver       |
| renames the group | `"rename"` (`displayName`)                                         | who renamed it   |
| changes the icon  | `"avatar"` (`action.kind === "set"`, bytes behind `action.read()`) | who changed it   |
| clears the icon   | `"avatar"` (`action.kind === "clear"`)                             | who cleared it   |

```ts theme={null}
for await (const [space, message] of app.messages) {
  if (message.content.type === "addMember") {
    console.log(
      `${message.sender?.id ?? "someone"} added ${message.content.members.join(", ")}`
    );
  }
}
```

Semantics to rely on:

* `message.sender` may be `undefined` — Apple does not always record the actor.
  The affected member is always present (in `members`, or as the sender for
  `leaveSpace`).
* The agent's own actions never echo back: `space.add(...)`,
  `space.rename(...)`, and friends are suppressed from the inbound stream,
  matching how self-sent messages behave.
* Icon-change events carry a snapshot of the icon fetched at event time; an
  icon that was already replaced or removed by then is skipped (the follow-up
  event carries the current state).
* On dedicated lines, group events ride the same durable catch-up log as
  messages and polls, so changes that happen while the app is down are replayed
  on reconnect. After a cursor gap, reconcile with `space.getMembers()` /
  `space.getAvatar()`.
