# `AisStream`
[🔗](https://github.com/GiuseppeSaluto/aisstream_elixir/blob/v0.1.0/lib/ais_stream.ex#L1)

Unofficial client for the [AISStream](https://aisstream.io) WebSocket API.

Sends every message to the `:to` process as `{:aisstream, message}` (decoded JSON) and
reconnects on its own.

    {:ok, _pid} =
      AisStream.start_link(
        api_key: System.fetch_env!("AISSTREAM_API_KEY"),
        bounding_boxes: [[[43.0, 7.5], [44.6, 10.5]]],
        filter_message_types: ["PositionReport"],
        to: self()
      )

    receive do
      {:aisstream, %{"MessageType" => type}} -> IO.puts(type)
    end

## Options

  * `:api_key` (required) - API key, or a zero-arity function returning it (use the function
    under a supervisor, to keep the key out of its reports).
  * `:bounding_boxes` (required) - list of boxes, each `[[lat1, lon1], [lat2, lon2]]`.
  * `:filter_message_types` - list of message types, e.g. `["PositionReport"]`.
  * `:to` (required) - pid or registered name receiving the messages. The client stops when a
    pid exits; with a name not registered at that moment, messages are dropped.
  * `:name` - name to register the client process under.
  * `:ping_interval` - keepalive interval in ms, default `30_000`.
  * `:max_queue_len` - drop messages while the local `:to` process has this many queued,
    logging a warning at most once a minute. Best-effort, not backpressure; remote processes
    always receive. Default `nil` (no limit).
  * `:url` - default `wss://stream.aisstream.io/v0/stream`.

# `option`

```elixir
@type option() ::
  {:api_key, String.t() | (-&gt; String.t())}
  | {:bounding_boxes, [[[number()]]]}
  | {:filter_message_types, [String.t()]}
  | {:to, pid() | atom()}
  | {:name, GenServer.name()}
  | {:ping_interval, pos_integer()}
  | {:max_queue_len, pos_integer() | nil}
  | {:url, String.t()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

```elixir
@spec start_link([option()]) :: GenServer.on_start()
```

Starts the client.

Raises `ArgumentError` on an unknown option or an invalid `:ping_interval`, `:max_queue_len`
or `:url`, and `KeyError` if `:api_key`, `:bounding_boxes`
or `:to` is missing.

---

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