This page explains how Planga works, and how you can use it.

Planga is designed with the following three features in mind:

  • Simplicity
  • Scalability
  • Security
All choices made to the design of how Planga functions and how you can interact with it, are based on those three principles.
Planga is currently in open beta. This means that while we are very eager to let you try out this software, it is not yet fully finished!
Besides adding more functionality, improving the documentation is one of our top priorities.
If you see something that feels confusing, weird or missing: please open an issue and tell us about it!

Language Integrations:

Getting started with Planga is very simple:

For many common languages and programming environments, we have libraries that do nearly all of the work for you:

Language Package Version Source Repository
Elixir planga_phoenix Hex.PM ResiliaDev/planga-phoenix
Ruby planga-ruby Rubygems ResiliaDev/planga-ruby
Python planga PyPi ResiliaDev/planga-python
Furthermore, the following integrations are being worked on, and will be released soon:
  • Node.js
  • PHP
  • Haskell
  • C#
  • Rust

If your language is not (yet!) in this list, do not fret: it still is quite simple to configure and use Planga. And if you do, please release your code as open source library. We'd love to hear about it and contribute!

General Idea

Your application already has users that visit the various pages of your application. Planga piggy-backs on that. Of course, to keep your system as scalable as possible, chatting does not go through your server. Instead, the only thing your application provides (as can be seen in the picture ), is a bit of configuration that the browser of a visitor will use to initiate contact with Planga.

To ensure that this configuration is not altered by a visitor, it is created in an encrypted way by your service.

How this encryption works exactly is not important to use Planga: properly encrypting your configuration and building an HTML/JS snippet from it is what the language integration libraries do for you.

So the only thing you then need to figure out, is what configuration information you need to fill in.


The details to be sent in the configuration are exactly the details that are required to set up a chat channel between two (or more) users.

Naming is here in snake case; the exact naming depends on the language integration you are using, as it follows that language's conventions.

There are three required pieces of information:
  • channel_id The ID of the channel the user will see in this chat window. This ID can be anything, but should be unique in your application (when you re-use this ID at another time, then that browser window will connect to the same channel! This is exactly how multiple users connect to the same chat channel.)
  • current_user_id The ID of the current user. This ID can be anything, but should be unique in your application (when you re-use this ID, then that browser window will connect as that given user to Planga. This is exactly how the same user is able to use Planga again and again.)
  • current_user_name The name of the current user. This is a string that can be anything, but since it is (only) used visually to allow users to identify one-another, it should be sensibly set to e.g. the username or email-address of the user in your application. Changing this value in subsequent requests is allowed; a new value will override the previously stored value and in this way the username of a certain user inside Planga is updated.

Optionally, you can also specify an array of `other_users` (every element of this array should have an `id` and a `name`; check the specific language library for exact syntax). These are users that should also be added to the given chat, as soon as the first message is created. This is used for channels like private messaging channels, which would otherwise make it very hard to find back a conversation (you only want to open private conversations between users that actually say something to each-other, rather than potentially between all users).

Besides this, two extra pieces of information are necessary to be sent, but these will usually stay the same across all requests:
  • public_id This is the public ID that Planga will use to find the private key to decrypt the encrypted configuration, as well as letting Planga know what app this chat belongs to. This is the one thing that is (on purpose!) sent in plain text.
  • private_key This is the private key that the language integration will use to encrypt the settings above with. This should be kept very secret! Only you(r app) and Planga should know this key.

Constructing the Chat window

Once you've filled in the proper configuration, the library gives you back a snippet of HTML (which contains some embedded JS). You should put this in your HTML page response that you send to the visitor's browser, in the appropriate location where you want the chat window to be rendered.

The HTML snippet will automatically include the Planga JS frontend code, and invoke it with the encrypted configuration, to set up a connection to Planga at page load. If successful, it will, inside the block element in the HTML snippet, render and maintain the resulting chat window.


You can find example styles in the Planga Styles repository.

Take these as a starting point, and customize them to fit in with your application!

It is possible to completely style the chat window to your liking: feel free to show/hide it whenever you want, etc.

All different visual elements have been given their own CSS classes, which are prefixed with `.planga--`, so you can easily create some special style rules that work on them, and completely configure it to make the chat screen fit in with your application.

Since the resulting chat window is properly part of your app's page, and not rendered in an iframe or similar, you can completely go bonkers with this!

In-depth information about how Planga works

Over here, we explain more about the internals of Planga. This is mostly important for you if you want to write your own language integration.

Communication between the browser and the Planga Chat Server

After your app has returned a HTML page that includes an HTML snippet to create a chat, the visitor's browser will attempt to connect to (one of the) the Planga Chat Server(s). For this connection, we use WebSockets, if available, falling back on LongPolling if not (which uses slightly more bandwidth and is slower, but is supported in all archaically old browsers).

Every time the connected visitor sends a message, this is broadcasted by the Planga Chat Server to all other users connected to this chat screen, while simultaneously being saved persistently so that when someone looks at the chat later, the messages are still there.

Because this happens side-by-side, Planga is able to send and handle messages very quickly. All users are connected using a persistent WebSocket (or LongPolling) connection, to their dedicated 'green thread' (to be exact: Elixir/Erlang Processes) inside the Planga Chat Server. The overhead for these green threads is very low, but it is what enables us to push and broadcast messages quickly.

The Configuration Encryption

This is usually done by the library that you are using. You only need to understand this if you are building another language integration for a new language.

The encryption/decryption is done using two pieces of information: the private key, which is secret and only Planga and your app know what it is, and the public id, which is public and is used so that Planga can efficiently find a given private key.

Encryption of the configuration information is then done using the JOSE.JWK specification, using the AES-128-GCM-KW algorithm.