# `SmsGora`
[🔗](https://github.com/TekservixHQ/smsgora-elixir/blob/v1.0.0/lib/smsgora.ex#L1)

Elixir client for the [SMS Gora SMS Gateway](https://tekservix.com/smsgora/) API.

SMS Gora turns Android phones with ordinary SIM cards into an SMS gateway: your server
calls the API, a linked phone sends the text, and replies and delivery reports come back.

    client = SmsGora.new(System.fetch_env!("SMSGORA_KEY"))
    {:ok, %{"message_ids" => [id]}} = SmsGora.send_sms(client, "+15551234567", "Your code is 482913")

Every function returns `{:ok, data}` (the decoded `data` field of the answer) or
`{:error, %SmsGora.Error{}}`. Keep the API key on your server.

API reference: https://tekservix.com/smsgora/docs/

# `result`

```elixir
@type result() :: {:ok, term()} | {:error, SmsGora.Error.t()}
```

Result of every API call.

# `t`

```elixir
@type t() :: %SmsGora{req: Req.Request.t()}
```

A client. Create one with `new/2` and reuse it.

# `cancel_message`

```elixir
@spec cancel_message(t(), integer() | String.t()) :: result()
```

Cancels a queued or scheduled message.

# `create_webhook`

```elixir
@spec create_webhook(t(), String.t(), keyword()) :: result()
```

Registers a webhook. Options: `:events` (default `["sms.received"]`), `:device_id`.
The answer includes the secret, returned only once.

# `delete_webhook`

```elixir
@spec delete_webhook(t(), integer() | String.t()) :: result()
```

Deletes a webhook.

# `get_account`

```elixir
@spec get_account(t()) :: result()
```

Account, plan and usage.

# `get_batch`

```elixir
@spec get_batch(t(), integer() | String.t()) :: result()
```

One bulk batch.

# `get_device`

```elixir
@spec get_device(t(), integer() | String.t()) :: result()
```

One phone.

# `get_message`

```elixir
@spec get_message(t(), integer() | String.t()) :: result()
```

One message. Status is queued, dispatched, sent, delivered, failed or cancelled.

# `list_devices`

```elixir
@spec list_devices(t()) :: result()
```

Your linked Android phones.

# `list_messages`

```elixir
@spec list_messages(t(), keyword()) :: result()
```

Sent and received messages. Filters: direction, status, device_id, phone, since, after_id, page, limit.

# `list_received_sms`

```elixir
@spec list_received_sms(t(), keyword()) :: result()
```

Incoming SMS for all phones, or one phone with `device_id:`. Other filters as in `list_messages/2`.

# `list_webhooks`

```elixir
@spec list_webhooks(t()) :: result()
```

Your webhooks.

# `new`

```elixir
@spec new(String.t(), keyword()) :: t()
```

Creates a client with your API key (starts with `sgk_`, from SMS Gora -> API keys).

Options:

  * `:base_url` - change only for testing
  * `:receive_timeout` - milliseconds to wait for an answer (default 30_000)
  * `:req_options` - extra options passed to `Req.new/1` (proxy, plug for tests, ...)

# `request`

```elixir
@spec request(t(), atom(), String.t(), map() | nil, keyword()) :: result()
```

Calls any documented endpoint, e.g. `request(client, :get, "/devices")`.
Returns the `data` field of the answer.

# `send_bulk_sms`

```elixir
@spec send_bulk_sms(t(), integer() | String.t(), [map()], keyword()) :: result()
```

Different texts for different people in one call (up to 5,000 recipients).

    SmsGora.send_bulk_sms(client, 42, [
      %{recipients: ["+15551234567"], message: "Hi Aline, parcel #1042 is ready."},
      %{recipients: ["+15557654321"]}
    ], message_template: "Hello, your parcel is ready for pickup.")

# `send_sms`

```elixir
@spec send_sms(t(), String.t() | [String.t()], String.t(), keyword()) :: result()
```

Sends an SMS to one number or a list (up to 1,000). Uses your best online phone unless
`:device_id` is given. Returns `{:ok, %{"message_ids" => [...]}}`.

Options: `:device_id`, `:sim_slot` (0 = SIM 1, 1 = SIM 2), `:schedule_at`
(`DateTime` or ISO 8601 string).

# `verify_webhook`

```elixir
@spec verify_webhook(binary(), String.t() | nil, String.t()) :: boolean()
```

Checks the `X-SmsGora-Signature` header (`sha256=<hex HMAC-SHA256 of the raw body>`).
Pass the raw request body exactly as received, before JSON parsing.

In Phoenix, keep the raw body with a custom `body_reader` in `Plug.Parsers`, then:

    SmsGora.verify_webhook(raw_body, get_req_header(conn, "x-smsgora-signature") |> List.first(), secret)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
