Current section
Files
Jump to
Current section
Files
src/wimp.erl
-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.