Documentation Release Notes - November 2024
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"))
show all 17 lines// 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"))
show all 18 linesLocal 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);
show all 16 linesval 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"
show all 23 linesPNConfiguration.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 -> {
show all 20 linespubnub.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 {
/**
show all 24 linesfrom 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.
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.