ExLine.Client (ExLine v0.1.0)

Copy Markdown View Source

Holds the Messaging API credentials and HTTP configuration as a plain value.

A client is constructed and passed per call — the SDK never owns a global registry, so multi-channel / multi-tenant apps simply build the right client for each request:

client = ExLine.Client.new(access_token: provider.message_channel_access_token)
ExLine.Api.Messaging.push(client, user_id, message)

For the single-channel case, from_env/1 reads a default from application config.

Note: the webhook channel secret is intentionally not held here — it belongs to a different trust boundary and is passed directly to ExLine.Webhook.Signature.valid?/3.

Summary

Functions

Default response handling: 2xx → {:ok, body}, otherwise a classified ExLine.Error.

Builds a client from application config (single-channel convenience).

Builds a client from a keyword list or map.

Performs a request against the LINE API.

Builds a transport-only client with no access token.

Types

t()

@type t() :: %ExLine.Client{
  access_token: String.t() | nil,
  adapter: module(),
  base_url: String.t(),
  channel_id: String.t() | nil,
  data_url: String.t(),
  retry: keyword()
}

Functions

decode(error)

@spec decode({:ok, ExLine.Client.Adapter.response()} | {:error, ExLine.Error.t()}) ::
  {:ok, term()} | {:error, ExLine.Error.t()}

Default response handling: 2xx → {:ok, body}, otherwise a classified ExLine.Error.

from_env(app \\ :ex_line)

@spec from_env(atom()) :: t()

Builds a client from application config (single-channel convenience).

config :ex_line, access_token: "...", channel_id: "..."

new(opts)

@spec new(keyword() | map()) :: t()

Builds a client from a keyword list or map.

iex> client = ExLine.Client.new(access_token: "tok")
iex> client.access_token
"tok"
iex> client.base_url
"https://api.line.me"

request(client, opts)

@spec request(
  t(),
  keyword()
) :: {:ok, ExLine.Client.Adapter.response()} | {:error, ExLine.Error.t()}

Performs a request against the LINE API.

Options:

  • :method — HTTP method (default :get)
  • :path — request path appended to the host (required)
  • :body — request body, JSON-encoded by the adapter
  • :raw_body — request body sent as-is (e.g. image bytes); requires :content_type
  • :content_type — content type for a :raw_body upload
  • :form — request body sent as application/x-www-form-urlencoded (used by the OAuth/token endpoints)
  • :query — query params (keyword)
  • :host:api (default, base_url) or :data (data_url, for content)
  • :retry_key — sets the X-Line-Retry-Key header for idempotent retries

Returns the raw {:ok, response} / {:error, ExLine.Error.t()} from the adapter; use decode/1 (or an endpoint-specific handler) to map it to a result.

transport(opts \\ [])

@spec transport(keyword() | map()) :: t()

Builds a transport-only client with no access token.

The channel-access-token endpoints (ExLine.Api.ChannelAccessToken) authenticate with the channel id/secret or a signed JWT assertion — not a Bearer token — so they need the adapter/host configuration but not an access_token. Use this to obtain a token before you can build a normal client:

iex> client = ExLine.Client.transport()
iex> client.access_token
nil
iex> client.base_url
"https://api.line.me"