defmodule GlificWeb.Providers.Gupshup.Enterprise.Controllers.MessageController do @moduledoc """ Dedicated controller to handle different types of inbound message form Gupshup """ use GlificWeb, :controller alias Glific.{ Communications, Providers.Gupshup } @doc false @spec handler(Plug.Conn.t(), map(), String.t()) :: Plug.Conn.t() def handler(conn, _params, _msg) do conn |> Plug.Conn.send_resp(200, "") |> Plug.Conn.halt() end @doc """ Parse text message payload and convert that into Glific message struct """ @spec text(Plug.Conn.t(), map()) :: Plug.Conn.t() def text(conn, params) do params |> Gupshup.Enterprise.Message.receive_text() |> Map.put(:organization_id, conn.assigns[:organization_id]) |> Communications.Message.receive_message() handler(conn, params, "text handler") end @doc """ Callback for gupshup enterprise image """ @spec image(Plug.Conn.t(), map()) :: Plug.Conn.t() def image(conn, params), do: media(conn, params, :image) @doc """ Callback for gupshup enterprise videos """ @spec video(Plug.Conn.t(), map()) :: Plug.Conn.t() def video(conn, params), do: media(conn, params, :video) @doc """ Callback for gupshup enterprise audio """ @spec audio(Plug.Conn.t(), map()) :: Plug.Conn.t() def audio(conn, params), do: media(conn, params, :audio) @doc """ Callback for gupshup enterprise document """ @spec document(Plug.Conn.t(), map()) :: Plug.Conn.t() def document(conn, params), do: media(conn, params, :document) @doc false # Handle Gupshup location message and convert them into Glific Message struct @spec location(Plug.Conn.t(), map()) :: Plug.Conn.t() def location(conn, params) do params |> Gupshup.Enterprise.Message.receive_location() |> Map.put(:organization_id, conn.assigns[:organization_id]) |> Communications.Message.receive_message(:location) handler(conn, params, "location handler") end @doc """ Parse button message payload and convert that into Glific message struct """ @spec button(Plug.Conn.t(), map()) :: Plug.Conn.t() def button(conn, params) do params |> parse_button_text() |> Gupshup.Enterprise.Message.receive_text() |> Map.put(:organization_id, conn.assigns[:organization_id]) |> Communications.Message.receive_message() handler(conn, params, "text handler") end @spec parse_button_text(map()) :: map() defp parse_button_text(params), do: params["button"] |> Jason.decode!() |> then(&Map.put(params, "text", &1["text"])) @doc """ Parse interactive list message payload and convert that into Glific message struct """ @spec interactive(Plug.Conn.t(), map()) :: Plug.Conn.t() def interactive(conn, params) do params |> parse_interactive_list() |> Gupshup.Enterprise.Message.receive_text() |> Map.put(:organization_id, conn.assigns[:organization_id]) |> Communications.Message.receive_message() handler(conn, params, "text handler") end @spec parse_interactive_list(map()) :: map() defp parse_interactive_list(params) do params["interactive"] |> Jason.decode!() |> then(&do_parse_interactive_list(params, &1, &1["type"])) end @spec do_parse_interactive_list(map(), map(), String.t()) :: map() defp do_parse_interactive_list(params, reply, "button_reply"), do: Map.put(params, "text", reply["button_reply"]["title"]) defp do_parse_interactive_list(params, reply, "list_reply"), do: Map.put(params, "text", reply["list_reply"]["title"]) @doc false # Handle Gupshup media message and convert them into Glific Message struct @spec media(Plug.Conn.t(), map(), atom()) :: Plug.Conn.t() defp media(conn, params, type) do params |> Gupshup.Enterprise.Message.receive_media() |> Map.put(:organization_id, conn.assigns[:organization_id]) |> Communications.Message.receive_message(type) handler(conn, params, "media handler") end end