Categories
Healthcare IT

How to build a HIPAA Compliant Chat App using PubNub

Building a HIPAA secure chat application for your medical practice. Here are tips and tricks, the design choices to make and possible issues.

  1. Business Problem

    We need to develop a chat application for the doctors and the referral coordinators. The application has to be a HIPAA Compliant. The chat application will be used to communicate about the referral and the patient-related information. And, we made it using PubNub.

    To meet the requirement we had two choices, either create our own chat application which required a thorough knowledge of the system architecture and WebSocket programming. We also had to invest in gateways’, servers’ database and also look after the security of the data. 

    Or we could use PubNub as this removed the overhead of hiring the Domain expertise for the system architecture needed for Chat. So, PubNub was our preferred choice. 

    We need to develop a chat application for the doctors and the referral coordinators. The application has to be a HIPAA Compliant. The chat application will be used to communicate about the referral and the patient-related information. 

    We had two choices, either create our own chat application which required a thorough knowledge of the system architecture and WebSocket programming. We also had to invest in gateways’, servers’ database and also look after the security of the data. 

    Or we could use PubNub as this removed the overhead of hiring the Domain expertise for the system architecture needed for Chat. So, PubNub was our preferred choice. 

    hipaa-secure-messaging-platform-considerations

  2. What is PubNub and its utility?

    PubNub is a Programmable Network for developing real-time applications; an evolution from three-tier architecture, purpose-built to handle all the complexities of data streams. PubNub operates at the edge of the network to handle and apply logic to real-time data, thereby minimizing latency to 100 milliseconds or less worldwide, and guaranteeing reliability and scalability.

    The PubNub DSN empowers developers to provide an out-of-the-box ‘always-on, real-time’ experience for their applications leaving engineers, architects, developers, product managers, and others to focus on solving the actual business problems for their company and their customers, rather than worrying about the network, infrastructure, and support resources needed to maintain their own Data Stream Network.

    So in simple words, it helps us create the chat application by providing everything needed to be successful. Also, it saved us a lot of effort needed for designing the system architecture.
    In PubNub, we need to create the channel IDs which must be unique. We created those on the server and the channel IDs are associated with the users who can access that channel. And whenever the user asks for access to the channel he is associated with, the server sends these channel IDs to the users. 

    You must be wondering what is a channel ID? You will get a clear understanding as we move forward. For now, just remember that it is a unique channel ID on which communication is going to happen. 

    We also created a Channel Group with its ID as the username of the user. In this group, all the channels created for the user were added.
     
    Now there are two aspects of PubNub which you need to understand: one is the Subscribe and the second is the Listener. 
    Subscribing the channel will generate an event in which anyone listening to that channel can listen to. If the other user has set a listener on that channel. It creates a JOIN event so that the other user knows that the user one has now subscribed and is online on this channel. 

    Let me give you an example for a better understanding. 

    Suppose that user A subscribed to channel ID and user B is listening to that channel then user A Left. 

    Listeners not only listen to the JOIN and Left event but also get to know if the message was sent by the other user. 

    Now let us understand this by a scenario – user A wants to communicate with user B so now user A calls the API and asks the server that it wants to chat with user B. So the server checks if a channel is already created on the server between these two. If yes, then return the channel ID created earlier, if not send a new channel ID and map the ID’s of these two users against this newly generated channel ID.

    Now that the channel is created and the user A has the channel ID. The user A can start sending the messages on this channel ID. Now, remember we created a username channel-group where all the channel IDs associated were added, will receive an event of JOIN. If the user A unsubscribes, the user B will receive the event as the add this newly created channel ID in the username channel group of user A and B both. 

    Since user B is listening to its username channel-group, it will get an event where it will get this newly created channel ID. Which the user B can use to fetch more information from the server using this channel ID. Like the new details of the user who created this channel ID. So that it can be displayed in the recent chat list. 

    Whenever a message is sent to the channel ID by user A, user B will receive it on the username channel group which can be updated on the recent chat list. 

    Now if User B also opens the communication activity on that channel, as soon as the user enters the communication channel there are four things that it does: 
     It subscribes to that channel ID
    It fetches the last 25 Messages on that channel from PubNub.
    It listens to that channel. Meanwhile, it will start receiving real-time communication on that channel ID. It also starts updating the real-time message received from user A, also the message sent by user B on the communication activity. 
    It also checks for Here Now. In PubNub, we need to create the channel IDs which must be unique. We created those on the server and the channel IDs are associated with the users who can access that channel. And whenever the user asks for access to the channel he is associated with, the server sends these channel IDs to the users. 

    You must be wondering what is a channel ID? You will get a clear understanding as we move forward. For now, just remember that it is a unique channel ID on which communication is going to happen. 

    We also created a Channel Group with its ID as the username of the user. In this group, all the channels created for the user were added.
     
    Now there are two aspects of PubNub which you need to understand: one is the Subscribe and the second is the Listener. 
    Subscribing the channel will generate an event in which anyone listening to that channel can listen to. If the other user has set a listener on that channel. It creates a JOIN event so that the other user knows that the user one has now subscribed and is online on this channel. 

    Let me give you an example for a better understanding. 

    Suppose that user A subscribed to channel ID and user B is listening to that channel then user A Left. 

    Listeners not only listen to the JOIN and Left event but also get to know if the message was sent by the other user. 

    Now let us understand this by a scenario – user A wants to communicate with user B so now user A calls the API and asks the server that it wants to chat with user B. So the server checks if a channel is already created on the server between these two. If yes, then return the channel ID created earlier, if not send a new channel ID and map the ID’s of these two users against this newly generated channel ID.

    Now that the channel is created and the user A has the channel ID. The user A can start sending the messages on this channel ID. Now, remember we created a username channel-group where all the channel IDs associated were added, will receive an event of JOIN. If the user A unsubscribes, the user B will receive the event as the add this newly created channel ID in the username channel group of user A and B both. 

    Since user B is listening to its username channel-group, it will get an event where it will get this newly created channel ID. Which the user B can use to fetch more information from the server using this channel ID. Like the new details of the user who created this channel ID. So that it can be displayed in the recent chat list. 

    Whenever a message is sent to the channel ID by user A, user B will receive it on the username channel group which can be updated on the recent chat list. 

    Now if User B also opens the communication activity on that channel, as soon as the user enters the communication channel there are four things that it does: 
     It subscribes to that channel ID
    It fetches the last 25 Messages on that channel from PubNub.
    It listens to that channel. Meanwhile, it will start receiving real-time communication on that channel ID. It also starts updating the real-time message received from user A, also the message sent by user B on the communication activity. 
    It also checks for Here Now. In PubNub, we need to create the channel IDs which must be unique. We created those on the server and the channel IDs are associated with the users who can access that channel. And whenever the user asks for access to the channel he is associated with, the server sends these channel IDs to the users. 

    You must be wondering what is a channel ID? You will get a clear understanding as we move forward. For now, just remember that it is a unique channel ID on which communication is going to happen. 

    We also created a Channel Group with its ID as the username of the user. In this group, all the channels created for the user were added.
     
    Now there are two aspects of PubNub which you need to understand: one is the Subscribe and the second is the Listener. 
    Subscribing the channel will generate an event in which anyone listening to that channel can listen to. If the other user has set a listener on that channel. It creates a JOIN event so that the other user knows that the user one has now subscribed and is online on this channel. 

    Let me give you an example for a better understanding. 

    Suppose that user A subscribed to channel ID and user B is listening to that channel then user A Left. 

    Listeners not only listen to the JOIN and Left event but also get to know if the message was sent by the other user. 

    Now let us understand this by a scenario – user A wants to communicate with user B so now user A calls the API and asks the server that it wants to chat with user B. So the server checks if a channel is already created on the server between these two. If yes, then return the channel ID created earlier, if not send a new channel ID and map the ID’s of these two users against this newly generated channel ID.

    Now that the channel is created and the user A has the channel ID. The user A can start sending the messages on this channel ID. Now, remember we created a username channel-group where all the channel IDs associated were added, will receive an event of JOIN. If the user A unsubscribes, the user B will receive the event as the add this newly created channel ID in the username channel group of user A and B both. 

    Since user B is listening to its username channel-group, it will get an event where it will get this newly created channel ID. Which the user B can use to fetch more information from the server using this channel ID. Like the new details of the user who created this channel ID. So that it can be displayed in the recent chat list. 

    Whenever a message is sent to the channel ID by user A, user B will receive it on the username channel group which can be updated on the recent chat list. 

    Now if User B also opens the communication activity on that channel, as soon as the user enters the communication channel there are four things that it does: 
     It subscribes to that channel ID
    It fetches the last 25 Messages on that channel from PubNub.
    It listens to that channel. Meanwhile, it will start receiving real-time communication on that channel ID. It also starts updating the real-time message received from user A, also the message sent by user B on the communication activity. 
    It also checks for Here Now.

  3. How to implement PubNub?
    What is PubNub and its utility? What is PubNub and its utility? What is PubNub and its utility?

    In PubNub, we need to create the channel IDs which must be unique. We created those on the server and the channel IDs are associated with the users who can access that channel. And whenever the user asks for access to the channel he is associated with, the server sends these channel IDs to the users. 

    You must be wondering what is a channel ID? You will get a clear understanding as we move forward. For now, just remember that it is a unique channel ID on which communication is going to happen. 

    We also created a Channel Group with its ID as the username of the user. In this group, all the channels created for the user were added.
     
    Now there are two aspects of PubNub which you need to understand: one is the Subscribe and the second is the Listener. 
    Subscribing the channel will generate an event in which anyone listening to that channel can listen to. If the other user has set a listener on that channel. It creates a JOIN event so that the other user knows that the user one has now subscribed and is online on this channel. 

    Let me give you an example for a better understanding. 

    Suppose that user A subscribed to channel ID and user B is listening to that channel then user A Left. 

    Listeners not only listen to the JOIN and Left event but also get to know if the message was sent by the other user. 

    Now let us understand this by a scenario – user A wants to communicate with user B so now user A calls the API and asks the server that it wants to chat with user B. So the server checks if a channel is already created on the server between these two. If yes, then return the channel ID created earlier, if not send a new channel ID and map the ID’s of these two users against this newly generated channel ID.

    Now that the channel is created and the user A has the channel ID. The user A can start sending the messages on this channel ID. Now, remember we created a username channel-group where all the channel IDs associated were added, will receive an event of JOIN. If the user A unsubscribes, the user B will receive the event as the add this newly created channel ID in the username channel group of user A and B both. 

    Since user B is listening to its username channel-group, it will get an event where it will get this newly created channel ID. Which the user B can use to fetch more information from the server using this channel ID. Like the new details of the user who created this channel ID. So that it can be displayed in the recent chat list. 

    Whenever a message is sent to the channel ID by user A, user B will receive it on the username channel group which can be updated on the recent chat list. 

    Now if User B also opens the communication activity on that channel, as soon as the user enters the communication channel there are four things that it does: 
     It subscribes to that channel ID
    It fetches the last 25 Messages on that channel from PubNub.
    It listens to that channel. Meanwhile, it will start receiving real-time communication on that channel ID. It also starts updating the real-time message received from user A, also the message sent by user B on the communication activity. 
    It also checks for Here Now.
    PubNub is a Programmable Network for developing real-time applications; an evolution from three-tier architecture, purpose-built to handle all the complexities of data streams. PubNub operates at the edge of the network to handle and apply logic to real-time data, thereby minimizing latency to 100 milliseconds or less worldwide, and guaranteeing reliability and scalability.

    The PubNub DSN empowers developers to provide an out-of-the-box ‘always-on, real-time’ experience for their applications leaving engineers, architects, developers, product managers, and others to focus on solving the actual business problems for their company and their customers, rather than worrying about the network, infrastructure, and support resources needed to maintain their own Data Stream Network.

    So in simple words, it helps us create, the chat application by providing everything needed to be successful. Also, it saved us a lot of effort needed for designing the system architecture. 

  4. Let’s talk about “Here Now”

    I think by now we know about the Subscribe and Listeners. Now, this is one more new term – Here Now. This is used to know who is actively chatting on this channel. The Listener will let us know whenever a new user subscribes to the channel. But Here Now will let us know who all already subscribe to the channel. We will discuss this further why we need to know who all are subscribed to the channel. 

    Whenever the user leaves the communication activity the user unsubscribes to that channel. 

    Now, why do we subscribe and unsubscribe when listeners are the ones providing us with real-time communication and why do we do Here Now? 

    The answer to this question is as simple as we want to send the push notification to the users who are not actively chatting on the channel to know who is active and not active we use subscribe unsubscribe and do Here Now. So that we can choose who to send the notification and who not to send. 

    There were still two major issues for us as we wanted to add two features that were of the utmost importance. 
    Online status. 
    Unread Count

    How we handled this is also very interesting to know. 
    Online status of the users
    We created another channel group with the channel ID as username-connections. For example, if my username is Dhiraj then I would subscribe to “Dhiraj-connections” Now in this group, all the user names of the users with whom I have chatted earlier would be added whenever I create a new chat with some user that user’s username channel gets added. 

    We not only subscribe to this channel group but also we listen to this channel group. If you remember in the beginning I wrote that everyone subscribes to their username channel. So now, every time a user who I had chatted earlier and is a part of my username-connections channel will generate an event JOIN and LEFT whenever they subscribe and unsubscribe to their username channel. 

    This helps us determine in real-time who is online and who goes offline. So whenever the app goes in the background we unsubscribe to the username channel. 
    You will be having a question what if the user had subscribed earlier to us starts to listen to the channel? The answer is we use Here Now on the username-connections channel group to know who had already subscribed to their username channel. 

    I hope this explains how we showed the online and offline users on our recent chat screen. Where we can see all the users whom we have chatted earlier. 

    Unread Count.
    This is even more interesting to know. This was tricky and we had no easy way of doing this. So we created a channel “unread count-chat” and we also created a service in PubNub that would listen to this channel. 

    Whenever user A sends (publish) a message to user B and user B is not online, then user A will also publish an increment message on the “unread-count-chat” channel which has the following details. Channel ID, username, first name and last name of the user B. 

    We have a service that listens to this channel (unread-count-chat). What it does is simply create a key by combining channel_ID and username and saves increment count in this. If the second time a message is received it first fetches the count using the key of channel ID and username and adds to it and saves again. Then it also publishes the unread count with message type as “unread count” on the username channel of user B. So now if a user is online and is looking at the recent chat screen he can see that a new message was received and the count was updated. 

    Now if user B goes into that channel on communication activity then it first publishes a message to zero the unread count for this channel. 

    This way we always get the correct unread count. 

    Now about the Push Notification. We had previously gone for push notification from the server-side. We achieved this as follows. 

    Now the user publishes (sends) the message on the channel in that message, it sends one more parameter which suggests if the other user is actively chatting on the channel or not. There is another service on PubNub all it does is no matter where the message was published it sends that to our server. Our server gets the channel ID and the username to whom it was sent and the active status. If the server finds that the other user is not active on the channel then it sends the push notification to the other user. 

    In the next blog, we will discuss Group chat and its implementation. We will also discuss the various problems faced and the solutions that we came up with to resolve those. So stay tuned! 

  5. How to make a chat app secure?

    Now, we need the chat to be secured. The implementation in an earlier blog, it needs to be secure since anyone with the channel ID can easily fetch the chat details. 

    So we need to add a new feature called PubNub Access Manager. This may sound like something very difficult to implement. But in reality, it is pretty easy. We did that by using Pubnub Access Manager

  6. How to implement the PubNub Access Manager?

    Let us see how we can implement the PubNub Access Manager. First, you need to enable the Pubnub Access Manager option from the PubNub console for our project. 

    Once you are done with that you will no longer be able to subscribe to channel ID, publish or do anything on that channel. 

    So now the server comes into the picture and gives us access to the channel ID. The server creates an Access Key and gives access to all the channels for this newly created key. This key is valid for only 24 hours. 

  7. How to create a group chat?

    When any application (android/ ios/ web) asks for the channels for the user, the server generates a key if it is not present or is invalid. Then it sends it to the application. The application will use this access key to initialize the PubNub object. Once the PubNub object is initialized with this key, all the channels can be accessed using this key. Whenever the new channel is created the access key provides access to this newly created channel ID. For both parties who are associated with the channel.

  8. What’s the difference between one to one and group chat?

    In one to one chat there are two parties and in the group chat multiple users are involved and so the same channel ID is associated with multiple users. Multiple users will have access to that channel. The server will have to provide a new access key to each of them and each access key will have access to this Group Channel ID.

    To make a group, the user selects the users and gives a name to the group and uses an API where he sends the ID of the users and the group name that he wants to create. The server then creates a channel ID and associate all the users’ ID with this channel ID.

    In group chat also users subscribe to the channel whenever they want to start communication. They also listen to the channel ID for new messages and online status.

    Whenever the user subscribes to a channel the other users who are listening to that channel will get a Join event. This way all the users are aware of who is now actively chatting on this channel. 

  9. Is there a need to use HERE NOW in group chat?

    In group chat also we need to do ‘Here Now’ as soon as we enter the chat activity for the channel. Here Now will provide us with the user IDs of the users who have subscribed to the channel before we subscribe to that channel. 

    Now that we know who all are online, we create the array of the users who are not active on the channel. Whenever we publish the message on the channel ID we also provide the array of the users who are not active on the channel.  

    Like we have seen there is a service on PubNub which listens to all the communications happening on the PubNub channels. It relays the information to the server. The server then sends the notification to all the users who are not online.

  10. Can we send notifications directly through PubNub?

    Let’s discuss the other option where we can start sending the Notification directly from the PubNub instead of relaying it to the server and then sending the notification. 

    First, we need to activate the notification on the PubNub console. We also need to provide the server key for Firebase android notification and .pem file for IOS notification.

    On the app side, we fetch the registration token for android and device ID token for IOS and associate this with the username channel. Now the service which listens to all the communications will send a notification to the username channel. If you remember we send an array of the username who are not online in case of group chat whereas in one to one chat we send the online status and the username of the other user. 

    PubNub publishes the message on the username channel. This is a special message. It publishes the two payloads.
    1. pn_gcm
    2. pn_apns

    In order to send the notification to an android and ios device. This message is received like we receive the normal notification. We also receive this message on the username channel in case we are online(if you remember we had subscribed to username channel when we started the app)  but we ignore such messages. 

  11. What issues can you face?

    The issue you can face is of unread count and recent chat messages, just like us.

    The unread count and the latest message would stop working once we start chatting on the channel and came back to the recent chat list. 

    This was happening because we subscribed to the channel when we start the chat and we unsubscribe when we came out of chat. 

    We subscribe to the username channel group which has all the channels associated with it. Since we use the singleton PubNub Object the channel that we visited and when we came out the channel it got unsubscribed. Hence, messages sent on that channel were not received on the username channel listener. To fix the problem, we created two PubNub objects one to chat on the channel, one for receiving the unread count and recent chat message.

Leave a Reply

Your email address will not be published. Required fields are marked *