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

# Summer.client.messages

> The player's Summer direct messages, behind the player's per-Game consent.

**Class:** `SummerClientMessages` · **Inherits:** RefCounted · **Access:** `Summer.client.messages`

The player's Summer direct messages, behind the player's per-Game consent.

Reads and sends the player's direct messages with their friends: the same account history the Summer app shows. Each operation needs its own permission, which the Build declares and the player grants in the Summer app's consent sheet: `social.messages.read` for [`list_conversations()`](/api-reference/gdscript/client/messages#list_conversations), [`list_messages()`](/api-reference/gdscript/client/messages#list_messages) and [`list_messages_after()`](/api-reference/gdscript/client/messages#list_messages_after); `social.messages.send` for [`send()`](/api-reference/gdscript/client/messages#send); and `social.messages.read_state.write` for [`mark_read()`](/api-reference/gdscript/client/messages#mark_read). Friendship, blocks and the age rule still apply to every message.
Message text is plain Unicode, never markup, and passes the Summer chat text filter. Names and message text that reach the game never carry control characters other than newline and tab in message text; a read that would deliver one fails with `protocol_error` and changes nothing. Without a permission an operation fails with `permission_not_requested`, `permission_declined`, `permission_revoked` or `permission_undeclared`, matching [`get_access()`](/api-reference/gdscript/client/messages#get_access); ask with [`request_access()`](/api-reference/gdscript/client/messages#request_access). Other typed failures are `text_not_allowed` (the filter refused the text; nothing was stored), `target_unavailable` (the other player is not a friend, blocked this player, or is gone), `rate_limited` (retryable), `age_restricted`, `invalid_argument`, `capability_unavailable` when [`is_available()`](/api-reference/gdscript/client/messages#is_available) is `false`, and `unavailable` (retryable) when the Player Host cannot be reached.

```gdscript theme={null}
var messages := Summer.client.messages
messages.messages_changed.connect(_reload_thread)

func _send(friend_id: String, text: String) -> void:
    var op := messages.send(friend_id, text)
    var result: SummerResult = await op.completed
    if result.code == &"permission_not_requested":
        if (await messages.request_access([&"social.messages.send"]).completed).is_ok():
            op = messages.send(friend_id, text)
            result = await op.completed
    if result.is_ok():
        add_bubble(op.message)
```

**Host capabilities named here:** `player.messaging@1`

## Methods

### get\_access

```gdscript theme={null}
func get_access(permission: StringName) -> StringName const
```

Returns the player's latest known decision for the messaging `permission` in this Game: `granted`, `declined`, `revoked`, `not_requested`, or `undeclared`. The Engine reads the decisions when the event stream starts or resyncs and after a consent decision, and every messaging operation's answer updates its own permission. An unknown permission name is `undeclared`.

| Parameter | Type | Default |
| - | - | - |
| `permission` | StringName | required |

**Returns:** StringName

### is\_available

```gdscript theme={null}
func is_available() -> bool const
```

Returns `true` when the Summer app offers direct messages (`player.messaging@1`) to this signed-in player. Always `false` in local play, for guests, and for accounts the platform does not allow social features (`age_restricted`). The player must still grant each permission.

**Returns:** bool

### list\_conversations

```gdscript theme={null}
func list_conversations(cursor: String = "", limit: int = 0) -> SummerConversationsOperation
```

Reads one page of the player's conversations. Pass [`SummerConversationsOperation.next_cursor`](/api-reference/gdscript/types/conversations-operation#next_cursor) from the previous page as `cursor` to continue. `limit` is the page size, from `1` to `100`, or `0` for the platform default; the platform may return fewer.

| Parameter | Type | Default |
| - | - | - |
| `cursor` | String | `""` |
| `limit` | int | `0` |

**Returns:** [`SummerConversationsOperation`](/api-reference/gdscript/types/conversations-operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

### list\_messages

```gdscript theme={null}
func list_messages(user_id: String, cursor: String = "", limit: int = 0) -> SummerDirectMessagesOperation
```

Reads one page of the conversation with `user_id`. Pass [`SummerDirectMessagesOperation.next_cursor`](/api-reference/gdscript/types/direct-messages-operation#next_cursor) from the previous page as `cursor` to continue. `limit` matches [`list_conversations()`](/api-reference/gdscript/client/messages#list_conversations).

| Parameter | Type | Default |
| - | - | - |
| `user_id` | String | required |
| `cursor` | String | `""` |
| `limit` | int | `0` |

**Returns:** [`SummerDirectMessagesOperation`](/api-reference/gdscript/types/direct-messages-operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

### list\_messages\_after

```gdscript theme={null}
func list_messages_after(user_id: String, sequence: int, limit: int = 0) -> SummerDirectMessagesOperation
```

Reads messages in the conversation with `user_id` whose [`SummerDirectMessage.sequence`](/api-reference/gdscript/types/direct-message#sequence) is above `sequence`, in ascending order: the catch-up read after [`messages_changed`](/api-reference/gdscript/client/messages#messages_changed). `sequence` must be above `0`.

| Parameter | Type | Default |
| - | - | - |
| `user_id` | String | required |
| `sequence` | int | required |
| `limit` | int | `0` |

**Returns:** [`SummerDirectMessagesOperation`](/api-reference/gdscript/types/direct-messages-operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

### mark\_read

```gdscript theme={null}
func mark_read(user_id: String, sequence: int) -> SummerOperation
```

Marks the conversation with `user_id` read up to the message `sequence`, on every device the player uses.

| Parameter | Type | Default |
| - | - | - |
| `user_id` | String | required |
| `sequence` | int | required |

**Returns:** [`SummerOperation`](/api-reference/gdscript/types/operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

### request\_access

```gdscript theme={null}
func request_access(permissions: PackedStringArray) -> SummerOperation
```

Asks the Summer app to show its consent sheet for the messaging `permissions`: `social.messages.read`, `social.messages.send` and `social.messages.read_state.write`. Only the trusted app records the player's decision; the Engine then reads it. Succeeds when the player granted every requested permission, at once when they already had; otherwise fails with the first refusal, such as `permission_declined`, or `permission_not_requested` when the player closed the sheet without deciding. Fails at once with `permission_undeclared` when this Build does not declare a requested permission, `invalid_argument` for any other name, and `ui_unavailable` when the app cannot show the sheet now. One consent sheet is requested at a time, shared with [`Summer.client.friends.request_access()`](/api-reference/gdscript/client/friends#request_access).

| Parameter | Type | Default |
| - | - | - |
| `permissions` | PackedStringArray | required |

**Returns:** [`SummerOperation`](/api-reference/gdscript/types/operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

### send

```gdscript theme={null}
func send(user_id: String, text: String) -> SummerDirectMessageSendOperation
```

Sends `text` to the friend `user_id`. The text is 1 to 4000 characters, not only whitespace, with no control characters other than newline and tab; anything else fails with `invalid_argument` before any request. On success, [`SummerDirectMessageSendOperation.message`](/api-reference/gdscript/types/direct-message-send-operation#message) is the accepted message. Each call is one message: the Engine never sends it twice.

| Parameter | Type | Default |
| - | - | - |
| `user_id` | String | required |
| `text` | String | required |

**Returns:** [`SummerDirectMessageSendOperation`](/api-reference/gdscript/types/direct-message-send-operation)

Returns at once. Wait for the result with `var result: SummerResult = await op.get_result_or_completed_signal()`; see [SummerOperation](/api-reference/gdscript/types/operation).

## Signals

### messages\_changed

```gdscript theme={null}
signal messages_changed()
```

The player's direct messages may have changed: a message arrived or was read on another device, or the event stream resynced and changes may have been missed. Re-read the pages the game shows. Pending native Host support: the Summer apps do not yet forward message hints to games, so today this fires only after a stream resync.

***

What is live on the platform today: [platform capability status](/knowledge-base/source-status). Check availability at runtime before you offer a feature.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.