Candy
— a JavaScript-based multi-user chat clientCandy is different. It's built for your community.
Why Candy?
- Focused on real-time multi-user chatting → Screenshot & Demo
- Easy to configure, easy to run, easy to use → Setup & Usage
- Highly customizable → Plugins & Event Hooks
- 100% well-documented JavaScript source code → API Documentation
- Built for XMPP (Jabber), using famous technologies → Under The Hood
- Used and approved in a productive environment with up to 400 concurrent users → About Candy
- Works with all major web browsers including IE7, and mobile browsers thanks for the Bootstrap front-end framework.
It's worth more than a thousand pictures.
Awesome Features!
- Beautiful default theme
- Join multiple rooms and start private conversations
- Get notified when new messages arrive
- Ignore spammers and people you don't like
- Moderation: Kick and ban users, change the subject of the room
Setup & Usage
Prerequisites
Install and configure a XMPP server with HTTP binding enabled. Read our setup guides.
Due to the nature of AJAX you need to proxy the HTTP requests to the XMPP service which usually runs on a different port. The source code contains a sample .htaccess
file to be used with Apache. We cover the configuration for the most used web servers here.
Setup
Download Candy and extract it in your web directory.
Getting Started
Copy example/htaccess
to example/.htaccess
and change the rewrite rule to point to your HTTP bind service. If you're running your XMPP host with HTTP bind service at yourhost.com/http-bind/
on port 5280, the .htaccess
file should look like this:
AddDefaultCharset UTF-8
Options +MultiViews
RewriteEngine On
RewriteRule http-bind/ http://yourhost.com:5280/http-bind/ [P]
If you are using nginx - copy this config:
location / {
root /var/www/xmpp/candy/;
index index.html;
location /http-bind/ {
# you need to change it to your http-bind port
proxy_pass https://127.0.0.1:5280/http-bind/;
proxy_buffering off;
tcp_nodelay on;
}
# you can use this workaround to allow nginx to send POST data to proxy_pass
error_page 405 =200 $uri;
}
Open your web browser and navigate to example/index.html
. Make sure that you're visiting the site via Apache because it's essential that the requests to http-bind/ are redirected to your XMPP server by the .htaccess file.
You should be greeted with a login form. Enter your JID (username@yourhost.com) and password to connect to the XMPP server.
Configuration
Configuring Candy is pretty simple. Take a look at the example/index.html file to get an idea how to load the libraries and to initialize Candy.
You can configure Candy by passing an object containing following options to Candy.init
:
Candy.init(SERVICE, { core: { CORE_OPTIONS }, view: { VIEW_OPTIONS } });
Service
'http-bind/'
- BOSH URL of your server/proxy
'ws://example.com:5280/http-bind'
- Websocket URL of your server (preferably wss:// to prevent MITM)
Core Options
debug — true or false
- Enable debug output to browser console.
autojoin — boolean true or an array containing rooms to auto-join: [room1,room2,...]
-
If set to true, Candy will follow XEP-0048 and auto-join rooms based on the bookmarks configuration of your XMPP server.
Please note: Bookmarks are supported by ejabberd and Openfire, amongst others.
For servers which don't support XEP-0048 1.0, you can explicitly list which rooms to join by passing an array such as ['jid1', 'jid2', ...] resource — string
- Set a custom resource. If not set, default is Candy.
View Options
language — language identifier, default: 'en'
-
Tell Candy which language pack to use. Following languages are currently delivered with the package:
- English (en)
- Catalan (ca)
- Chinese (cn)
- Czech (cs)
- Dutch (nl)
- French (fr)
- German (de)
- Hebrew (he)
- Italian (it)
- Japanese (ja)
- Polish (pl)
- Portuguese (pt)
- Brazilian portuguese (pt_br)
- Russian (ru)
- Spanish (es)
- Swedish (sv)
Please contribute your translations to the project.
assets — path to assets folder, default: 'res/'
- Path to the assets folder with trailing slash.
crop — settings to crop messages & nicknames: { message: { nickname: 15, body: 1000 }, roster: { nickname: 15 } }
- Messages and nicknames will be cropped to the specified lengths.
messages — object containing settings to clean up old messages: {limit: 2000, remove: 500}
-
If message count hits limit, remove n messages.
Because browsers are getting slower as the DOM tree grows, Candy will remove messages from each room based on this settings to keep the DOM tree at an acceptable size. You probably don't want to change the default values. enableXHTML — enable parsing XHTML annotated XMPP messages
- Using XHTML clients can format their messages in various ways. Using this flag, all your Candy users will also see nicely formatted messages.
Example
Following example configuration will enable debugging, auto-join two rooms, and display the front end in german language:
Candy.init( 'http://yourhost.com/http-bind/', {
core: {
debug: true,
autojoin: ['room1@conference.yourhost.com', 'room2@conference.yourhost.com']
}, view: {
language: 'de'
}
});
Login Methods
There are six different methods to connect to a chat server:
-
Candy.Core.connect('jid', 'password')
- Connnect as a registered user.
-
Candy.Core.connect('servername')
- Connnect anonymously to a specific server. Users will be greeted with a nickname form.
-
Candy.Core.connect('servername', null, 'nickname')
-
Connect anonymously to a specific server, but don't greet the users with a login form. Instead the specified nickname will be used.
The second param (password) has to be null, because anonymous logins don't have a password (of course). -
Candy.Core.connect('jid')
- Users will be greeted with a login form. In order to authenticate they have to provide their password.
-
Candy.Core.connect()
- Users will be greeted with a login form. In order to authenticate they have to provide their JID (username@yourhost.com) and password.
-
Candy.Core.attach(jid, sid, rid)
- Attach to an established session (HTTP pre-binding). This method is useful to intialize sessions at server side. Jack Moffitt, creator of Strophe, has written a nice article about pre-binding.
Usage
The user interface of Candy is very intuitive. Just take a look at the screenshot. No things to learn. No manual to read.
You might want to try the demo and get the real feeling instead.
Administrative Options
Room moderators are able to kick or ban users and change the room's subject.
Getting Help
- Check out the official wiki pages and issue tracker on GitHub.
- There's also a mailing list on Google Groups.
- Use it, love it, spread it: Tell the world about Candy.
- Improve it: Feel free to fork and push your changes back into the main repository.
- Extend it: Write plugins to make Candy more awesome.
- Give us feedback: Tell us what you like about Candy and what you don't by dropping an email.
Contributing
Plugins & Event Hooks
Due to the nature of JavaScript and the built-in event hooks, customizing Candy is no rocket science.
Plugins
There's an official plugin repository called candy-plugins. We would like to see the number of plugins grow. Just fork it, write your own plugin and push it back into the main respository.
Download Candy Plugins and extract it in your web directory.
The Colors Plugin — An Example
This plugin has originally been developed for our productive chat and because our users love it, we decided to share it with you. It's also a great example how to customize Candy.
What it does is adding a color chooser to the UI and displaying messages sent by users in their chosen colors.
To enable Colors you have to include its JavaScript code and stylesheet:
<script type="text/javascript" src="candyshop/colors/candy.js"></script>
<link rel="stylesheet" type="text/css" href="candyshop/colors/candy.css" />
Finally call its init()
method after Candy has been initialized:
Candy.init('/http-bind/');
CandyShop.Colors.init();
Candy.Core.connect();
Styles & Templates
We use to write our themes as plugins. The plugin folder is a good place to put your custom stylesheet into. During the process of styling you'll probably find yourself changing a template here and adding some logic there. If this happens you're already organized. Just think about it as writing a plugin that changes the appearance.
Event Hooks
Candy provides hooks that will be called during specific events which makes it easy for you to tweak and extend basic functionalities, such as displaying messages:
// candy:view.message.before-show is triggered before a chat message is displayed
$(Candy).on('candy:view.message.before-show', function(evt, args) {
args.message = args.message.replace(/jappix/gi, '*censored*'); // censor 'jappix' in chat messages
});
API Documentation
The API documentation of the latest version can be found here.
Under The Hood
Candy is built with JavaScript using long poll AJAX requests to emulate bidirectional-streams between client and server following the draft standard XEP-0124 of the XMPP Standards Foundation. By using this standard there are no additional requirements on client-side but having a web browser installed.
3rd Party Libraries
- Strophe.js an XMPP library for JavaScript
- jQuery The Write Less, Do More, JavaScript Library
- mustache.js Logic-less templates with JavaScript
- Bootstrap front-end framework, for responsiveness to various screen sizes
Credits
- Swissjabber provides the chat server for our official demo. Swissjabber is a service by nine.ch
About Candy
Candy — abbreviation for Chats are not dead yet — was developed by Michael Weibel (@weibelm) and Patrick Stadler (@pstadler).