A received ntfy message — the JSON schema shared by publish responses and subscribe events.
Parsing is lenient by design: the server adds fields over time, so unknown
keys never crash and the original decoded map is retained in raw. Known
event names become atoms; unrecognized ones become {:unknown, string}.
Summary
Functions
Decodes a JSON binary (e.g. one NDJSON line from a /json subscription) into
a message.
Builds a message from a decoded JSON map.
Types
@type event() :: :open | :keepalive | :message | :message_clear | :message_delete | :poll_request | {:unknown, String.t()}
@type t() :: %ExNtfy.Message{ actions: [ExNtfy.Action.t()] | nil, attachment: ExNtfy.Attachment.t() | nil, click: String.t() | nil, content_type: String.t() | nil, event: event(), expires: integer() | nil, icon: String.t() | nil, id: String.t(), message: String.t() | nil, priority: 1..5 | nil, raw: map(), sequence_id: String.t() | nil, tags: [String.t()] | nil, time: integer(), title: String.t() | nil, topic: String.t() }
Functions
Decodes a JSON binary (e.g. one NDJSON line from a /json subscription) into
a message.
Returns {:error, reason} on invalid JSON, non-object JSON, or missing
always-present fields.
Builds a message from a decoded JSON map.
Returns {:error, {:missing_fields, fields}} when any of the always-present
fields (id, time, event, topic) are absent; everything else is
optional and defaults to nil.
Examples
iex> {:ok, msg} = ExNtfy.Message.from_map(%{
...> "id" => "sPs71M8A2T",
...> "time" => 1735920000,
...> "event" => "message",
...> "topic" => "mytopic",
...> "message" => "hi"
...> })
iex> {msg.event, msg.message, msg.priority}
{:message, "hi", nil}