Chat-based customer support built on nPubSub

[Editor]: This article is translated from the Chinese version by @heron.

You might have seen those ubiquitous online chat bubbles for customer support, in many modern websites. Do you know that you can create similar online customer support chat quickly and easily using NKN’s nPubSub function? In this article, we will use show an example of such a customized customer support chat system using the NKN Javascript SDK.

04 PM
28 PM


1. Client UI: we will not cover this in detail

2. Customer Support staff UI: we will use D-Chat or nMobile for private group.

If you use D-Chat, you can install the Chrome/Brave browser extension as below:


3. SDK: nkn-wallet , nkn-multiclient

$ yarn add nkn-wallet
$ yarn add nkn-multiclient

Create private group for customer support staff

Regular nPubSub API can create public group, that anyone can join and send/receive messages. In our example, how can we make sure that only authorized customer support staff can receive and respond to client requests? The answer is permission control and private/permissioned group.

1. Subscribe to a private topic/group. In order to distinguish from the regular/public group, we will use a self-defined format topic.address

Note: If you use nMobile to create the private group, you can skip this step.

import Wallet from 'nkn-wallet'

// Create a new wallet, in order to manage private topic
let wallet = Wallet.newWallet('PASSWORD')
// If there is existing wallet
// let wallet = Wallet.restoreWalletBySeed('SEED','PASSWORD')
let seed = wallet.getSeed() // save seed

// Subscribe to private topic
let address = `${wallet.getPublicKey()}`
let topic = `TOPIC.${address}`

// Add private group member addresses. Please keep the size of array for each page within the limit of meta data max size, and you might need multiple calls for large group.
wallet.subscribe(topic, 400000, `__0__.__permission__`, JSON.stringify({accept: [{addr:'ADDRESS1'},{addr:'ADDRESS2'},/*...*/]}))
wallet.subscribe(topic, 400000, `__1__.__permission__`, JSON.stringify({accept: [{addr:'ADDRESS3'},{addr:'ADDRESS3'},/*...*/]}))
// ......

2. Client will get the list of addresses of authorized customer support staff for this private topic

import Client from 'nkn-multiclient'

let client = Client()
// Get the list of addresses of customer support staff
let getSubscribers = async function (topic, owner) {
  let i = 0
  let members = [owner]
  while (true) {
    // Use _i_ as index, query all pages
    let res = await client.clients[0].getSubscription(`${topic}`, `__${i}__.__permission__.${owner}`)
    let meta
    try {
      meta = JSON.parse(res.meta)
    } catch (e) {
    if (meta && meta.accept && meta.accept.length > 0) {
      // If the group is not empty, merge all data
      meta.accept.forEach(x=> members.push(x.addr))
    } else {
      // Quit if the private group is empty
  return members

3. Send and receive customer support messages

async function main (){
  // Get the list of addresses of customer support staff
  let dests = await getSubscribers(topic, address)
  // Package the data into private chat format compatible with D-Chat
  let data = {
    contentType: 'text',
    id: uuidv4(), // import uuidv4 from 'uuid/v4'
    content: 'hello world',
    isPrivate: true,
    timestamp: new Date().getTime()

  client.on('connect', function () {
    // Group send message to private group members
    client.send(dests, JSON.stringify(data))

  // Receive customer support message
  client.on('message', function (src, data) {
    // src: sender address, data: received message
    let message = JSON.parse(data)
    if (message.contentType === 'text') {
      // TODO ... Display message to customer support staff UI
      // Package into an Acknowledgement message that is compatible with D-Chat
      let receipt = {
        contentType: 'receipt',
        id: uuidv4(), // import uuidv4 from 'uuid/v4'
        timestamp: new Date().getTime(),
        isPrivate: true
      // Send acknowledgement message
      client.send(dests, JSON.stringify(receipt))

Now we can receive the customer support messages in D-Chat!


Source code example for vue module