Packages

An Elixir client for the Polymarket API.

Current section

Files

Jump to
ex_polymarket lib websocket message_handler.ex
Raw

lib/websocket/message_handler.ex

defmodule Polymarket.WebSocket.MessageHandler do
@moduledoc """
Pure functions to handle messages coming from the Polymarket websocket.
"""
alias Polymarket.Schemas.BestBidAskEvent
alias Polymarket.Schemas.BookEvent
alias Polymarket.Schemas.LastTradePriceEvent
alias Polymarket.Schemas.MarketResolvedEvent
alias Polymarket.Schemas.NewMarketEvent
alias Polymarket.Schemas.PriceChangeEvent
alias Polymarket.Schemas.TickSizeChangeEvent
alias Polymarket.WebSocket.Handler
require Logger
@doc """
Handles an event from the websocket.
Decodes the event into a struct if possible, then forwards it to the handler
module injected into the websocket state (`state.handler`). Prints a warning
if the event is undecodable.
"""
@spec handle_message(map(), Polymarket.WebSocket.t()) ::
{:reply, {:text, String.t()}, Polymarket.WebSocket.t()}
| {:noreply, Polymarket.WebSocket.t()}
def handle_message(message, state) do
case decode_event(message) do
{:ok, event} ->
apply_handler(event, state)
{:error, _} ->
Logger.warning("Failed to decode #{inspect(message)}")
{:noreply, state}
end
end
@spec apply_handler(Handler.event(), Polymarket.WebSocket.t()) ::
{:reply, Handler.frame(), Polymarket.WebSocket.t()}
| {:noreply, Polymarket.WebSocket.t()}
defp apply_handler(event, %{handler: handler} = state) do
handler.handle_event(event, state)
end
@spec decode_event(map()) ::
{:ok,
NewMarketEvent.t()
| BestBidAskEvent.t()
| PriceChangeEvent.t()
| BookEvent.t()
| MarketResolvedEvent.t()
| LastTradePriceEvent.t()
| TickSizeChangeEvent.t()}
| {:error, {:missing_fields, [atom()]} | :unknown_message}
defp decode_event(message) do
case message do
%{event_type: "new_market"} ->
NewMarketEvent.from_attrs(message)
%{event_type: "best_bid_ask"} ->
BestBidAskEvent.from_attrs(message)
%{event_type: "price_change"} ->
PriceChangeEvent.from_attrs(message)
%{event_type: "book"} ->
BookEvent.from_attrs(message)
%{event_type: "market_resolved"} ->
MarketResolvedEvent.from_attrs(message)
%{event_type: "last_trade_price"} ->
LastTradePriceEvent.from_attrs(message)
%{event_type: "tick_size_change"} ->
TickSizeChangeEvent.from_attrs(message)
_ ->
{:error, :unknown_message}
end
end
end