Setting up simple Live Chat in a Phoenix project using Planga

Planga is a new web-service that is currently in open Beta, that allows you to seamlessly integrate live chat functionality in your existing web-app.

We are super excited to let you try out Planga.io! This guide is intended to show you how easy it is to get started using Planga in a Phoenix/Elixir-project.

Planga.io — Seamless Live Chat for Applications and Platforms

Planga makes it very easy to set up live chat using the existing users in your system! Although we are still in open beta, it is already very easy to use Planga’s functionality.

In this example tutorial, we’ll be using Coherence as user-identification and authentication solution. Of course, you could just as easily use one of the other existing packages on Hex.PM or roll your own.

To make it very easy to get started, this tutorial builds on top of the Coherence Demo Project which you can find here.

Setting up the basic Coherence Demo project

The following is taken directly from the Coherence Demo Project Readme:

git clone https://github.com/smpallen99/coherence_demo.git planga_demo
cd planga_demo
mix do deps.get, deps.compile
mix ecto.setup
cd assets && npm install && cd ..
iex -S mix phx.server

After running this, you’ll now have the demo project chugging along nicely. However, to make it easier to test things out with multiple demo users (which is nice when you want to see if multiple users are able to chat with each-other), open up priv/repo/seeds.exs and add a couple of more users to it; for instance like these:

CoherenceDemo.Repo.delete_all CoherenceDemo.Coherence.User
CoherenceDemo.Coherence.User.changeset(%CoherenceDemo.Coherence.User{}, %{name: "Demo User", email: "demouser@example.com", password: "secret", password_confirmation: "secret"})
CoherenceDemo.Coherence.User.changeset(%CoherenceDemo.Coherence.User{}, %{name: "Clark Kent", email: "clark@example.com", password: "secret", password_confirmation: "secret"})
CoherenceDemo.Coherence.User.changeset(%CoherenceDemo.Coherence.User{}, %{name: "Bruce Wayne", email: "bruce@example.com", password: "secret", password_confirmation: "secret"}) |> CoherenceDemo.Repo.insert!
|> Coherence.Controller.confirm!

And then re-create the users in the database by running mix run priv/repo/seeds.exs .

All right! We’re all ready now to add Planga to the application!

Adding PlangaPhoenix and an API Key pair

First, we’ll add the Planga integration library called planga_phoenix to our mix.exs . Please make sure you use the newest version, since updates are released regularly ❤️.

After running mix deps.get and restarting the application again, we can start writing adding chat channels!

There’s only one extra piece you need: Your own API key pair. Head over to https://planga.io to make a free account and get a key pair!

First, I’ll show you the absolute least-effort way to add chat to your application. Afterward, we’ll then slightly improve this code to make it a bit more general and reusable.

Setting up a basic General chat channel

Let’s now go ahead and create a very simple chat channel that all users are able to use, which is visible on the homepage of the application.

For this, open up lib/coherence_demo_web/templates/page/index.html.eex , and add the following code below the Jumbotron: (with your API key pair filled in in the appropriate placeholder locations)

<% if Coherence.current_user(@conn) do %>
<h1>General Chat Channel:</h1>
<%= PlangaPhoenix.chat(
%{
public_api_id: "[YOUR PUBLIC API ID]",
private_api_key: "[YOUR PRIVATE API KEY]",
conversation_id: "general",
current_user: %{
id: Coherence.current_user(@conn).id,
name: Coherence.current_user(@conn).name
}
})
%>
<% end %>

There you go! Now, when visiting the homepage while you are logged in, you are able to chat with the other users in the system!

🍰 Yes, it was that simple!

Refactoring our code

Above example was very easy to copy-and-paste, but having this much configuration logic in our templates is of course not very nice. So let’s change this!

Add a new file called /lib/coherence_demo_web/chat.ex and fill in the following:

defmodule CoherenceDemoWeb.Chat do
def default_options() do
Application.fetch_env!(:coherence_demo, :planga_phoenix)
|> Map.new
end
  def planga_chat(conn, options) do
current_user_options = %{
current_user: %{
id: Coherence.current_user(conn).id,
name: Coherence.current_user(conn).name
}
}
    options =
default_options()
|> Map.merge(current_user_options)
|> Map.merge(Map.new(options))
    PlangaPhoenix.chat(options)
end
end

Then, in your config file (such as config/config.exs, although you might of course decide to e.g. use different API keys for the development versions and the production versions of your application), add:

config :coherence_demo, :planga_phoenix,
public_api_id: "[YOUR PUBLIC API ID]",
private_api_key: "[YOUR PRIVATE API KEY]",

Finally, open lib/coherence_demo_web/coherence_demo_web.ex and alter the def view do to import the new module into the view context:

def view do
quote do
# ... Existing `import` and `use` lines
      import CoherenceDemoWeb.Chat
end
end

Now, you can replace the contents of the snippet in your lib/coherence_demo_web/page/index.html.eex with this much cleaner code, which will do exactly the same:

<%= if Coherence.current_user(@conn) do %>
<h1>General Chat Channel:</h1>
<%= planga_chat(@conn, conversation_id: "general") %>
<% end %>

😎

It also sets us up for the next step: Adding private chatting functionality to our application.


Private Chat

Private chatting between two users is a very common feature that many applications would like to use. In the near future, we will an improve API for creating private channels, which will make it even simpler for you to use, but even now it does not take a lot of effort to create private channels:

Add the following function to lib/coherence_demo_web/chat.ex :

  def planga_private_chat(conn, other_user, options \\ %{}) do
IO.inspect(other_user)
private_conversation_id =
[other_user.id, Coherence.current_user(conn).id]
|> Enum.sort
|> Enum.join("/")
    options =
Map.new(conversation_id: private_conversation_id)
|> Map.merge(options)
|> IO.inspect
    planga_chat(conn, options)
end

As you can see, we create a channel_id here that will match the pair of users that are supposed to speak to one-another. Because we sort the two IDs, regardless of whom initiates contact first, the resulting channel_id will be the same.

If you’re interested in security, here’s a side note: The user IDs (and channel IDs) you specify and send to Planga are never visible to end users, because they are encrypted before going over the wire. Also, Planga does not at all care if you are using numeric IDs, UUIDs, or some other identifier-scheme (as long as it uniquely identifies the user or the channel in your application).

Now, let’s add the following single line of code to lib/coherence_demo_web/templates/user/show.html.eex :

<%= planga_private_chat(@conn, %{id: @user.id, name: @user.name}) %>

And there we are! (side note: because we can only see this profile page when we are logged in, we don’t have to put an extra if around it)

Now, when a user visits another user’s profile, they are able to see the messages they’ve exchanged with this other user, and send new messages!


So there we are! You now know how to add Planga to an Elixir/Phoenix application.

🎈

We are eagerly developing more features as well as improving our documentation, and would love to hear from you! Please reach out to us on https://planga.io/contact and tell us what you think.

🕶