defmodule ApiBrasil.Core.DeviceResponse do @moduledoc """ Envelope de resposta dos serviços *device-based* (`%{"error" => ..., "message" => ..., "response" => ..., "api_limit" => ...}`). Traz acessores nomeados e implementa `Access` — o acesso por chave continua funcionando: {:ok, envelope} = ApiBrasil.Messaging.WhatsApp.send_text(client, body) ApiBrasil.Core.DeviceResponse.error?(envelope) # false ApiBrasil.Core.DeviceResponse.response(envelope) # payload do provedor envelope["response"] # o mesmo, por chave envelope.json # envelope completo """ @behaviour Access @type t :: %__MODULE__{json: map()} defstruct json: %{} @doc "Embrulha o mapa JSON no envelope." @spec new(map()) :: t() def new(json) when is_map(json), do: %__MODULE__{json: json} @doc "Informa se o gateway sinalizou erro no envelope." @spec error?(t()) :: boolean() def error?(%__MODULE__{json: json}), do: Map.get(json, "error") == true @doc "Mensagem devolvida pelo gateway." @spec message(t()) :: String.t() | nil def message(%__MODULE__{json: json}), do: Map.get(json, "message") @doc "Payload do provedor (campo `response`)." @spec response(t()) :: term() def response(%__MODULE__{json: json}), do: Map.get(json, "response") @doc "Limite de requisições do plano." @spec api_limit(t()) :: term() def api_limit(%__MODULE__{json: json}), do: Map.get(json, "api_limit") @doc "Janela do limite (ex: `\"day\"`)." @spec api_limit_for(t()) :: term() def api_limit_for(%__MODULE__{json: json}), do: Map.get(json, "api_limit_for") @doc "Quanto do limite já foi consumido." @spec api_limit_used(t()) :: term() def api_limit_used(%__MODULE__{json: json}), do: Map.get(json, "api_limit_used") @doc "Devolve o envelope completo como mapa." @spec to_map(t()) :: map() def to_map(%__MODULE__{json: json}), do: json @impl Access def fetch(%__MODULE__{json: json}, key), do: Map.fetch(json, key) @impl Access def get_and_update(%__MODULE__{json: json} = envelope, key, function) do {value, updated} = Map.get_and_update(json, key, function) {value, %{envelope | json: updated}} end @impl Access def pop(%__MODULE__{json: json} = envelope, key) do {value, updated} = Map.pop(json, key) {value, %{envelope | json: updated}} end end