Photo by Daniele Levis Pelusi on Unsplash

Bot Orchestration Framework Built on Elixir/Phoenix

Marcelo Reichert
Nov 6 · 3 min read

Who's Olivia?

I named the framework Olivia. Olivia was strongly inspired by Justus Eapen’s Virtuoso. Olivia is designed to support a conversation with IBM Watson Assistant or Wit. You can use Facebook Messenger, or a WebApp and connect using webhook or socket.

Create a Project

First, you must create a new project. Let’s call it my_project.

mix phx.new <my_project>
cd <my_project>
{:olivia, git: "https://github.com/marceloreichert/olivia.git"}
{:poison, "~> 3.1 }

Setting Up Your Project

Olivia lets you use 3 different interface types: Facebook Messenger, a WebApp with webhook, and a WebApp with channels.

pipeline :webhook_fb_messenger do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
end
scope "/chat/messenger", OliviaWeb.Chat do
pipe_through :webhook_fb_messenger
get "/", MessengerController, :verify
post "/", MessengerController, :create
end
pipeline :webhook_webapp do
plug :accepts, ["json"]
end

scope "/chat/webapp", OliviaWeb.Chat do
pipe_through :webhook_webapp
post "/", WebAppController, :create
end
scope "/chat/webapp", OliviaWeb.Chat do
pipe_through :webhook_webapp
post "/", WebAppController, :create
end
defmodule <MyProject>.Orchestra do
def run(impression) do
impression
end
end
# config/dev.exs...import_config "dev.secret.exs"
use Mix.Config

config :olivia,
fb_page_recipient_id: "",
fb_page_access_token: "",
wit_server_access_token: "",
watson_assistant_id: "",
watson_assistant_token: "",
watson_assistant_version: "",
default_nlp: :watson_assistant or :wit,
bot_name: <MyProject>

Running

With everything set up, now just get our bot to work.

mix ecto.create
mix phx.server

How it works?

The entry point is the entry.ex files in lib/olivia/chat/interface/ fb_messenger ou web_app. With the input data from the interface we go through processing phases until returning a response to the interface. We have the Translation, Conversation, Thinker andDispatcher modules.

payload
|> Translation.process_messages
|> Conversation.received_message
|> Thinker.run
|> Dispatcher.build_response(sender_id, token)

Translation (Olivia.Chat.Interface.FbMessenger.Translation)

Receives raw message from Messenger or WebApp interface and stores it in a struct %Impression{}.

Conversation (Olivia.Chat.Conversation)

Uses GenServer to maintain conversation state.

Thinker (Olivia.Chat.Thinker)

Responsible for calling Olivia.Chat.Thinker.WatsonAssistant.Thinking, ou Olivia.Chat.Thinker.Wit.Thinking module and according to the interface configuration you are using. Send Watson the incoming message and get back the intention, the entities involved and the response.

Dispatcher (Olivia.Chat.Interface.FbMessenger.Dispatcher)

Handles POST requests that return the response to Facebook Messenger.

Data Driven Investor

from confusion to clarity, not insanity

Marcelo Reichert

Written by

Ruby / Elixir / Node / Powerbuilder http://github.com/marceloreichert

Data Driven Investor

from confusion to clarity, not insanity

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade