Documentation Release Notes - November 2024

Documentation Release Notes - November 2024

Documentation and product highlights from November 2024.

This article was originally published at https://www.pubnub.com/docs/release-notes/2024/november

As the November chill sets in and the pace slows down, we're warming things up with some exciting updates.

In the world of SDKs, we've introduced message drafts in our Kotlin and Swift mobile chat SDKs. You can now create and tweak your messages before hitting send! Plus, we've added support for custom message types across multiple APIs, making it easier than ever to organize your messages.

For those using our JavaScript SDK, you'll love the new shared workers feature, which helps manage connections and keeps your data consistent across multiple windows. We've also added tree shaking to help cut down on functionalities you don't need and speed up load times.

The Publish API got a little enhancement too โ€“ we now accept floating-point numbers for the TTL parameter, giving you more precision in message expiration.

What's more, we've finally documented all the roles and permissions you can assign in the Admin Portal. This means you can now easily see who has access to what and manage permissions smoothly.

Finally, our Insights and BizOps tools are working more closely together. You can now export top user and channel data directly from Insights to BizOps, making data management easier than ever.

See whatโ€™s new!

General ๐Ÿ› ๏ธ

Roles & permissions in Admin Portal

Type: Update

We've finally documented all the roles you can assign to users in the Admin Portal. Each role grants a different set of permissions, allowing general access on various levels or restricting access to specific features, like Functions, BizOps, or Illuminate.

SDKs ๐Ÿ“ฆ

Message drafts in mobile chat SDKs

Type: New feature

As of this month, Kotlin and Swift Chat SDKs support message drafts. The new functionality lets you create, edit, and manage messages before sending them in a chat application.

The integral message elements listener handles any changes in the draft message, including plain text, user mentions (@sue), channel references (#channel), or links, and lets you display these message elements to users.

  • Kotlin
  • Swift
// Create an empty message draft
val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)

// Add a text
messageDraft.update(text = "Hello Alex!")

// Add a user mention to the string 'Alex'
messageDraft.addMention(offset = 6, length = 4, target = MentionTarget.User(userId = "alex_d"))

// Change the text
messageDraft.update(text = "Hello Alex! I have sent you this link on the #offtopic channel.")

