-module(wimp). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). -export([new/3, formatting/2, title/2, priority/2, time_to_live/2, device/2, supplimentary_url/3, sound/2, message_request/1, decode_message_response/1]). -export_type([error/0, priority/0, formatting/0, limits/0, builder/0]). -type error() :: {message_limit_exceeded, limits()} | invalid_application_token | {bad_request, binary()} | {rate_limited, limits(), binary()} | {unexpected_response, integer(), binary()}. -type priority() :: {emergency, integer(), integer()} | high | normal | low | lowest. -type formatting() :: html | text | monospace. -type limits() :: {limits, integer(), integer(), integer()}. -opaque builder() :: {builder, binary(), binary(), binary(), gleam@option:option(binary()), gleam@option:option(binary()), priority(), formatting(), gleam@option:option(integer()), gleam@option:option(binary()), gleam@option:option({binary(), binary()})}. -spec new(binary(), binary(), binary()) -> builder(). new(Token, User, Message) -> Message@1 = gleam@string:slice(Message, 0, 1024), {builder, Token, User, Message@1, none, none, normal, text, none, none, none}. -spec formatting(builder(), formatting()) -> builder(). formatting(Builder, Formatting) -> erlang:setelement(8, Builder, Formatting). -spec title(builder(), binary()) -> builder(). title(Builder, Title) -> Title@1 = gleam@string:slice(Title, 0, 250), erlang:setelement(6, Builder, {some, Title@1}). -spec priority(builder(), priority()) -> builder(). priority(Builder, Priority) -> erlang:setelement(7, Builder, Priority). -spec time_to_live(builder(), integer()) -> builder(). time_to_live(Builder, Time_to_live) -> erlang:setelement(9, Builder, {some, Time_to_live}). -spec device(builder(), binary()) -> builder(). device(Builder, Device) -> erlang:setelement(5, Builder, {some, Device}). -spec supplimentary_url(builder(), binary(), binary()) -> builder(). supplimentary_url(Builder, Title, Url) -> erlang:setelement(11, Builder, {some, {Title, Url}}). -spec sound(builder(), binary()) -> builder(). sound(Builder, Sound) -> erlang:setelement(10, Builder, {some, Sound}). -spec add_formatting(list({binary(), gleam@json:json()}), formatting()) -> list({binary(), gleam@json:json()}). add_formatting(Properties, Formatting) -> case Formatting of text -> Properties; html -> [{<<"html"/utf8>>, gleam@json:int(1)} | Properties]; monospace -> [{<<"monospace"/utf8>>, gleam@json:int(1)} | Properties] end. -spec add_supplimentary_url( list({binary(), gleam@json:json()}), gleam@option:option({binary(), binary()}) ) -> list({binary(), gleam@json:json()}). add_supplimentary_url(Properties, Supplimentary_url) -> case Supplimentary_url of none -> Properties; {some, {Title, Url}} -> [{<<"url"/utf8>>, gleam@json:string(Url)}, {<<"url_title"/utf8>>, gleam@json:string(Title)} | Properties] end. -spec add_priority(list({binary(), gleam@json:json()}), priority()) -> list({binary(), gleam@json:json()}). add_priority(Properties, Priority) -> {Extra@1, Priority@1} = case Priority of {emergency, Retry, Expire} -> Extra = [{<<"retry"/utf8>>, gleam@json:int(gleam@int:max(Retry, 30))}, {<<"expire"/utf8>>, gleam@json:int(gleam@int:min(Expire, 10800))}], {Extra, 2}; high -> {[], 1}; normal -> {[], 0}; low -> {[], -1}; lowest -> {[], -2} end, _pipe = Extra@1, _pipe@1 = gleam@list:append(_pipe, Properties), gleam@list:prepend( _pipe@1, {<<"priority"/utf8>>, gleam@json:int(Priority@1)} ). -spec maybe_add( list({binary(), gleam@json:json()}), binary(), gleam@option:option(GSD), fun((GSD) -> gleam@json:json()) ) -> list({binary(), gleam@json:json()}). maybe_add(Properties, Key, Value, Encode) -> case Value of none -> Properties; {some, Value@1} -> [{Key, Encode(Value@1)} | Properties] end. -spec message_request(builder()) -> gleam@http@request:request(binary()). message_request(Builder) -> case erlang:element(4, Builder) of <<""/utf8>> -> erlang:error(#{gleam_error => panic, message => <<"message must not be blank"/utf8>>, module => <<"wimp"/utf8>>, function => <<"message_request"/utf8>>, line => 169}); _ -> nil end, Properties = begin _pipe = [{<<"token"/utf8>>, gleam@json:string(erlang:element(2, Builder))}, {<<"user"/utf8>>, gleam@json:string(erlang:element(3, Builder))}, {<<"message"/utf8>>, gleam@json:string(erlang:element(4, Builder))}], _pipe@1 = add_priority(_pipe, erlang:element(7, Builder)), _pipe@2 = add_formatting(_pipe@1, erlang:element(8, Builder)), _pipe@3 = add_supplimentary_url(_pipe@2, erlang:element(11, Builder)), _pipe@4 = maybe_add( _pipe@3, <<"ttl"/utf8>>, erlang:element(9, Builder), fun gleam@json:int/1 ), _pipe@5 = maybe_add( _pipe@4, <<"title"/utf8>>, erlang:element(6, Builder), fun gleam@json:string/1 ), _pipe@6 = maybe_add( _pipe@5, <<"sound"/utf8>>, erlang:element(10, Builder), fun gleam@json:string/1 ), maybe_add( _pipe@6, <<"device"/utf8>>, erlang:element(5, Builder), fun gleam@json:string/1 ) end, _pipe@7 = gleam@http@request:new(), _pipe@8 = gleam@http@request:set_method(_pipe@7, post), _pipe@9 = gleam@http@request:set_host(_pipe@8, <<"api.pushover.net"/utf8>>), _pipe@10 = gleam@http@request:set_path(_pipe@9, <<"/1/messages.json"/utf8>>), _pipe@11 = gleam@http@request:set_body( _pipe@10, gleam@json:to_string(gleam@json:object(Properties)) ), _pipe@12 = gleam@http@request:prepend_header( _pipe@11, <<"accept"/utf8>>, <<"application/json"/utf8>> ), gleam@http@request:prepend_header( _pipe@12, <<"content-type"/utf8>>, <<"application/json"/utf8>> ). -spec decode_message_response(gleam@http@response:response(binary())) -> {ok, limits()} | {error, error()}. decode_message_response(Resp) -> Get_int_header = fun(Name) -> _pipe = Resp, _pipe@1 = gleam@http@response:get_header(_pipe, Name), _pipe@2 = gleam@result:'try'(_pipe@1, fun gleam@int:parse/1), gleam@result:unwrap(_pipe@2, 0) end, App_limit = Get_int_header(<<"x-limit-app-limit"/utf8>>), App_remaining = Get_int_header(<<"x-limit-app-remaining"/utf8>>), App_reset = Get_int_header(<<"x-limit-app-reset"/utf8>>), Limits = {limits, App_limit, App_remaining, App_reset}, case erlang:element(2, Resp) of 200 -> {ok, Limits}; 400 -> {error, case gleam_stdlib:contains_string( erlang:element(4, Resp), <<"application token is invalid"/utf8>> ) of true -> invalid_application_token; false -> {bad_request, erlang:element(4, Resp)} end}; 429 -> {error, {rate_limited, Limits, erlang:element(4, Resp)}}; Code -> {error, {unexpected_response, Code, erlang:element(4, Resp)}} end.