Current section

Files

Jump to
telega src telega.erl
Raw

src/telega.erl

-module(telega).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/3, set_webhook/1, is_bot_request/2, bot_handler/2, reply/3, add_handler/2]).
-export_type([message_update/0, chat/0, message/0, bot/0]).
-type message_update() :: {message_update, message()}.
-type chat() :: {chat, integer()}.
-type message() :: {text_message, binary(), chat()}.
-opaque bot() :: {bot,
binary(),
binary(),
binary(),
list(fun((bot(), message()) -> {ok, nil} | {error, nil}))}.
-spec new(binary(), binary(), binary()) -> bot().
new(Token, Server_url, Secret) ->
{bot, Token, Server_url, Secret, []}.
-spec set_webhook(bot()) -> {ok, boolean()} | {error, binary()}.
set_webhook(Bot) ->
Webhook_url = <<<<(erlang:element(3, Bot))/binary, "/"/utf8>>/binary,
(erlang:element(4, Bot))/binary>>,
gleam@result:'try'(
telega@api:set_webhook(erlang:element(2, Bot), Webhook_url),
fun(Response) -> case erlang:element(2, Response) of
200 ->
{ok, true};
_ ->
{error, <<"Failed to set webhook"/utf8>>}
end end
).
-spec decode_message(gleam@dynamic:dynamic_()) -> {ok, message()} |
{error, list(gleam@dynamic:decode_error())}.
decode_message(Json) ->
Message_update_decoder = gleam@dynamic:decode1(
fun(Field@0) -> {message_update, Field@0} end,
gleam@dynamic:field(
<<"message"/utf8>>,
gleam@dynamic:decode2(
fun(Field@0, Field@1) -> {text_message, Field@0, Field@1} end,
gleam@dynamic:field(<<"text"/utf8>>, fun gleam@dynamic:string/1),
gleam@dynamic:field(
<<"chat"/utf8>>,
gleam@dynamic:decode1(
fun(Field@0) -> {chat, Field@0} end,
gleam@dynamic:field(
<<"id"/utf8>>,
fun gleam@dynamic:int/1
)
)
)
)
)
),
gleam@result:'try'(
Message_update_decoder(Json),
fun(Message_update) -> {ok, erlang:element(2, Message_update)} end
).
-spec is_bot_request(bot(), gleam@http@request:request(wisp:connection())) -> boolean().
is_bot_request(Bot, Req) ->
case fun gleam@http@request:path_segments/1(Req) of
[Segment] when Segment =:= erlang:element(4, Bot) ->
true;
_ ->
false
end.
-spec handle_update_loop(
bot(),
message(),
list(fun((bot(), message()) -> {ok, nil} | {error, nil}))
) -> nil.
handle_update_loop(Bot, Message, Handlers) ->
case Handlers of
[Handler | Rest] ->
case Handler(Bot, Message) of
{ok, _} ->
handle_update_loop(Bot, Message, Rest);
{error, _} ->
logging:log(error, <<"Failed to handle message"/utf8>>),
nil
end;
_ ->
nil
end.
-spec handle_update(bot(), message()) -> nil.
handle_update(Bot, Message) ->
handle_update_loop(Bot, Message, erlang:element(5, Bot)).
-spec bot_handler(bot(), gleam@http@request:request(wisp:connection())) -> gleam@http@response:response(wisp:body()).
bot_handler(Bot, Req) ->
wisp:require_json(Req, fun(Json) -> case decode_message(Json) of
{ok, Message} ->
logging:log(
info,
<<"Received message: "/utf8,
(erlang:element(2, Message))/binary>>
),
handle_update(Bot, Message),
wisp:ok();
{error, _} ->
logging:log(error, <<"Failed to decode message"/utf8>>),
wisp:ok()
end end).
-spec reply(bot(), message(), binary()) -> {ok, nil} | {error, nil}.
reply(Bot, Message, Text) ->
_pipe = telega@api:send_text(
erlang:element(2, Bot),
erlang:element(2, erlang:element(3, Message)),
Text
),
_pipe@1 = gleam@result:map(_pipe, fun(_) -> nil end),
gleam@result:nil_error(_pipe@1).
-spec add_handler(bot(), fun((bot(), message()) -> {ok, nil} | {error, nil})) -> bot().
add_handler(Bot, Handler) ->
erlang:setelement(5, Bot, [Handler | erlang:element(5, Bot)]).