// Add a link to the string 'link'
messageDraft.addMention(offset = 33, length = 4, target = MentionTarget.Url(url = "www.pubnub.com"))
// Create an empty message draft
if let messageDraft = channel?.createMessageDraft(isTypingIndicatorTriggered: channel?.type != .public) {

    // Add initial text
    messageDraft.update(text: "Hello Alex!")

    // Add a user mention to the string "Alex"
    messageDraft.addMention(offset: 6, length: 4, target: .user(userId: "alex_d"))

    // Change the text
    messageDraft.update(text: "Hello Alex! I have sent you this link on the #offtopic channel.")

    // Add a URL mention to the string "link"
    messageDraft.addMention(offset: 33, length: 4, target: .url(url: "www.pubnub.com"))
Local storage

Drafts do not automatically save locally. If you switch channels, the draft will be lost unless you implement your own storage solution to keep it saved.

Custom message type

Type: New feature

Last month, we mentioned a plan to introduce a message type parameter in SDKs to categorize messages. Following the updates in the REST API from last month, we now added support for the message type parameter in Publish, Subscribe, Message Persistence, and Files APIs in the following SDKs:

  • JavaScript
  • Kotlin
  • Java
  • Swift
  • Objective-C
  • Python
  • PHP
  • Unreal
try {
    const result = await pubnub.publish({
        message: {
            such: "object",
        },
        channel: "my_channel",
        sendByPost: false, // true to send via post
        storeInHistory: false, //override default Message Persistence options
        meta: {
            cool: "meta",
        }, // publish extra meta with the request
        customMessageType: "text-message",
    });
} catch (status) {
    console.log(status);
val configBuilder = com.pubnub.api.v2.PNConfiguration.builder(UserId("myUserId"), "demo").apply {
    publishKey = "demo"
}
val pubnub = PubNub.create(configBuilder.build())

val channel = pubnub.channel("myChannel")

val myMessage = JsonObject().apply {
    addProperty("lat", 32L)
    addProperty("lng", 32L)
}

channel.publish(
    message = myMessage, 
    customMessageType = "text-message"
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("yourUserId"), "demo");
configBuilder.publishKey("demo");

PNConfiguration pnConfiguration = configBuilder.build();
PubNub pubnub = PubNub.create(pnConfiguration);
Channel channel = pubnub.channel("myChannel");

JsonObject position = new JsonObject();
position.addProperty("lat", 32L);
position.addProperty("lng", 32L);

System.out.println("before pub: " + position);
channel.publish(position)
    .customMessageType("text-message")
    .async(result -> {
pubnub.publish(
  channel: "my-channel",
  message: "Hello from PubNub Swift SDK",
  customMessageType: "text-message"
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Response: \(error.localizedDescription)")
  }
}
self.client.publish()
    .channel(@"my_channel")
    .message(@"Hello from PubNub iOS!")
    .shouldStore(YES)
    .ttl(16)
    .customMessageType(@"text-message")
    .performWithCompletion(^(PNPublishStatus *status) {

    if (!status.isError) {

        // Message successfully published to specified channel.
    }
    else {

        /**
from pubnub.exceptions import PubNubException
try:
    envelope = pubnub.publish().channel("my_channel") \
    .message({ 
        'name': 'Alex',
        'online': True
    }) \
    .custom_message_type("text-message") \
    .sync()
    print("publish timetoken: %d" % envelope.result.timetoken)
except PubNubException as e:
    handle_exception(e)
$result = $pubnub->publish()
    ->channel("my_channel")
    ->message(["hello", "there"])
    ->shouldStore(true)
    ->ttl(15)
    ->usePost(true)
    ->customMessageType("file-message")
    ->sync();
#include "Kismet/GameplayStatics.h"
#include "PubnubSubsystem.h"

UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this);
UPubnubSubsystem* PubnubSubsystem = GameInstance->GetSubsystem<UPubnubSubsystem>();

FString Channel = "randomChannel";
FString Message = "{ \"text\" : \"This is my message\" }";

// Create an instance of FPubnubPublishSettings
FPubnubPublishSettings PublishSettings;
PublishSettings.CustomMessageType = "text-message"; // Set the CustomMessageType

// Publish the message with custom publish settings
PubnubSubsystem->PublishMessage(ChannelName, Message, PublishSettings);

Read Message Types for an overview of the new parameter and information on how it differs from the internal PubNub message type.

Unreal SDK JSON wrappers

Type: Improvement

Until now, all functions that provide server data like GetChannelMetadata() or FetchHistory() returned a JSON string, which may be difficult to handle due to the complex structure and possible parsing and debugging issues. That's why we decided to support an additional format of returned data and introduced output wrappers (custom structs) to encapsulate data in a more structured and type-safe way.

PubnubSubsystem->FetchHistory(
    FString Channel, 
    FOnFetchHistoryResponse OnFetchHistoryResponse, 
    FPubnubFetchHistorySettings FetchHistorySettings = FPubnubFetchHistorySettings()
);
Response variants

You can also call the {MethodName}_JSON() variant of each such method to get a FOnPubnubResponse, which contains pure JSON, like FetchHistory_JSON().

Shared workers in JS SDK

Type: New feature

We introduced a new shared workers configuration option in the JavaScript SDK to help you:

  • Manage concurrent connections across multiple client instances.
  • Reduce redundant operations such as multiple long-poll subscriptions by aggregating requests across multiple contexts.
  • Prevent false presence events by ensuring that leave events are only triggered when all associated tabs and windows are closed.
  • Coordinate shared data or state across different parts of an application running in separate contexts (like collaborative editing, shared state management, or ensuring data consistency across different views or interfaces).

The shared worker source must be hosted under the exact origin as the client app, following the Same-origin Policy.

To use shared workers, configure the subscriptionWorkerUrl parameter in the PubNub client during initialization:

const pubnub = new PubNub({
  subscribeKey: "demo",
  publishKey: "demo",
  userId: "unique-user-id",
  // using PubNub JS SDK v8.3.1, make sure the versions match
  subscriptionWorkerUrl: 'https://www.my-domain.com/static/js/pubnub.worker.8.3.1.js'
});

Tree shaking in JS SDK

Type: New feature

The JS SDK now lets you opt out of specific modules you don't need and optimize the final bundle size. You can do that by using either of two popular JavaScript build tools: Rollup or Webpack.

By only including the necessary modules and excluding the ones that aren't used, the application becomes more efficient and faster to load.

Refer to the Configuration doc for details.

TTL in Publish API accepts floats

Type: Enhancement

We extended the scope of the time-to-live (ttl) parameter, which you can use in Publish API calls to override the TTL value for Message Persistence set on your keyset.

ttl now accepts both integer (like 1 = 1 hour) and floating-point (0.5 = 30 minutes) numbers.

curl -L 'https://ps.pndsn.com/publish/demo/demo/0/channel/myCallback/%7B%22text%22%3A%22PubNub%20is%20awesome!%22%7D?uuid=user&ttl=0.5' \
-H 'Accept: application/json'

Insights ๐Ÿ“Š

Insights & BizOps collab

Type: New feature

Back in June, we communicated a new Import from Insights feature in BizOps Workspace that let you automatically import top 20 users and channels from Insights directly to your User and Channel Management views.

This time, we mirrored this functionality on the Insights end, letting you Export to BizOps top 20 data for users and channels.

Export data to BizOps

In addition, the new embedded links in the Top 20 Users and Top 20 Channels tables let you view the details of individual users and channels in BizOps Workspace.

View data in BizOps

ย