Adding a Realtime Chat Widget to your web app

We've built a Realtime Chat Widget that lets you to quickly add chat into your applications. In this short article we'll show how to add a Realtime Chat widget to your web application or web page. Then we'll provide you with a number of ideas of how to improve the widget by personalising it and integrating more closely it with you existing application.

This tutorial assumes that you have signed up for Pusher already, and have your API keys available.

We will cover the following:

Demo

To use the widget simply:

  1. Enter a nickname in the Name field
  2. Optionally supply an email address so the widget can lookup up your Gravatar and put a face to the name (don't worry your email isn't stored anywhere).
  3. Start chatting by entering some text in the message textarea and clicking the Send button

You can also try out a live side-by-side demo of the Realtime Pusher Chat widget.

The demo should load shortly...

Get the code

If you have a github account and are happy using git you can fork or clone the project from github (or download a zip instead).

Once you have the code you should make it accessible on your chosen web server hosting. For the purposes of getting up and running we’ll assume that the code is in a directory named pusher-realtime-chat-widget in the root of your app.

Adding the Realtime Chat Widget to the UI

To do this we’ll need to include a few JavaScript libraries; the Pusher JavaScript library, jQuery and the PusherChatWidget JavaScript library and stylesheet:

<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://js.pusher.com/2.2/pusher.min.js"></script> <script src="pusher-realtime-chat-widget/src/js/PusherChatWidget.js"></script> <link href="pusher-realtime-chat-widget/src/pusher-chat.css" rel="stylesheet" type="text/css" />

Now the libraries are included we need to connect to Pusher and create a PusherChatWidget instance, passing in the pusher instance, which will then subscribe to a chat channel based on the URL of the current page and create the chat widget in the UI. This can be done in just a few lines of code. The only change you’ll need to make is to replace the YOUR_APP_KEY with your app_key.

$(function() { var pusher = new Pusher('YOUR_APP_KEY'); var chatWidget = new PusherChatWidget(pusher, { chatEndPoint: 'pusher-realtime-chat-widget/src/php/chat.php' }); });

In the example above you’ll see that we’ve also passed in a second options parameter to the PusherChatWidget constructor. This is so the widget knows where to make the AJAX requests to in order for the server to validate and then trigger chat messages. The value of chatEndPoint should be updated so that the following file is executed (depending on your server technology):

Create and update your config

Within the sample application you’ll find a config_example.file_ext file (the config file location and file_ext on which server technology you’ve chosen to use). Copy this file and create a new files called just config.file_ext. Update this new file with your own Pusher credentials:

// config.php define('APP_KEY', 'YOUR_APP_KEY'); define('APP_SECRET', 'YOUR_APP_SECRET'); define('APP_ID', 'YOUR_APP_ID'); # config.rb require 'pusher' Pusher.app_id = 'YOUR_APP_KEY' Pusher.key = 'YOUR_APP_SECRET' Pusher.secret = 'YOUR_APP_ID'

Ready to go

Now that you’ve added the widget to your page, told it where the server trigger code is and configured the server code with your Pusher App credentials the chat widget should now be up and running on your web app or site.

If you’re experiencing any problems please get in touch.


Where next? A better Realtime Chat Widget

Now you’ve got your Pusher-Powered Realtime Chat widget up and running it’s time to consider how you can make this widget work with your site or application; how can you integrate it with your app and what features can you add to make it much more exciting, usable and valuable? Here are a few ideas:

Personalise by integrating with your existing user accounts

In the example widget we’re using Gravatar to personalise the chat. If a user supplies the optional email address we can use it to look up their Gravatar (Avatar) and display it along with their chosen nickname when they send a chat message. However, many applications already have user accounts so rather than using Gravatar it would be great to use the existing user account information.

For the moment the widget only supports a displayName and and image and you can use your own by passing them into the Activity object constructor:

$options = array( 'displayName' => 'Dave the PHP Guru', 'image' => array( 'url' => 'path_to_avatar_for_dave.png', 'height => '48', 'width => '48' ) ); $activity = new Activity('chat-message', $chat_info['text'], $options); options = { 'displayName' => 'Dave the PHP Guru', 'image' => { 'url' => 'path_to_avatar_for_dave.png', 'height => '48', 'width => '48' } } activity = Activity.new('chat-message', chat_info['text'], options);

Add extra checking to incoming requests

Chat Messages

Whilst the widget does try to strip out any HTML characters it doesn’t try to remove any profanity or anything else that others might find offensive. It might be a good idea to replace sweary words with funny images or reject the messages altogether.

You could also add some funny easter eggs like replacing certain words with images or kicking users out of the chat if they start talking about something you just don’t like - hey it’s your app after all!

Cross-site request forgery (and similar)

You will also want to ensure that the call to your server code has come from your web page or app. For more information simply Google CSRF and see the Wikipedia entry on CSRF.

Only let a logged in user participate in the chat

This is a pretty simple one. You could only display the chat widget if users are logged. Or, you could only let users participate if they are logged in, otherwise they can only view what’s being discussed.

The best way of ensuring that only logged in users can use the chat widget is by using a private channel which requires that the subscription to the channel is authenticated.

Read more about private channels and authenticating users

Make it a site-wide chat widget

The widget currently looks at the URL of the page or web application and creates a channel based on that. You could make widget use just one channel name for the entire site so that all users on the website use the same channel. This can actually be done now by providing a channel name option when creating the PusherChatWidget object:

$(function() { var pusher = new Pusher('YOUR_APP_KEY'); var chatWidget = new PusherChatWidget(pusher, { chatEndPoint: 'pusher-realtime-chat-widget/src/php/chat.php', channelName: 'site-wide-chat-channel' }); });

Read more about Channels

Handle unreliable connections

You can’t guarantee that the user of your web app has the best connection in the world so we’ve provided a way of accessing connection state events. You could update the widget so that it shows the state of the user’s connection. If the users can’t connect and the connection is unavailable then you could stop the user from using the widget and tell them that they appear to be offline at the moment.

Read more about connection states

Show chat participants using Pusher Presence

We provide a way of seeing who’s subscribed to a channel at any time through functionality we call Presence. You could update the chat widget to use a presence channel and then show who was online and participating in the chat at any time. You could also show events within the UI whenever a users joins or leaves the channel.

Read more about Presence

Storing a history of messages

The widget doesn’t save any of the messages to a database so we can’t pre-load any messages when the widget first loads. It also means messages aren’t searchable - which might be a nice feature.

At the moment the widget converts to showing who a users is when they send their first chat message. But if they then navigate to a different page the information about the user will be lost. If the widget were updated to store that information in the user session or a cookie then when the page loads for a user we can update the widget to show the user details, and we won’t need the user to enter them again.

Note: we might update the example to do this since it could get pretty annoying for a user if they have to keep doing that

Questions

If you’ve any questions about the Pusher Realtime Chat Widget examples please get in touch or ask a question by posting an issue/question on the github project.