diff --git a/src/pages/docs/auth/identified-clients.mdx b/src/pages/docs/auth/identified-clients.mdx index 6420260ee7..2efd28878f 100644 --- a/src/pages/docs/auth/identified-clients.mdx +++ b/src/pages/docs/auth/identified-clients.mdx @@ -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 diff --git a/src/pages/docs/auth/token/jwt.mdx b/src/pages/docs/auth/token/jwt.mdx index e5b660bc77..1666196b75 100644 --- a/src/pages/docs/auth/token/jwt.mdx +++ b/src/pages/docs/auth/token/jwt.mdx @@ -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', }), diff --git a/src/pages/docs/basics/index.mdx b/src/pages/docs/basics/index.mdx index e6b9f05a9e..d608201cf4 100644 --- a/src/pages/docs/basics/index.mdx +++ b/src/pages/docs/basics/index.mdx @@ -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 powers the [Spaces SDK](/docs/spaces/avatar) for avatar stacks and the [Chat SDK](/docs/chat/rooms/presence) for chat room member notifications. Use presence directly for custom use cases. See [product guidance](/docs/platform/products) for help choosing the right product. ### Message history diff --git a/src/pages/docs/channels/index.mdx b/src/pages/docs/channels/index.mdx index 79ac09db1c..cd50fbc960 100644 --- a/src/pages/docs/channels/index.mdx +++ b/src/pages/docs/channels/index.mdx @@ -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 must be [persisted](/docs/storage-history/storage#all-message-persistence) before they can be annotated or updated, and [continuous history](/docs/storage-history/history#continuous-history) features will not work. To set a rule: diff --git a/src/pages/docs/channels/options/echo.mdx b/src/pages/docs/channels/options/echo.mdx index fcdea74315..b035904c95 100644 --- a/src/pages/docs/channels/options/echo.mdx +++ b/src/pages/docs/channels/options/echo.mdx @@ -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](/docs/spaces), 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. diff --git a/src/pages/docs/channels/options/rewind.mdx b/src/pages/docs/channels/options/rewind.mdx index 65a8db6c1b..b5a74fb0d3 100644 --- a/src/pages/docs/channels/options/rewind.mdx +++ b/src/pages/docs/channels/options/rewind.mdx @@ -5,7 +5,7 @@ redirect_from: - /docs/realtime/channels/channel-parameters/rewind --- -The `rewind` channel param 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 param 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. Clients can rewind to a point in time in the past, or for a given number of messages. diff --git a/src/pages/docs/channels/states.mdx b/src/pages/docs/channels/states.mdx index 32dfca1ff7..e4c8feeb48 100644 --- a/src/pages/docs/channels/states.mdx +++ b/src/pages/docs/channels/states.mdx @@ -35,35 +35,35 @@ The following example explicitly attaches to a channel, which results in the cha ```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"); } } } @@ -71,21 +71,21 @@ channel.on(new ChannelStateListener() { ``` ```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") } ``` @@ -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: @@ -129,12 +129,12 @@ The following is an example of detaching from a channel: ```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(); ``` @@ -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) { @@ -517,7 +517,7 @@ Ably SDKs will attempt to automatically recover from non-fatal error conditions. ```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); @@ -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); @@ -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: @@ -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) { @@ -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) { @@ -582,7 +582,7 @@ 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); } @@ -590,7 +590,7 @@ privateChannel.Attach((_, 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)") } @@ -598,7 +598,7 @@ realtime.channels.get("private:chatroom").attach { error in ``` ```realtime_flutter -final channel = realtime.channels.get('private:chatroom'); +final channel = realtime.channels.get('private:my-channel'); channel .on() .listen((ably.ChannelStateChange stateChange) { @@ -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) }) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 1b7f1a30bd..415299c486 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -933,7 +933,7 @@ You should be aware of the following limitations: ## Mapping of message reactions to 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](/docs/messages/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 | | ------------- | --------------- | diff --git a/src/pages/docs/faq/push-faqs.mdx b/src/pages/docs/faq/push-faqs.mdx index 43cbd26705..2ae68c2a41 100644 --- a/src/pages/docs/faq/push-faqs.mdx +++ b/src/pages/docs/faq/push-faqs.mdx @@ -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 a push notification via a channel](/docs/push/publish#via-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? @@ -111,7 +111,7 @@ Consistent duplication on a specific device usually indicates both a `deviceId` ### Why can I not publish push notifications on channels? -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 push notifications to channels](/docs/push/publish#via-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. diff --git a/src/pages/docs/messages/annotations.mdx b/src/pages/docs/messages/annotations.mdx index c3ab7ca093..c9babeea79 100644 --- a/src/pages/docs/messages/annotations.mdx +++ b/src/pages/docs/messages/annotations.mdx @@ -7,6 +7,12 @@ 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. + + + + 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 diff --git a/src/pages/docs/messages/updates-deletes.mdx b/src/pages/docs/messages/updates-deletes.mdx index 54b8155ec1..91ec6dc6c0 100644 --- a/src/pages/docs/messages/updates-deletes.mdx +++ b/src/pages/docs/messages/updates-deletes.mdx @@ -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. + + 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 diff --git a/src/pages/docs/presence-occupancy/index.mdx b/src/pages/docs/presence-occupancy/index.mdx index 3cb17665d8..10df25abd1 100644 --- a/src/pages/docs/presence-occupancy/index.mdx +++ b/src/pages/docs/presence-occupancy/index.mdx @@ -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 used in each channel to indicate which users are online, and to notify other members when someone leaves the room. + + diff --git a/src/pages/docs/presence-occupancy/presence.mdx b/src/pages/docs/presence-occupancy/presence.mdx index 1feec4ad35..4861550c82 100644 --- a/src/pages/docs/presence-occupancy/presence.mdx +++ b/src/pages/docs/presence-occupancy/presence.mdx @@ -14,7 +14,11 @@ redirect_from: - /docs/core-features/versions/v1.1/presence --- -Presence enables clients to be aware of other clients that are currently "present" on a channel. Each member present on a channel has a unique self-assigned client identifier and system-assigned connection identifier, along with an optional payload that can be used to describe the member's status or attributes. Presence enables you to quickly build apps such as chat rooms and multiplayer games by automatically keeping track of who is present in real time across any device. +Presence enables clients to be aware of other clients that are currently "present" on a channel. Each member present on a channel has a unique self-assigned client identifier and system-assigned connection identifier, along with an optional payload that can be used to describe the member's status or attributes. Presence enables you to quickly build apps such as [chat rooms](/docs/chat) and multiplayer games by automatically keeping track of who is present in real time across any device. + + Other devices and services can subscribe to presence events in real time using the realtime interface or with [integrations](/docs/platform/integrations). You can also request a list of clients or devices on a channel at a particular point in time with the REST interface. @@ -32,7 +36,7 @@ The following presence events are emitted: |-------|-------------| | Enter | A new member has entered the channel | | Leave | A member who was present has now left the channel. This may be a result of an explicit request to leave or implicitly when detaching from the channel. Alternatively, if a member's connection is abruptly disconnected and they do not resume their connection within a minute, Ably treats this as a leave event as the client is no longer present | -| Update | An already present member has updated their [member data](#member-data). Being notified of member data updates can be useful, for example, it can be used to update the status of a user when they are typing a message | +| Update | An already present member has updated their [member data](#member-data). Being notified of member data updates can be useful, for example, it can be used to update the status of a user when they are typing a message (see also [Chat typing indicators](/docs/chat/rooms/typing) for a purpose-built solution) | | Present | When subscribing to presence events on a channel that already has members present, this event is emitted for every member already present on the channel before the subscribe listener was registered |