Build a Chatbot with Phoenix and Api.ai - Part 1

If you are reading this, you have likely seen my website (or maybe not). But, on the front page of the site is a chatbot. I know what you are thinking; chatbots are so 2017. Well, that is when I started working on it so I am still going to share it with you all.

Alright, what does this chatbot do? It can make small talk, it can answer some simple questions about me, it can give you links to my other projects. It is basically like having a hype man.

Here are some examples of what we want to achieve:

What are some projects that you have worked on?

I am just a machine but Evan has worked on some cool things…TBD.

What is Evan good at?

Everything.

How do I contact him?

You can send him an email at [email protected]

Nice. We are cooking now. Let’s get it started (cue the black-eyed peas). Create a phoenix project

mix phx.new goldfish

This command will create a new project named goldfish. I try to come up with names for projects that are a little fun but also that won’t conflict when creating more modules. If you were to name your project ChatBot what happens when you build a bot? Is it now ChatBot.Bot? What if you want to expand your site to have blog posts? There will be a lot of refactoring in the future. So just pick a fun name.

Here are the commands to get the rest of the stuff up and running:

  • Copy environment variables with cp .env.example .env
  • Install dependencies with mix deps.get
  • Create and migrate your database with mix ecto.create && mix ecto.migrate
  • Install Node.js dependencies with cd assets && yarn
  • Start Phoenix endpoint with mix phx.server

Create some messages

Ideal, let’s now create how we are going to store these messages. Let’s run this command:

mix phx.gen.context Chat Message messages body session_id bot:boolean

The above command is creating a Message module scoped under Chat with the table name messages and the fields body, session_id, and bot. bot is a boolean here to determine that this was sent from the bot.

This task has also created a few boilerplate functions in the Goldfish.Chat module. These functions will serve as a way for the controller to create, edit, and retrieve messages through a limited API. Set session id for a visiter

Open router.ex and add the following at the bottom:

  defp put_session_id(conn, _) do
    case get_session(conn, :session_id) do
      nil ->
        token = :crypto.strong_rand_bytes(length) |> Base.url_encode64
        conn
        |> put_session(:session_id, token)
        |> assign(:session_id, token)
      token -> assign(conn, :session_id, token)
    end
  end

Also, add the following to your browser pipeline:

pipeline :browser do
  # ...
  plug :put_session_id
end

This code stores a random string as a session identifier. This will be important later to determine which room someone is in. This will allow the user to refresh the page and still have the same conversation going.

Want to continue on? Here is part two.