Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/pages/docs/auth/identified-clients.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ When a client is authenticated and connected to Ably, it is considered to be an

When a client is assigned a trusted identity, that is, a `clientId`, then they are considered to be an identified client. For all operations that client performs with the Ably service, their `clientId` field will be automatically populated and can be trusted by other clients.

For example, assume you are building a chat application and want to allow clients to publish messages and be present on a channel. If each client is assigned a trusted identity by your server, such as a unique email address or UUID, then all other subscribed clients can trust any messages or presence events they receive in the channel as being from that client. No other clients are permitted to assume a `clientId` that they are not assigned in their Ably-compatible token. They are unable to masquerade as another `clientId`.
For example, assume you are building a [chat application](/docs/chat) and want to allow clients to publish messages and be present on a channel. If each client is assigned a trusted identity by your server, such as a unique email address or UUID, then all other subscribed clients can trust any messages or presence events they receive in the channel as being from that client. No other clients are permitted to assume a `clientId` that they are not assigned in their Ably-compatible token. They are unable to masquerade as another `clientId`.

## ClientId immutability <a id="immutability"/>

Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/auth/token/jwt.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -625,11 +625,11 @@ Embed trusted metadata in JWTs that other clients can read. Use the `ably.channe
const ablyJwt = jwt.sign(
{
'x-ably-capability': JSON.stringify({
'chat:*': ['publish', 'subscribe', 'presence'],
'my-channel:*': ['publish', 'subscribe', 'presence'],
}),
'x-ably-clientId': userId,
// Channel-scoped claim - other clients can read this
'ably.channel.chat:lobby': JSON.stringify({
'ably.channel.my-channel:lobby': JSON.stringify({
role: 'moderator',
displayName: 'Alice',
}),
Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/basics/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Ably Pub/Sub enables you to implement the [publish-subscribe (pub-sub) pattern](

The [presence](/docs/presence-occupancy) feature enables clients to be aware of other clients that are currently "present" on a channel. Subscribers receive three types of updates from presence members. These are when a client joins the presence set, when they leave the presence set, and when they update an optional payload associated with each member. The payload can be used to describe their status, or attributes associated with them, such as setting their status to 'out for lunch'.

Presence is most commonly used as an online indicator to create an avatar stack for an application, or to notify occupants of a chat room that a member has joined or left.
Presence is the underlying primitive used by the [Spaces SDK](/docs/spaces/avatar) for avatar stacks and by the [Chat SDK](/docs/chat/rooms/presence) for chat room member notifications. It can also be used directly for custom use cases. See [product guidance](/docs/platform/products) for help choosing the right product.

### Message history <a id="history"/>

Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/channels/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ The rules related to enabling features are:
| Push notifications enabled | If checked, publishing messages with a push payload in the `extras` field is permitted. This triggers the delivery of a [Push Notification](/docs/push) to devices registered for push on the channel. |
| Server-side batching | If enabled, messages are grouped into batches before being sent to subscribers. [Server-side batching](/docs/messages/batch#server-side) reduces the overall message count, lowers costs, and mitigates the risk of hitting rate limits during high-throughput scenarios. |
| Message conflation | If enabled, messages are aggregated over a set period of time and evaluated against a conflation key. All but the latest message for each conflation key value will be discarded, and the resulting message, or messages, will be delivered to subscribers as a single batch once the period of time elapses. [Message conflation](/docs/messages#conflation) reduces costs in high-throughput scenarios by removing redundant and outdated messages. |
| Message annotations, updates, deletes, and appends | If enabled, allows message "annotations":/docs/messages/annotations to be used, as well as updates, deletes, and appends to be published to messages. Note that these features are currently in public preview. When this feature is enabled, messages will be "persisted":/docs/storage-history/storage#all-message-persistence (necessary in order from them later be annotated or updated), and "continuous history":/docs/storage-history/history#continuous-history features will not work.
| Message annotations, updates, deletes, and appends | If enabled, allows message [annotations](/docs/messages/annotations) to be used, as well as updates, deletes, and appends to be published to messages. Note that these features are currently in public preview. When this feature is enabled, messages will be [persisted](/docs/storage-history/storage#all-message-persistence) (necessary in order for them later be annotated or updated), and [continuous history](/docs/storage-history/history#continuous-history) features will not work.

To set a rule:

Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/channels/options/echo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Echo
meta_description: "The echo channel option enables per-channel control over whether a client receives its own published messages."
---

By default, clients receive their own messages when subscribed to a channel they publish on. This is useful in many applications because it means every subscriber, including the publisher, renders state from the same stream of messages. For example, in a chat application or collaborative editor, a client can publish a message and then update its UI only when that message arrives back on the channel, guaranteeing that all participants see the same ordering and state.
By default, clients receive their own messages when subscribed to a channel they publish on. This is useful in many applications because it means every subscriber, including the publisher, renders state from the same stream of messages. For example, in a [chat application](/docs/chat) or collaborative editor, a client can publish a message and then update its UI only when that message arrives back on the channel, guaranteeing that all participants see the same ordering and state.

However, this is not always desirable. A client streaming pricing updates, publishing telemetry data, or sending tokens via [AI Transport](/docs/ai-transport) does not need to hear its own messages echoed back. Suppressing echo on these channels reduces unnecessary bandwidth and message processing.

Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/channels/options/rewind.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ redirect_from:
- /docs/realtime/channels/channel-parameters/rewind
---

The `rewind` channel option enables a client to specify where to start an attachment from, when attaching to a channel. Rewind can provide context to clients attaching to a channel by passing them previously published messages, such as in the example of a joining a chat room.
The `rewind` channel option enables a client to specify where to start an attachment from, when attaching to a channel. Rewind can provide context to clients attaching to a channel by passing them previously published messages, such as joining a chat room (for chat history, see the [Chat SDK](/docs/chat/rooms/history)).

Clients can rewind to a point in time in the past, or for a given number of messages.

Expand Down
56 changes: 28 additions & 28 deletions src/pages/docs/channels/states.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,57 +35,57 @@ The following example explicitly attaches to a channel, which results in the cha

<Code>
```realtime_javascript
const channel = realtime.channels.get('chatroom');
const channel = realtime.channels.get('my-channel');
await channel.attach();
```

```realtime_nodejs
const channel = realtime.channels.get('chatroom');
const channel = realtime.channels.get('my-channel');
await channel.attach();
```

```realtime_ruby
realtime.channels.get('chatroom').attach do |channel|
puts "'chatroom' exists and is now available globally in every datacenter"
realtime.channels.get('my-channel').attach do |channel|
puts "'my-channel' exists and is now available globally in every datacenter"
end
```

```realtime_python
channel = realtime.channels.get('chatroom')
channel = realtime.channels.get('my-channel')
await channel.attach()
print("'chatroom' exists and is now available globally in every datacenter")
print("'my-channel' exists and is now available globally in every datacenter")
```

```realtime_java
Channel channel = realtime.channels.get("chatroom");
Channel channel = realtime.channels.get("my-channel");
channel.on(new ChannelStateListener() {
@Override
public void onChannelStateChanged(ChannelStateChange state) {
switch (state.current) {
case attached: {
System.out.println("'chatroom' exists and is now available globally");
System.out.println("'my-channel' exists and is now available globally");
}
}
}
});
```

```realtime_csharp
IRealtimeChannel channel = realtime.Channels.Get("chatroom");
IRealtimeChannel channel = realtime.Channels.Get("my-channel");
channel.Attach((success, error) => {
Console.WriteLine("'chatroom' exists and is now available globally");
Console.WriteLine("'my-channel' exists and is now available globally");
});
```

```realtime_objc
[[realtime.channels get:@"chatroom" options:options] attach:^(ARTErrorInfo *error) {
NSLog(@"'chatroom' exists and is now available globally in every datacenter");
[[realtime.channels get:@"my-channel" options:options] attach:^(ARTErrorInfo *error) {
NSLog(@"'my-channel' exists and is now available globally in every datacenter");
}];
```

```realtime_swift
realtime.channels.get("chatroom").attach { error in
print("'chatroom' exists and is now available globally in every datacenter")
realtime.channels.get("my-channel").attach { error in
print("'my-channel' exists and is now available globally in every datacenter")
}
```

Expand All @@ -96,7 +96,7 @@ final channelMessageSubscription = channel
.listen((ably.ChannelStateChange state) {
switch (state.current) {
case ably.ChannelState.attached: {
print("'chatroom' exists and is now available globally");
print("'my-channel' exists and is now available globally");
break;
}
default:
Expand Down Expand Up @@ -129,12 +129,12 @@ The following is an example of detaching from a channel:

<Code>
```realtime_javascript
const channel = realtime.channels.get('chatroom');
const channel = realtime.channels.get('my-channel');
await channel.detach();
```

```realtime_nodejs
const channel = realtime.channels.get('chatroom');
const channel = realtime.channels.get('my-channel');
await channel.detach();
```

Expand Down Expand Up @@ -256,7 +256,7 @@ channel.on(ChannelEvent.attached, new ChannelStateListener() {
```

```realtime_csharp
IRealtimeChannel channel = realtime.Channels.Get("chatroom");
IRealtimeChannel channel = realtime.Channels.Get("my-channel");
channel.On(ChannelEvent.Attached, stateChange => {
Console.WriteLine("channel " + channel.Name + " is now attached");
if (stateChange.Resumed) {
Expand Down Expand Up @@ -517,7 +517,7 @@ Ably SDKs will attempt to automatically recover from non-fatal error conditions.

<Code>
```realtime_javascript
const channel = realtime.channels.get('private:chatroom');
const channel = realtime.channels.get('private:my-channel');

channel.on('failed', (stateChange) => {
console.log('Channel failed, reason: ', stateChange.reason);
Expand All @@ -527,7 +527,7 @@ await channel.attach();
```

```realtime_nodejs
const channel = realtime.channels.get('private:chatroom');
const channel = realtime.channels.get('private:my-channel');

channel.on('failed', (stateChange) => {
console.log('Channel failed, reason: ', stateChange.reason);
Expand All @@ -537,14 +537,14 @@ await channel.attach();
```

```realtime_ruby
deferrable = realtime.channels.get('private:chatroom').attach
deferrable = realtime.channels.get('private:my-channel').attach
deferrable.errback do |error|
puts "Attach failed: #{error}"
end
```

```realtime_python
channel = realtime.channels.get('private:chatroom')
channel = realtime.channels.get('private:my-channel')

# Attach to the channel
try:
Expand All @@ -555,7 +555,7 @@ except Exception as err:
```

```realtime_java
Channel channel = realtime.channels.get("private:chatroom");
Channel channel = realtime.channels.get("private:my-channel");
channel.on(new ChannelStateListener() {
@Override
public void onChannelStateChanged(ChannelStateChange stateChange) {
Expand All @@ -572,7 +572,7 @@ channel.attach();
```

```realtime_csharp
IRealtimeChannel privateChannel = realtime.Channels.Get("private:chatroom");
IRealtimeChannel privateChannel = realtime.Channels.Get("private:my-channel");
privateChannel.Attach((_, error) => {
if (error != null)
{
Expand All @@ -582,23 +582,23 @@ privateChannel.Attach((_, error) => {
```

```realtime_objc
[[realtime.channels get:@"private:chatroom"] attach:^(ARTErrorInfo *error) {
[[realtime.channels get:@"private:my-channel"] attach:^(ARTErrorInfo *error) {
if (error) {
NSLog(@"Attach failed: %@", error);
}
}];
```

```realtime_swift
realtime.channels.get("private:chatroom").attach { error in
realtime.channels.get("private:my-channel").attach { error in
if let error = error {
print("Attach failed: \(error)")
}
}
```

```realtime_flutter
final channel = realtime.channels.get('private:chatroom');
final channel = realtime.channels.get('private:my-channel');
channel
.on()
.listen((ably.ChannelStateChange stateChange) {
Expand All @@ -616,7 +616,7 @@ channel.attach();
```

```realtime_go
channel := realtime.Channels.Get("private:chatroom")
channel := realtime.Channels.Get("private:my-channel")
channel.On(ably.ChannelEventFailed, func(stateChange ably.ChannelStateChange) {
fmt.Printf("Channel failed, reason: '%v'", stateChange.Reason)
})
Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/chat/rooms/message-reactions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ You should be aware of the following limitations:

## Mapping of message reactions to annotations <a id="mapping-annotations"/>

Chat message reactions are powered by the PubSub annotations feature. Chat uses the `reaction:` prefix for annotation types. Here is the mapping from message reaction types to annotation types:
Chat message reactions are powered by the Pub/Sub annotations feature. Chat uses the `reaction:` prefix for annotation types. Here is the mapping from message reaction types to annotation types:

| Reaction type | Annotation type |
| ------------- | --------------- |
Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/faq/push-faqs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ FAQs related to push notification costs and connection limits.

No. [Push notifications](/docs/push) do not require a device or browser to stay connected to Ably, so they do not count as a [connection](/docs/connect).

However, [publishing](/docs/channels#publish) a push notification via a [channel](/docs/channels) activates that channel. Therefore, your concurrent (peak) channel count includes the number of channels you simultaneously publish to.
However, [publishing](/docs/pub-sub#publish) a push notification via a [channel](/docs/channels) activates that channel. Therefore, your concurrent (peak) channel count includes the number of channels you simultaneously publish to.

### Does Ably charge for push notifications? <a id="push-billing"/>

Expand Down Expand Up @@ -111,7 +111,7 @@ Consistent duplication on a specific device usually indicates both a `deviceId`

### Why can I not publish push notifications on channels? <a id="cannot-publish-push"/>

If you're unable to [publish](/docs/channels#publish) push notifications to [channels](/docs/channels), this is typically due to configuration or permission issues. The following are possible reasons for this issue:
If you're unable to [publish](/docs/pub-sub#publish) push notifications to [channels](/docs/channels), this is typically due to configuration or permission issues. The following are possible reasons for this issue:

1. [Rules](/docs/channels#rules): Channels must be explicitly enabled for push notifications via rules. They are disabled by default.
2. [Permissions](/docs/auth/capabilities): The publisher must have permission to publish to that channel.
Expand Down
8 changes: 7 additions & 1 deletion src/pages/docs/messages/annotations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ meta_description: "Annotate messages on a channel with additional metadata."
Message annotations are currently in Public Preview. That means that we are committed to supporting it and expect the API to be stable unless we discover a significant issue, but it may not yet be implemented in all of our SDKs, and there may be other minor shortcomings.
</Aside>

<Aside data-type='note'>
For chat applications, the [Chat SDK](/docs/chat) provides dedicated APIs for [message reactions](/docs/chat/rooms/message-reactions), [read receipts](/docs/chat/rooms/read-receipts), and [moderation](/docs/chat/moderation). Message annotations are intended for adding metadata to Pub/Sub messages outside of chat contexts. See [product guidance](/docs/platform/products) for a full comparison.
</Aside>

<a id="interactions"/>

Message annotations enable clients to append information to existing messages on a channel. You can use annotations to implement features like:

* **Message reactions** - add emoji reactions (👍, ❤️, 😂) to messages
* **Message reactions** - add emoji reactions (👍, ❤️, 😂) to messages (for chat applications, see [Chat SDK message reactions](/docs/chat/rooms/message-reactions))
* **Content categorization** - tag messages with categories such as "important" or "urgent"
* **Community moderation** - flag inappropriate content for review
* **Read receipts** - mark messages as "read" or "delivered"
Expand Down
4 changes: 4 additions & 0 deletions src/pages/docs/messages/updates-deletes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ meta_description: "Update and delete messages published to a channel, and retrie
Message updates and deletes are currently in Public Preview. That means that we are committed to supporting it and expect the API to be stable unless we discover a significant issue, but it may not yet be implemented in all of our SDKs, and there may be other minor shortcomings.
</Aside>

<Aside data-type='note'>
For chat applications, the [Chat SDK](/docs/chat) provides purpose-built APIs for [message editing](/docs/chat/rooms/messages#update) and [moderation](/docs/chat/moderation). Message updates and deletes are intended for Pub/Sub messages outside of chat contexts.
</Aside>

You can update and delete messages that have been published to a channel, for use cases such as:

* **Message editing** - allow users to edit their messages in chat-like applications
Expand Down
6 changes: 5 additions & 1 deletion src/pages/docs/presence-occupancy/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ Presence is a feature that tracks the membership of a presence set for a channel

Occupancy provides metrics for a channel. It is a feature that counts how many of a thing are attached to a channel, such as the number of connections. It does not provide any information that can identify individual connections or clients attached to the channel.

Take a chat application containing multiple chat rooms as an example. Occupancy would be a more lightweight method for displaying the popularity of rooms, by displaying the number of connections to each channel. Presence could be utilized in each channel to indicate which users are online, and to notify other members when someone leaves the room.
Take a [chat application](/docs/chat) containing multiple chat rooms as an example. Occupancy would be a more lightweight method for displaying the popularity of rooms, by displaying the number of connections to each channel. Presence could be utilized in each channel to indicate which users are online, and to notify other members when someone leaves the room.

<Aside data-type='note'>
For chat applications, the [Chat SDK](/docs/chat) provides built-in [presence](/docs/chat/rooms/presence) and [occupancy](/docs/chat/rooms/occupancy) features. The example below illustrates how these primitives work at the Pub/Sub level. See [product guidance](/docs/platform/products) for a full comparison.
</Aside>
Loading