Migrating from PubNub to WebSockets
RingCentral's use of PubNub is officially deprecated and will eventually be discontinued. All developers are required to migrate their applications to use WebSockets instead. Depending upon how you have implemented PubNub, your migration path may vary, and this guide will hopefully put you on the right path.
Add the WebSocketsSubscription app scope to your app
With the introduction of WebSockets we are making another change to the platform. Currently we support a single app scope called Subscriptions, which we will breaking out into three distinct scopes:
- Webhook Subscriptions
- PubNub Subscriptions
- WebSockets Subscriptions
We are attempting to update everyone's apps on their behalf to ease the migration experience, but developers should double check their app and confirm that the necessary app scopes are present. If they are not, please add them.
Migrate your code to use WebSockets
In migrating away from PubNub, every developer will need to make as least some small change to their code. The size and nature of that change will depend almost entirely upon your specific implementation, which can fall into two main buckets.
Migrating code manually for self-built SDKs
Some developers choose not to use an SDK provided by RingCentral. If this is the case for you, then you will need to make a number of changes to switch to the WebSockets. We have two guides that walk through how we have implemented WebSockets to help you with this process:
Even if you do not use a RingCentral SDK, we strongly recommend using a third-party library to help implement the WebSockets protocol.
Upgrading your RingCentral SDK
If you use a RingCentral SDK, then you will need to update the most recent version of that SDK, and make a few changes to your source code. The following will provide the SDK-specific instructions to guide you in this process.
Upgrade ringcentral-js to version 5.0.0 or later.
There are no code changes you will need to make. When you upgrade to the latest version of the SDK, it will automatically begin using WebSockets if you were once using PubNub.
Upgrade ringcentral-python to version 0.8.0 or later.
Before
import os
import sys
from dotenv import load_dotenv
from ringcentral import SDK
from multiprocessing import Process
from time import sleep
from ringcentral.subscription import Events
load_dotenv()
rcsdk = SDK( os.environ.get('RC_APP_CLIENT_ID'),
os.environ.get('RC_APP_CLIENT_SECRET'),
os.environ.get('RC_SERVER_URL') )
platform = rcsdk.platform()
try:
platform.login( jwt=os.environ.get('RC_USER_JWT') )
except Exception as e:
sys.exit("Unable to authenticate to platform: " + str(e))
def on_message(msg):
print (msg)
def pubnub():
try:
s = rcsdk.create_subscription()
s.add_events([{FILTERS}]) # replace {FILTERS} with filter urls
s.on(Events.notification, on_message)
res = s.register()
try:
print("Wait for notification...")
except Exception as e:
print (e)
sys.exit(1)
while True:
sleep(0.1)
except KeyboardInterrupt:
print("Pubnub listener stopped...")
p = Process(target=pubnub)
try:
p.start()
except KeyboardInterrupt:
p.terminate()
print("Stopped by User")
sys.exit(1)
After
from ringcentral import SDK
from dotenv import load_dotenv
import asyncio
import os
from ringcentral.websocket.events import WebSocketEvents
def on_notification(message):
print(message)
def on_sub_created(sub):
print(sub.get_subscription_info())
def on_ws_created(web_socket_client):
print(web_socket_client.get_connection_info())
async def subscribe():
load_dotenv(override=True)
sdk = SDK(
os.environ['RC_APP_CLIENT_ID'],
os.environ["RC_APP_CLIENT_SECRET"],
os.environ["RINGCENTRAL_SERVER_URL"],
)
platform = sdk.platform()
platform.login(jwt=os.environ["RC_USER_JWT"])
try:
web_socket_client = sdk.create_web_socket_client()
web_socket_client.on(WebSocketEvents.connectionCreated, on_ws_created)
web_socket_client.on(WebSocketEvents.subscriptionCreated, on_sub_created)
web_socket_client.on(WebSocketEvents.receiveSubscriptionNotification, on_notification)
await asyncio.gather(
web_socket_client.create_new_connection(),
web_socket_client.create_subscription([{FILTERS}]) # replace {FILTERS} with filter urls
)
except KeyboardInterrupt:
print("Stopped by User")
Upgrade ringcentral-php to version 3.0.0 or later.
Before
<?php
use RingCentral\SDK\Subscription\Events\NotificationEvent;
use RingCentral\SDK\Subscription\Subscription;
$rcsdk = new RingCentral\SDK\SDK( $_ENV['RC_APP_CLIENT_ID'],
$_ENV['RC_APP_CLIENT_SECRET'],
$_ENV['RC_SERVER_URL'] );
$platform = $rcsdk->platform();
$platform->login( [ "jwt" => $_ENV['RC_USER_JWT'] ] );
$subscription = $rcsdk->createSubscription('Pubnub');
$subscription->addEvents(array('/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS'));
$subscription->addListener(Subscription::EVENT_NOTIFICATION, function (NotificationEvent $e) {
print 'Notification ' . print_r($e->payload(), true) . PHP_EOL;
});
$subscription->setKeepPolling(true);
$subscription->register();
?>
After
<?php
use RingCentral\SDK\WebSocket\WebSocket;
use RingCentral\SDK\WebSocket\Subscription;
use RingCentral\SDK\WebSocket\Events\NotificationEvent;
$rcsdk = new RingCentral\SDK\SDK( $_ENV['RC_APP_CLIENT_ID'],
$_ENV['RC_APP_CLIENT_SECRET'],
$_ENV['RC_SERVER_URL'] );
$platform = $rcsdk->platform();
$platform->login( [ "jwt" => $_ENV['RC_USER_JWT'] ] );
$websocket = $rcsdk->initWebSocket();
$websocket->connect();
$subscription = $rcsdk->createSubscription();
$subscription->addEvents(array('/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS'));
$subscription->addListener(Subscription::EVENT_NOTIFICATION, function (NotificationEvent $e) {
print 'Notification ' . print_r($e->payload(), true) . PHP_EOL;
});
$subscription->register();
Upgrade ringcentral-java to version 3.0 or later.
Before
package com.ringcentral;
import com.ringcentral.RestClient;
import com.ringcentral.RestException;
import com.ringcentral.definitions.CreateInternalTextMessageRequest;
import com.ringcentral.definitions.PagerCallerInfoRequest;
import com.ringcentral.pubnub.Subscription;
import java.io.IOException;
import com.google.gson.Gson;
public class SubscriptionExample {
static RestClient rc;
public static void main(String[] args)
throws RestException, IOException, InterruptedException {
RestClient rc = new RestClient(
System.getenv("RC_APP_CLIENT_ID"),
System.getenv("RC_APP_CLIENT_SECRET"),
System.getenv("RC_SERVER_URL")
);
rc.authorize(System.getenv("RC_USER_JWT"));
final String[] message = {null};
Subscription subscription = new Subscription(rc,
new String[]{"/restapi/v1.0/account/~/extension/~/message-store"},
(jsonString) -> {
message[0] = jsonString;
}
);
subscription.subscribe();
// sleep and wait for notifications
Thread.sleep(60000);
}
}
After
package com.ringcentral;
import com.ringcentral.RestClient;
import com.ringcentral.RestException;
import com.ringcentral.definitions.CreateInternalTextMessageRequest;
import com.ringcentral.definitions.PagerCallerInfoRequest;
import com.ringcentral.websocket.Subscription;
import java.io.IOException;
import com.google.gson.Gson;
public class SubscriptionExample {
static RestClient rc;
public static void main(String[] args)
throws RestException, IOException, InterruptedException {
RestClient rc = new RestClient(
System.getenv("RC_APP_CLIENT_ID"),
System.getenv("RC_APP_CLIENT_SECRET"),
System.getenv("RC_SERVER_URL")
);
rc.authorize(
System.getenv("RC_USER_JWT")
);
final String[] message = {null};
Subscription subscription = new Subscription(rc,
new String[]{"/restapi/v1.0/account/~/extension/~/message-store"},
(jsonString) -> {
message[0] = jsonString;
}
);
subscription.subscribe();
// sleep and wait for notifications
Thread.sleep(60000);
}
}
Upgrade RingCentral.Net to version 6.0 or later.
Before
using RingCentral;
using dotenv.net;
DotEnv.Load();
namespace SubscriptionExample {
class Program {
static RestClient restClient;
static PubNubExtension pubnub;
static async Task Main(string[] args) {
restClient = new RestClient(
Environment.GetEnvironmentVariable("RC_APP_CLIENT_ID"),
Environment.GetEnvironmentVariable("RC_APP_CLIENT_SECRET"),
Environment.GetEnvironmentVariable("RC_SERVER_URL"));
await restClient.Authorize(Environment.GetEnvironmentVariable("RC_USER_JWT"));
pubnub = new PubNubExtension();
await restClient.InstallExtension(pubnub);
}
static private async Task subscribe_to_events() {
await pubnub.Subscribe(new string[] {
"/restapi/v1.0/account/~/extension/~/message-store"
}, message => { Console.WriteLine(message) });
}
}
}
await rc.Revoke();
After
using RingCentral;
using dotenv.net;
using RingCentral.Net.WebSocket;
DotEnv.Load();
namespace SubscriptionExample {
class Program {
static RestClient restClient;
static WebSocketExtension webSocket;
static async Task Main(string[] args) {
restClient = new RestClient(
Environment.GetEnvironmentVariable("RC_APP_CLIENT_ID"),
Environment.GetEnvironmentVariable("RC_APP_CLIENT_SECRET"),
Environment.GetEnvironmentVariable("RC_SERVER_URL"));
await restClient.Authorize(Environment.GetEnvironmentVariable("RC_USER_JWT"));
webSocket = new WebSocketExtension(new WebSocketOptions { debugMode = true });
await restClient.InstallExtension(webSocket);
await subscribe_to_events();
}
static private async Task subscribe_to_events() {
await webSocket.Subscribe(new string[] {
"/restapi/v1.0/account/~/extension/~/message-store"
}, message => { Console.WriteLine(message) });
}
}
}
await rc.Revoke();
Upgrade ringcentral-ruby to version TODO or later.
Before
events = [
'/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS',
]
s = PubNub.new($rc, events, lambda { |message|
callback.call(message)
})
s.subscribe()
After
events = [
'/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS',
]
s = rcsdk.create_subscription()
s.add_events( events )
s.on( Events.notification, lambda { |message|
callback.call(message) })
s.subscribe()
Remove the PubNubSubscription app scope from your application
The final step in your migration is to remove the PubNub Subscription app scope from your app via the Developer Console. When this is done, PubNub will be disabled in your account, and your migration will be complete.