Packages

A client used to interact with Microsoft Directline.

Current section

Files

Jump to
direxion lib client directline.ex
Raw

lib/client/directline.ex

defmodule Client.Directline do
@moduledoc """
A Microsoft Directline Client
"""
alias Direxion.{Util, Config}
@behaviour Direxion.ClientBehaviour
@doc """
Starts a conversation with directline
Returns a tuple containing the status of request and the conversation ID
"""
@spec start_conversation() :: tuple()
def start_conversation() do
url = "https://directline.botframework.com/v3/directline/conversations"
headers = Util.generate_directline_header()
case HTTPoison.post(url, "{}", headers) do
{:ok, %HTTPoison.Response{status_code: 201, body: body}} ->
conversation_id =
body
|> Poison.decode!()
|> Map.get("conversationId")
{:ok, conversation_id}
{:ok, _} ->
{:error, "Error Starting Conversation"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
@doc """
Sends an activity to a given conversation
Parameters:
* conversation_id - The Conversation ID
* activity - The activity payload
Returns a tuple containing the status of request and the activity ID
"""
@spec send_activity(String.t(), map()) :: tuple()
def send_activity(conversation_id, activity) do
url =
"https://directline.botframework.com/v3/directline/conversations/#{conversation_id}/activities"
headers = Util.generate_directline_header()
modified_activity = Util.modify_activity(activity, nil)
case HTTPoison.post(url, modified_activity, headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
id =
body
|> Poison.decode!()
|> Map.get("id")
{:ok, id}
{:ok, _} ->
{:error, "Error Sending Activity"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
@doc """
Receive the activities from a conversation.
Parameters:
* conversation_id - The Conversation ID
* activity_id - The Activity ID we want reponse to
Returns a Response object.
"""
@spec receive_activities(String.t(), String.t()) :: tuple()
def receive_activities(conversation_id, activity_id) do
url =
"https://directline.botframework.com/v3/directline/conversations/#{conversation_id}/activities"
headers = Util.generate_directline_header()
case HTTPoison.get(url, headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
body
|> Poison.decode!()
|> Map.get("activities")
|> Enum.filter(fn activity -> Map.get(activity, "replyToId") == activity_id end)
{:ok, _} ->
{:error, "Error Receiving Activities"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
@doc """
Send an activity to Directline
the response is the Directline reponse.
Parameters:
* activity - The activity to send
Returns a Directline Response
"""
@spec message(map()) :: map()
def message(activity) do
timeout = Config.get_request_timeout()
with {:ok, conversation_id} <-
Task.await(
Task.async(fn -> start_conversation() end),
timeout
),
{:ok, activity_response} <- message_conversation(conversation_id, activity) do
activity_response
end
end
@doc """
Send an activity to a conversation
the response is the Directline reponse.
Parameters:
* conversation_id - The conversation to send the activity
* activity - The activity to send
Returns a Directline Response
"""
@spec message_conversation(String.t(), map()) :: tuple()
def message_conversation(conversation_id, activity) do
timeout = Config.get_request_timeout()
with {:ok, activity_id} <-
Task.await(
Task.async(fn -> send_activity(conversation_id, activity) end),
timeout
),
{:ok, activity_response} <-
Task.await(
Task.async(fn -> receive_activities(conversation_id, activity_id) end),
timeout
) do
{:ok, activity_response}
end
end
end