Websockets enables 2 way chat

Enabling bi-directional, full duplex messages to be instantly distributed with little overhead 

Recently, I stumbled upon a new technology called Websockets while working on a client product for their real time chat / texting application.  The application was built to empower advisors and agents within Salesforce to engage with clients using text messaging, while adhering to regulatory standards.

The Situation

Companies are trying to engage with clients using modern channels like social media, text messaging and mobile calling. In order to provide a real time chat / texting experience , the application needs to establish a real time communication between client (browser) and server. The application was originally built using a polling mechanism which drastically increased load on the servers to fetch real time chat data for the advisors. This polling mechanism imposed a couple of challenges:

  • Advisor user had to wait 5 sec to send / receive data.
  • Browser / Server polling increases the number of API calls.
  • It is not scalable as the number of Adviser users increases on the platform. 
  • Does not provide a real time chat / texting experience.

While driving adoption with robust client engagement is really important, the mechanism of polling does not help to have real-time activity sync of text messages in Salesforce.

In order to provide a real time chat experience, we need to have a service which is scalable, seamless and provides minimal latency. This is when we got introduced to Pusher

By transitioning to a WebSocket-based solution, the load on the servers dropped dramatically and reduced the burden on their servers.

Pusher Introduction

Pusher provides real time infrastructure as a service for communicating with application servers and clients. Clients can be web browsers or mobile devices. Since pusher is a hosted service, it is massively scalable, secure and quick. They use WebSockets to publish and receive information to/from application servers and clients.

WebSockets have represented a long awaited evolution in client/server web technology. They allow a long-held single TCP socket connection to be established between the client and server, enabling bi-directional, full duplex messages to be instantly distributed with little overhead, resulting in a highly efficient, very low latency connection.

Pusher has 2 products which should be used based on the use case. 

Channels logo

Pusher Channels provides real time communication between servers, apps and devices. Channels is used for real time charts, realtime user lists, realtime maps, multiplayer gaming, and many other kinds of UI updates.

Beams logo

Pusher Beams is an API for mobile app developers to add Push Notifications sending capability to their apps.

Pusher Channels

In the Salesforce application use case, we used Pusher Channels to give the Salesforce advisors and agents a real time communication experience which uses Publish / Subscribe mechanism using WebSockets. Channels allows you to send messages to and from a server and receive event-driven responses without continuously polling the server, resulting in a highly efficient data transfer model. There are 4 types of channels at the moment:

  • Public channels can be subscribed to by anyone who knows their name.
  • Private channels should have a private- prefix. They introduce a mechanism which lets your server control access to the data you are broadcasting.
  • Private encrypted channels should have a private-encrypted- prefix. They extend the authorization mechanism of private channels, adding encryption of the data payloads so that not even Pusher can get access to it without authorization.
  • Presence channels should have a presence- prefix and are an extension of private channels. They let you ‘register’ user information on subscription, and let other members of the channel know who’s online.

Pusher Salesforce Integration 

For the purpose of real time chat experience in Salesforce, we used Pusher Private Channels with authorization mechanism from the external platform application server.

Pusher Diagram for Salesforce & External Programs

Prerequisites for Private Channels Integration

  1. Advisor / Agent in Salesforce logs into the external application using OAuth flow.  User authentication token is stored in  a protected custom setting.
  2. Download the latest version of Pusher Javascript file from here and upload it in Static Resource. 
  3. Pusher JS does not have issues with locker service, but it does not currently work with Salesforce Lightning Web Security (LWS).  In Salesforce Summer ‘23 , LWS is applicable for Aura components also. 
  4. Ensure to validate Pusher JS library in LWS Console to see if the LWS limitations are removed are not. If there are no issues with LWS, ensure to develop your components directly in Lightning Web Components.
  5. If there are issues with LWS with the latest Pusher JS version, ensure to follow either of the below options:
    • Navigate to Setup → Session Settings and Uncheck the Use Lightning Web Security check box
      Note : It is ideally NOT recommended to disable LWS in Salesforce setup.
    • We are hoping that Pusher JS will support LWS in the future. The only other option if we do not want to disable LWS, is to use Pusher JS inside a Visualforce Page. Below are the details about embedding Pusher JS inside Visualforce Page and interacting with Parent Lightning Web Components or Aura Components.  

Pusher Integration

As part of the pusher Salesforce use case , the texting widgets with PusherJS were built using custom Aura, Visualforce and LWC components. These components can be dropped in Salesforce homepages and  record pages to provide more insight about the customer engagement. Below are some high level use cases which provide a scalable and high performant real time chat / texting experience:

  • Notification utility bar component to notify agents about multiple client interactions.
  • Home page component to display a list of all conversations for the agent.
  • Record page component to display chat / texting widget with complete conversation history. 

Due to the PusherJS restrictions with lightning web security, the below suggested visualforce mechanism is used for the integration. If LWS supports Pusher JS in future, we can directly use it in Lightning Web Components. 

  1. Develop a Visualforce wrapper for embedding the Pusher JS script to bind to a private channel. Below is sample code.
  2. Use Javascript remoting to make apex controller calls to get the Pusher Key and authentication token. If the application is a managed package , Pusher Key can be stored as part of an admin setting in protected custom settings. 
  3. auth_token should be retrieved initially as part of the application server api authentication.  Public channels DO NOT need any authentication. Note : If you want to play with Public Channels, Setup your account in Pusher and get your free API keys.
  4. Every published event has an “event name”. The event you will publish will have the event name my-event.
Copy to Clipboard
  1. Use the above visualforce page as an iframe inside the aura component.A Visualforce page hosted in Lightning Experience is loaded in an iframe. In other words, it’s loaded in its own window object which is different from the main window object where the Lightning Components are loaded.
  2. The browser’s same-origin policy prevents a page from accessing content or code in another page loaded from a different origin (protocol + port + host).
  3. These restrictions are enforced for very good reasons. But fortunately, there is also an API (otherWindow.postMessage()) that provides a secure approach (when used properly) to exchange messages between different window objects with content loaded from different origins.

Sending the Message in a Visualforce Page 

Visualforce Page with parent.PostMessage()

Copy to Clipboard

Receiving the Message in a Lightning Component 

To receive the messages in your Lightning Component, you set up a listener for message events:

Aura Component

Copy to Clipboard

Aura Component Controller

Copy to Clipboard

With this infrastructure in place, the Lightning component can now listen for events sent by the Visualforce page and forward any relevant events to other Lightning components on the page using lightning message channels.

Use Cases for Salesforce 

PusherJs provides a powerful and scalable solution for real time communication, it can used in Salesforce in multiple use cases:

  1. Notification for Agents / Advisors in Salesforce Utility Bar about new interaction with a client.
  2. Help public facing community sites to improve gamification experience.
  3. Real Time Data Visualization: Create live data updates and insights.
  4. Apps for Customer Location Tracking: Monitor and track users’ locations in real-time.
  5. Chat Applications: Create multi-room and private conversations with agents and clients.