Packages

A client used to interact with Microsoft Directline.

Current section

Files

Jump to
direxion lib direxion.ex
Raw

lib/direxion.ex

defmodule Direxion do
@moduledoc """
A Microsoft Directline Client
"""
require UUID
import Direxion.Util
@doc """
Get the authorization token for bots request
Returns a tuple containing the status of request and the conversation ID
"""
@spec get_authorization_token() :: tuple()
def get_authorization_token() do
url = "https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token"
headers = [{"Content-Type", "application/x-www-form-urlencoded"}]
msa_credentials = get_msa_credentials()
client_id = Map.get(msa_credentials, :client_id)
params =
msa_credentials
|> Map.put("grant_type", "client_credentials")
|> Map.put("scope", "#{client_id}/.default")
|> Map.put("atver", 1)
|> URI.encode_query()
case HTTPoison.post(url, params, headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
access_token =
body
|> Poison.decode!()
|> Map.get("access_token")
{:ok, access_token}
{:ok, _} ->
{:error, "Error Getting Authorization Token"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
@doc """
Send an activity to a bot
Parameters:
* access_token - Microsoft bot authorization token
* activity - The activity we want reponse to send
Returns the assigned activity id.
"""
@spec send_activity_to_bot(String.t(), String.t()) :: tuple()
def send_activity_to_bot(access_token, activity) do
url = "https://shopbot-local.kia-dev.car-labs.com/api/messages"
headers = generate_header(access_token)
activity_id = UUID.uuid4()
modified_activity = modify_activity(activity, activity_id)
activity_encoded = Poison.encode!(modified_activity)
case HTTPoison.post(url, activity_encoded, headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: _}} ->
{:ok, activity_id}
{:ok, _} ->
{:error, "Error Sending Activity"}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
@doc """
Receive the response from a bot response service.
Parameters:
* activity_id - The Activity ID we want reponse to
Returns a Response object.
"""
@spec receive_response(String.t()) :: tuple()
def receive_response(activity_id) do
url = get_bot_response_url()
case HTTPoison.get("#{url}/activity/#{activity_id}") do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
{:ok, Poison.decode!(body)}
{: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:
* input_token - Directline Token to be used, Will be overridden by `DIRECTLINE_TOKEN` in path if found
* activity - The activity to send
Returns a Directline Response
"""
@spec message(map()) :: map()
def message(activity) do
timeout = get_request_timeout()
with {:ok, access_token} <-
Task.await(
Task.async(fn -> get_authorization_token() end),
timeout
),
response <- message_bot(access_token, activity) do
response
end
end
@doc """
Send an activity to a conversation
the response is the Directline reponse.
Parameters:
* input_token - Directline Token to be used, Will be overridden by `DIRECTLINE_TOKEN` in path if found
* activity - The activity to send
Returns a Directline Response
"""
@spec message_bot(String.t(), map()) :: tuple()
def message_bot(access_token, activity) do
timeout = get_request_timeout()
with {:ok, activity_id} <-
Task.await(
Task.async(fn -> send_activity_to_bot(access_token, activity) end),
timeout
),
_ <- Process.sleep(1000),
{:ok, response} <-
Task.await(
Task.async(fn -> receive_response(activity_id) end),
timeout
) do
response
end
end
end