<li><aclass="reference internal"href="#install-node-js-and-development-dependencies"id="id14">Install Node.js and development dependencies</a></li>
<li><aclass="reference internal"href="#install-3rd-party-dependencies"id="id15">Install 3rd party dependencies</a></li>
<li><aclass="reference internal"href="#with-amd-and-require-js-recommended"id="id16">With AMD and require.js (recommended)</a></li>
<li><aclass="reference internal"href="#without-amd-and-require-js"id="id17">Without AMD and require.js</a></li>
<li><aclass="reference internal"href="#before-submitting-a-pull-request"id="id18">Before submitting a pull request</a><ul>
<li><aclass="reference internal"href="#add-tests-for-your-bugfix-or-feature"id="id19">Add tests for your bugfix or feature</a></li>
<li><aclass="reference internal"href="#check-that-the-tests-pass"id="id20">Check that the tests pass</a></li>
<li><aclass="reference internal"href="#check-your-code-for-errors-or-bad-habits-by-running-jshint"id="id21">Check your code for errors or bad habits by running JSHint</a></li>
<h1><aclass="toc-backref"href="#id3">Quickstart (to get a demo up and running)</a><aclass="headerlink"href="#quickstart-to-get-a-demo-up-and-running"title="Permalink to this headline">¶</a></h1>
<p>You might also want to have more fine-grained control of what gets included in
the minified Javascript file. Read <aclass="reference internal"href="#configuration">Configuration</a> and <aclass="reference internal"href="#minification">Minification</a> for more info on how to do
<aclass="reference internal"href="#session-support">Session Support</a> (i.e. single-signon functionality whereby users are authenticated once and stay
<h2><aclass="toc-backref"href="#id6">An XMPP/Jabber server</a><aclass="headerlink"href="#an-xmpp-jabber-server"title="Permalink to this headline">¶</a></h2>
<p><em>Converse.js</em> implements <aclass="reference external"href="https://en.wikipedia.org/wiki/Xmpp">XMPP</a> as its messaging protocol, and therefore needs
to connect to an XMPP/Jabber server (Jabber is really just a synonym for XMPP).</p>
<p>Your website and <em>Converse.js</em> use <aclass="reference external"href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP</a> as protocol to communicate with
the webserver. HTTP connections are stateless and usually shortlived.</p>
<p><aclass="reference external"href="https://en.wikipedia.org/wiki/Xmpp">XMPP</a> on the other hand, is the protocol that enables instant messaging, and
its connections are stateful and usually longer.</p>
<p>To enable a web application like <em>Converse.js</em> to communicate with an XMPP
server, we need a proxy in the middle that can act as a bridge between the two
protocols.</p>
<p>This is the job of a connection manager. A connection manager can be either a
standalone application or part of an XMPP server. <aclass="reference external"href="http://www.ejabberd.im">ejabberd</a> for example,
includes a connection manager (but you have to enable it).</p>
<p>The demo on the <aclass="reference external"href="http://conversejs.org">Converse.js homepage</a> uses a a connection manager located at <aclass="reference external"href="https://bind.opkode.im">https://bind.opkode.im</a>.
This connection manager is for testing purposes only, please don’t use it in
<h3><aclass="toc-backref"href="#id8">Overcoming cross-domain request restrictions</a><aclass="headerlink"href="#overcoming-cross-domain-request-restrictions"title="Permalink to this headline">¶</a></h3>
<p>The domain of the <em>Converse.js</em> demo is <em>conversejs.org</em>, but the domain of the connection manager is <em>opkode.im</em>.
HTTP requests are made by <em>Converse.js</em> to the connection manager via XmlHttpRequests (XHR).
Until recently, it was not possible to make such requests to a different domain
than the one currently being served (to prevent XSS attacks).</p>
<p>Luckily there is now a standard called <aclass="reference external"href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a> (Cross-origin resource sharing), which enables exactly that.
Modern browsers support CORS, but there are problems with Internet Explorer <
10.</p>
<p>IE 8 and 9 partially support CORS via a proprietary implementation called
XDomainRequest. There is a <aclass="reference external"href="https://gist.github.com/1095825/6b4517276f26b66b01fa97b0a78c01275fdc6ff2">Strophe.js plugin</a> which you can use to enable
support for XDomainRequest when it is present.</p>
<p>In IE < 8, there is no support for CORS.</p>
<h4>For example:<aclass="headerlink"href="#for-example"title="Permalink to this headline">¶</a></h4>
<p>Assuming your site is accessible on port <ttclass="docutils literal"><spanclass="pre">80</span></tt> for the domain <ttclass="docutils literal"><spanclass="pre">mysite.com</span></tt>
and your connection manager manager is running at <ttclass="docutils literal"><spanclass="pre">someothersite.com/http-bind</span></tt>.</p>
<p>The <em>bosh_service_url</em> value you want to give Converse.js to overcome
the cross-domain restriction is <ttclass="docutils literal"><spanclass="pre">mysite.com/http-bind</span></tt> and not
<p>Your <ttclass="docutils literal"><spanclass="pre">nginx</span></tt> or <ttclass="docutils literal"><spanclass="pre">apache</span></tt> configuration will look as follows:</p>
</div>
<divclass="section"id="nginx">
<h4>Nginx<aclass="headerlink"href="#nginx"title="Permalink to this headline">¶</a></h4>
<divclass="highlight-python"><pre>http {
server {
listen 80
server_name mysite.com;
location ~ ^/http-bind/ {
proxy_pass http://someothersite.com;
}
}
}</pre>
</div>
</div>
<divclass="section"id="apache">
<h4>Apache<aclass="headerlink"href="#apache"title="Permalink to this headline">¶</a></h4>
<h2><aclass="toc-backref"href="#id9">Server-side authentication</a><aclass="headerlink"href="#server-side-authentication"title="Permalink to this headline">¶</a></h2>
<spanid="session-support"></span><h3><aclass="toc-backref"href="#id10">Prebinding and Single Session Support</a><aclass="headerlink"href="#prebinding-and-single-session-support"title="Permalink to this headline">¶</a></h3>
<p>To do this you will require a <aclass="reference external"href="http://xmpp.org/about-xmpp/technology-overview/bosh/">BOSH server</a>
for converse.js to connect to (see the <aclass="reference internal"href="#bosh-service-url">bosh_service_url</a> under <aclass="reference internal"href="#configuration-variables">Configuration variables</a>)
<p>Jack Moffitt has a great <aclass="reference external"href="http://metajack.im/2008/10/03/getting-attached-to-strophe">blogpost</a> about this and even provides an <aclass="reference external"href="https://github.com/metajack/strophejs/tree/master/examples/attach">example Django application</a> to demonstrate it.</p>
<p>When you authenticate to the XMPP server on your backend application (for
<h3><aclass="toc-backref"href="#id11">Setting up a BOSH server</a><aclass="headerlink"href="#setting-up-a-bosh-server"title="Permalink to this headline">¶</a></h3>
<h2><aclass="toc-backref"href="#id12">Facebook integration</a><aclass="headerlink"href="#facebook-integration"title="Permalink to this headline">¶</a></h2>
<pclass="last">It should be possible to integrate Converse.js with Facebook chat, and
below I’ll provide some tips and documentation on how to achieve this. That
said, I don’t have a Facebook account and therefore haven’t tried to do
this myself. Feedback and patches from people who have succesfully done this
will be appreciated.</p>
</div>
<p>Converse.js uses <aclass="reference external"href="http://strophe.im/strophejs">Strophe.js</a> to connect and
communicate with the XMPP server. One nice thing about Strophe.js is that it
can be extended via <aclass="reference external"href="http://github.com/strophe/strophejs-plugins">plugins</a>.</p>
<p>Here is a <aclass="reference external"href="https://github.com/kissrobber/turedsocial/blob/master/strophe-plugins/src/facebook.js">plugin for authenticating with facebook</a>.</p>
<p>You will need your own BOSH connection manager to act as a proxy between
Converse.js/Strophe.js and Facebook’s XMPP server. That is because Facebook’s
XMPP server doesn’t support BOSH natively.</p>
<p>The BOSH connection manager that I make available for
<h2><aclass="toc-backref"href="#id14">Install Node.js and development dependencies</a><aclass="headerlink"href="#install-node-js-and-development-dependencies"title="Permalink to this headline">¶</a></h2>
<p>We use development tools (<aclass="reference external"href="http://gruntjs.com">Grunt</a> and <aclass="reference external"href="http://bower.io">Bower</a>)
which depend on Node.js and npm (the Node package manager).</p>
<p>If you don’t have Node.js installed, you can download and install the latest
version <aclass="reference external"href="https://nodejs.org/download">here</a>.</p>
<h2><aclass="toc-backref"href="#id15">Install 3rd party dependencies</a><aclass="headerlink"href="#install-3rd-party-dependencies"title="Permalink to this headline">¶</a></h2>
<p>After running <ttclass="docutils literal"><spanclass="pre">npm</span><spanclass="pre">install</span></tt>, you will now have Grunt and Bower installed.</p>
<p>We use Bower to manage Converse’s front-end dependencies (e.g. Javascript that
<h2><aclass="toc-backref"href="#id16">With AMD and require.js (recommended)</a><aclass="headerlink"href="#with-amd-and-require-js-recommended"title="Permalink to this headline">¶</a></h2>
<h2><aclass="toc-backref"href="#id17">Without AMD and require.js</a><aclass="headerlink"href="#without-amd-and-require-js"title="Permalink to this headline">¶</a></h2>
<h2><aclass="toc-backref"href="#id18">Before submitting a pull request</a><aclass="headerlink"href="#before-submitting-a-pull-request"title="Permalink to this headline">¶</a></h2>
<h3><aclass="toc-backref"href="#id19">Add tests for your bugfix or feature</a><aclass="headerlink"href="#add-tests-for-your-bugfix-or-feature"title="Permalink to this headline">¶</a></h3>
<p>Add a test for any bug fixed or feature added. We use Jasmine
for testing.</p>
<p>Take a look at <ttclass="docutils literal"><spanclass="pre">tests.html</span></tt> and <ttclass="docutils literal"><spanclass="pre">spec/MainSpec.js</span></tt> to see how
<h3><aclass="toc-backref"href="#id20">Check that the tests pass</a><aclass="headerlink"href="#check-that-the-tests-pass"title="Permalink to this headline">¶</a></h3>
<h3><aclass="toc-backref"href="#id21">Check your code for errors or bad habits by running JSHint</a><aclass="headerlink"href="#check-your-code-for-errors-or-bad-habits-by-running-jshint"title="Permalink to this headline">¶</a></h3>
<h2><aclass="toc-backref"href="#id23">Conflicts with other Javascript libraries</a><aclass="headerlink"href="#conflicts-with-other-javascript-libraries"title="Permalink to this headline">¶</a></h2>
<divclass="section"id="problem">
<h3><aclass="toc-backref"href="#id24">Problem:</a><aclass="headerlink"href="#problem"title="Permalink to this headline">¶</a></h3>
<p>You are using other Javascript libraries (like JQuery plugins), and
get errors like these in your browser console:</p>
<divclass="highlight-python"><pre>Uncaught TypeError: Object [object Object] has no method 'xxx' from example.js</pre>
</div>
</div>
<divclass="section"id="solution">
<h3><aclass="toc-backref"href="#id25">Solution:</a><aclass="headerlink"href="#solution"title="Permalink to this headline">¶</a></h3>
<p>First, find out which object is referred to by <ttclass="docutils literal"><spanclass="pre">Object</span><spanclass="pre">[object</span><spanclass="pre">Object]</span></tt>.</p>
<p>It will probably be the jQuery object <ttclass="docutils literal"><spanclass="pre">$</span></tt> or perhaps the underscore.js object <ttclass="docutils literal"><spanclass="pre">_</span></tt>.</p>
<p>For the purpose of demonstration, I’m going to assume its <ttclass="docutils literal"><spanclass="pre">$</span></tt>, but the same
rules apply if its something else.</p>
<p>The bundled and minified default build of converse.js, <ttclass="docutils literal"><spanclass="pre">converse.min.js</span></tt>
includes within it all of converse.js’s dependencies, which include for example <em>jQuery</em>.</p>
<p>If you are having conflicts where attributes or methods aren’t available
on the jQuery object, you are probably loading <ttclass="docutils literal"><spanclass="pre">converse.min.js</span></tt> (which
includes jQuery) as well as your own jQuery version separately.</p>
<p>What then happens is that there are two <ttclass="docutils literal"><spanclass="pre">$</span></tt> objects (one from
converse.js and one from the jQuery version you included manually)
and only one of them has been extended to have the methods or attributes you require.</p>
<p>Which jQuery object you get depends on the order in which you load the libraries.</p>
<p>There are multiple ways to solve this issue.</p>
<p>Firstly, make sure whether you really need to include a separate version of
jQuery. Chances are that you don’t. If you can remove the separate
version, your problem should be solved, as long as your libraries are loaded in
the right order.</p>
<p>Either case, whether you need to keep two versions or not, the solution depends
on whether you’ll use require.js to manage your libraries or whether you’ll
load them manually.</p>
<divclass="section"id="with-require-js">
<h4>With require.js<aclass="headerlink"href="#with-require-js"title="Permalink to this headline">¶</a></h4>
<p>Instead of using <ttclass="docutils literal"><spanclass="pre">converse.min.js</span></tt>, manage all the libraries in your project
(i.e. converse.js and its dependencies plus all other libraries you use) as one
require.js project, making sure everything is loaded in the correct order.</p>
<p>Then, before deployment, you make your own custom minified build that bundles everything
you need.</p>
</div>
<divclass="section"id="with-script-tags">
<h4>With <script> tags<aclass="headerlink"href="#with-script-tags"title="Permalink to this headline">¶</a></h4>
<p>Take a look at <aclass="reference external"href="https://github.com/jcbrand/converse.js/blob/master/non_amd.html">non_amd.html</a>
in the converse.js repo.</p>
<p>It shows in which order the libraries must be loaded via <ttclass="docutils literal"><spanclass="pre"><script></span></tt> tags. Add
your own libraries, making sure that they are loaded in the correct order (e.g.
<h2><aclass="toc-backref"href="#id27">Configuration variables</a><aclass="headerlink"href="#configuration-variables"title="Permalink to this headline">¶</a></h2>
<h3><aclass="toc-backref"href="#id28">allow_contact_requests</a><aclass="headerlink"href="#allow-contact-requests"title="Permalink to this headline">¶</a></h3>
<p>Hide the <ttclass="docutils literal"><spanclass="pre">server</span></tt> input field of the form inside the <ttclass="docutils literal"><spanclass="pre">Room</span></tt> panel of the
controlbox. Useful if you want to restrict users to a specific XMPP server of
<p>For prebinding to work, your backend server must authenticate for you, and
then return a JID (jabber ID), SID (session ID) and RID (Request ID).</p>
<p>If you set <ttclass="docutils literal"><spanclass="pre">prebind</span></tt> to <ttclass="docutils literal"><spanclass="pre">true</span></tt>, you have to make sure to also pass in these
values as <ttclass="docutils literal"><spanclass="pre">jid</span></tt>, <ttclass="docutils literal"><spanclass="pre">sid</span></tt>, <ttclass="docutils literal"><spanclass="pre">rid</span></tt>.</p>
<p>Additionally, you have to specify <ttclass="docutils literal"><spanclass="pre">bosh_service_url</span></tt>.</p>
<h3><aclass="toc-backref"href="#id39">show_controlbox_by_default</a><aclass="headerlink"href="#show-controlbox-by-default"title="Permalink to this headline">¶</a></h3>
<h3><aclass="toc-backref"href="#id40">show_only_online_users</a><aclass="headerlink"href="#show-only-online-users"title="Permalink to this headline">¶</a></h3>
<h3><aclass="toc-backref"href="#id42">xhr_custom_status_url</a><aclass="headerlink"href="#xhr-custom-status-url"title="Permalink to this headline">¶</a></h3>
<li>The user inputs some text (for example part of a firstname or lastname), an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned. The user can then choose one of the matches to add as a contact.</li>
<p>This setting enables the second mechanism, otherwise by default the first will be used.</p>
<p><em>What is expected from the remote server?</em></p>
<p>A default JSON encoded list of objects must be returned. Each object
corresponds to a matched user and needs the keys <ttclass="docutils literal"><spanclass="pre">id</span></tt> and <ttclass="docutils literal"><spanclass="pre">fullname</span></tt>.</p>
<h3><aclass="toc-backref"href="#id44">xhr_user_search_url</a><aclass="headerlink"href="#xhr-user-search-url"title="Permalink to this headline">¶</a></h3>
<h2><aclass="toc-backref"href="#id46">Minifying Javascript and CSS</a><aclass="headerlink"href="#minifying-javascript-and-css"title="Permalink to this headline">¶</a></h2>
<p>Please make sure to read the section <aclass="reference internal"href="#development">Development</a> and that you have installed
all development dependencies (long story short, you can run <ttclass="docutils literal"><spanclass="pre">npm</span><spanclass="pre">install</span></tt>
and then <ttclass="docutils literal"><spanclass="pre">grunt</span><spanclass="pre">fetch</span></tt>).</p>
containing all translations and from which for each language an individual PO
file is generated.</p>
<p>The POT file contains all translateable strings extracted from converse.js.</p>
<p>To make a user facing string translateable, wrap it in the double underscore helper
function like so:</p>
<divclass="highlight-python"><divclass="highlight"><pre><spanclass="n">__</span><spanclass="p">(</span><spanclass="s">'This string will be translated at runtime'</span><spanclass="p">);</span>
</pre></div>
</div>
<p>After adding the string, you’ll need to regenerate the POT file, like so:</p>
<divclass="highlight-python"><pre>make pot</pre>
</div>
<p>You can then create or update the PO file for a specific language by doing the following:</p>
<p>Unfortunately <aclass="reference external"href="http://slexaxton.github.io/Jed">Jed</a> cannot use the PO files directly. We have to generate from it