Current section

Files

Jump to
nadia examples conversation_bot.ex
Raw

examples/conversation_bot.ex

defmodule Nadia.Examples.ConversationBot do
@moduledoc false
@behaviour Nadia.Handler
alias Nadia.Context
alias Nadia.Dispatcher
alias Nadia.SessionStore
@store {Nadia.SessionStore.ETS, Nadia.Examples.ConversationBot.Sessions}
@impl Nadia.Handler
def handle_update(_update, context) do
cond do
match?({:ok, _match}, Dispatcher.match_command(context, "start")) ->
start_conversation(context)
match?({:ok, _match}, Dispatcher.match_command(context, "cancel")) ->
cancel_conversation(context)
true ->
continue_conversation(context)
end
end
def store, do: @store
defp start_conversation(context) do
with_session_key(context, fn key ->
with {:ok, _message} <- Context.reply(context, "What is your name?"),
:ok <- SessionStore.put(@store, key, %{step: :name}) do
:ok
end
end)
end
defp cancel_conversation(context) do
with_session_key(context, fn key ->
with {:ok, _message} <- Context.reply(context, "Cancelled."),
:ok <- SessionStore.delete(@store, key) do
:ok
end
end)
end
defp continue_conversation(context) do
with_session_key(context, fn key ->
with {:ok, session} <- SessionStore.get(@store, key) do
advance(context, key, session)
end
end)
end
defp advance(%Context{message: %{text: name}} = context, key, %{step: :name})
when is_binary(name) do
with {:ok, _message} <- Context.reply(context, "What is your email address?"),
:ok <- SessionStore.put(@store, key, %{step: :email, name: name}) do
:ok
end
end
defp advance(%Context{message: %{text: email}} = context, key, %{
step: :email,
name: name
})
when is_binary(email) do
with {:ok, _message} <- Context.reply(context, "Thanks #{name}. Received #{email}."),
:ok <- SessionStore.delete(@store, key) do
:ok
end
end
defp advance(_context, _key, _session), do: :ignore
defp with_session_key(context, fun) do
case SessionStore.chat_user_key(context) do
{:ok, key} -> fun.(key)
{:error, :missing_chat_id} -> :ignore
{:error, :missing_user_id} -> :ignore
end
end
end