-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)]).