-module(telega@client). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/telega/client.gleam"). -export([new/2, use_transformer/2, set_default_parse_mode/2, default_parse_mode_string/1, default_request_queue_config/0, set_request_queue/2, new_with_queue/2, fetch/2, fetch_multipart/4, set_fetch_client/2, set_fetch_bits_client/2, get_fetch_bits_client/1, set_max_retry_attempts/2, set_tg_api_url/2, get_token/1, shutdown/1, get_queue_length/1, is_queue_overheated/1, fetch_with_rule/3, get_api_url/1, request_method/1, request_body/1, map_request_body/2, new_post_request/3, new_get_request/3]). -export_type([telegram_client/0, request_queue_config/0, request_queue_rule/0, telegram_api_request/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Module provides a simple interface to the Telegram Bot API.\n" " If you want to use `telega` as a Telegram client, you can use only this module.\n" "\n" " Use an adapter package like `telega_httpc` or `telega_hackney` to create a client,\n" " or provide your own `FetchClient` function.\n" "\n" " ```gleam\n" " import telega/client\n" " import telega/api\n" "\n" " fn main() {\n" " ...\n" " let response = client.new(token, my_fetch_adapter) |> api.send_message(client, send_message_parameters)\n" " ...\n" " }\n" " ```\n" ). -opaque telegram_client() :: {telegram_client, binary(), integer(), binary(), fun((gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}), gleam@option:option(fun((gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(bitstring())} | {error, telega@error:telega_error()})), gleam@option:option(telega@internal@request_queue:request_queue()), list(fun((telegram_api_request(), fun((telegram_api_request()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()})) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()})), gleam@option:option(telega@format:parse_mode())}. -type request_queue_config() :: {request_queue_config, list(request_queue_rule()), gleam@option:option(integer()), gleam@option:option(integer()), integer(), integer()}. -type request_queue_rule() :: {request_queue_rule, binary(), integer(), integer(), integer()}. -opaque telegram_api_request() :: {telegram_api_post_request, binary(), binary(), binary()} | {telegram_api_get_request, binary(), gleam@option:option(list({binary(), binary()})), binary()}. -file("src/telega/client.gleam", 92). ?DOC(" Create a new Telegram client with the given fetch client adapter.\n"). -spec new( binary(), fun((gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> telegram_client(). new(Token, Fetch_client) -> {telegram_client, Token, 3, <<"https://api.telegram.org/bot"/utf8>>, Fetch_client, none, none, [], none}. -file("src/telega/client.gleam", 111). ?DOC( " Add a transformer to the client's middleware chain.\n" " Transformers run in the order they were added: the first added\n" " is the outermost (sees the request first, the result last).\n" ). -spec use_transformer( telegram_client(), fun((telegram_api_request(), fun((telegram_api_request()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()})) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> telegram_client(). use_transformer(Client, Transformer) -> {telegram_client, erlang:element(2, Client), erlang:element(3, Client), erlang:element(4, Client), erlang:element(5, Client), erlang:element(6, Client), erlang:element(7, Client), lists:append(erlang:element(8, Client), [Transformer]), erlang:element(9, Client)}. -file("src/telega/client.gleam", 124). ?DOC( " Set the default parse mode for `telega/reply` text helpers\n" " (`with_text`, `with_markup`, `edit_text`, ...). Explicit helpers like\n" " `with_html` and parameters with a parse mode already set are not affected.\n" ). -spec set_default_parse_mode(telegram_client(), telega@format:parse_mode()) -> telegram_client(). set_default_parse_mode(Client, Parse_mode) -> {telegram_client, erlang:element(2, Client), erlang:element(3, Client), erlang:element(4, Client), erlang:element(5, Client), erlang:element(6, Client), erlang:element(7, Client), erlang:element(8, Client), {some, Parse_mode}}. -file("src/telega/client.gleam", 133). ?DOC( " Get the default parse mode as an API string (e.g. `Some(\"HTML\")`),\n" " or `None` if no default is configured.\n" ). -spec default_parse_mode_string(telegram_client()) -> gleam@option:option(binary()). default_parse_mode_string(Client) -> gleam@option:map( erlang:element(9, Client), fun telega@format:parse_mode_to_string/1 ). -file("src/telega/client.gleam", 351). -spec default_request_queue_config() -> request_queue_config(). default_request_queue_config() -> Default_config = telega@internal@request_queue:default_config(), Rules = gleam@list:map( erlang:element(2, Default_config), fun(Rule) -> {request_queue_rule, erlang:element(2, Rule), erlang:element(3, Rule), erlang:element(4, Rule), erlang:element(5, Rule)} end ), {request_queue_config, Rules, erlang:element(3, Default_config), erlang:element(4, Default_config), erlang:element(5, Default_config), erlang:element(6, Default_config)}. -file("src/telega/client.gleam", 426). ?DOC( " Enable request queue with custom configuration for rate limiting\n" "\n" " The request queue helps prevent hitting Telegram's rate limits by:\n" " - Queuing requests when limits are reached\n" " - Automatically retrying failed requests with exponential backoff\n" " - Supporting different rate limits for different types of requests\n" "\n" " ## Example\n" "\n" " ```gleam\n" " import telega/client\n" "\n" " let config = client.RequestQueueConfig(\n" " rules: [\n" " // Default rule for most requests\n" " client.RequestQueueRule(\n" " id: \"default\",\n" " rate: 30, // 30 requests\n" " limit: 1000, // per 1 second\n" " priority: 5,\n" " ),\n" " // Slower rate for sending messages\n" " client.RequestQueueRule(\n" " id: \"send_message\",\n" " rate: 1, // 1 request\n" " limit: 1000, // per 1 second\n" " priority: 10,\n" " ),\n" " // Higher priority for important requests\n" " client.RequestQueueRule(\n" " id: \"important\",\n" " rate: 5,\n" " limit: 1000,\n" " priority: 1, // Lower number = higher priority\n" " ),\n" " ],\n" " overall_rate: Some(30), // Global limit across all rules\n" " overall_limit: Some(100), // Max concurrent requests\n" " retry_delay: 1000, // Retry after 1 second\n" " max_retries: 3,\n" " )\n" "\n" " let assert Ok(client) =\n" " client.new(token)\n" " |> client.set_request_queue(config)\n" "\n" " // Use specific rule for rate-limited operations\n" " client.fetch_with_rule(request, client, \"send_message\")\n" "\n" " // Check queue status\n" " let queue_length = client.get_queue_length(client)\n" " let is_busy = client.is_queue_overheated(client)\n" " ```\n" ). -spec set_request_queue(telegram_client(), request_queue_config()) -> {ok, telegram_client()} | {error, telega@error:telega_error()}. set_request_queue(Client, Config) -> case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:shutdown(Queue); none -> nil end, gleam@result:'try'( begin _pipe = telega@internal@request_queue:start( {queue_config, gleam@list:map( erlang:element(2, Config), fun(Rule) -> {rule, erlang:element(2, Rule), erlang:element(3, Rule), erlang:element(4, Rule), erlang:element(5, Rule)} end ), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config)} ), gleam@result:map_error( _pipe, fun(_) -> {fetch_error, <<"Failed to start request queue"/utf8>>} end ) end, fun(Queue@1) -> {ok, {telegram_client, erlang:element(2, Client), erlang:element(3, Client), erlang:element(4, Client), erlang:element(5, Client), erlang:element(6, Client), {some, Queue@1}, erlang:element(8, Client), erlang:element(9, Client)}} end ). -file("src/telega/client.gleam", 143). ?DOC( " Create a new Telegram client with default request queue configuration.\n" "\n" " This is a convenience function that creates a client with sensible\n" " default rate limiting settings for the Telegram Bot API.\n" ). -spec new_with_queue( binary(), fun((gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> {ok, telegram_client()} | {error, telega@error:telega_error()}. new_with_queue(Token, Fetch_client) -> _pipe = new(Token, Fetch_client), set_request_queue(_pipe, default_request_queue_config()). -file("src/telega/client.gleam", 552). -spec emit_api_retry(binary(), integer(), integer()) -> nil. emit_api_retry(Method, Attempt, Retry_delay) -> telega@telemetry:execute( [<<"telega"/utf8>>, <<"api_call"/utf8>>, <<"retry"/utf8>>], [{<<"retry_after"/utf8>>, Retry_delay}], [{<<"method"/utf8>>, {string_value, Method}}, {<<"attempt"/utf8>>, {int_value, Attempt}}] ). -file("src/telega/client.gleam", 565). ?DOC( " Extract the delay in milliseconds from a 429 response's\n" " `parameters.retry_after` (seconds), falling back to the default delay.\n" ). -spec retry_delay_from_response(gleam@http@response:response(binary())) -> integer(). retry_delay_from_response(Response) -> _pipe = gleam@json:parse( erlang:element(4, Response), gleam@dynamic@decode:at( [<<"parameters"/utf8>>, <<"retry_after"/utf8>>], {decoder, fun gleam@dynamic@decode:decode_int/1} ) ), _pipe@1 = gleam@result:map( _pipe, fun(Retry_after) -> Retry_after * 1000 end ), gleam@result:unwrap(_pipe@1, 1000). -file("src/telega/client.gleam", 574). -spec send_with_retry( telegram_client(), binary(), gleam@http@request:request(binary()), integer() ) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. send_with_retry(Client, Method, Api_request, Retries) -> Response = (erlang:element(5, Client))(Api_request), case Retries of 0 -> Response; _ -> case Response of {ok, Response@1} -> case erlang:element(2, Response@1) of 429 -> Retry_delay = retry_delay_from_response(Response@1), emit_api_retry( Method, (erlang:element(3, Client) - Retries) + 1, Retry_delay ), gleam_erlang_ffi:sleep(Retry_delay), send_with_retry( Client, Method, Api_request, Retries - 1 ); _ -> {ok, Response@1} end; {error, _} -> emit_api_retry( Method, (erlang:element(3, Client) - Retries) + 1, 1000 ), gleam_erlang_ffi:sleep(1000), send_with_retry(Client, Method, Api_request, Retries - 1) end end. -file("src/telega/client.gleam", 511). -spec send_request(telegram_client(), gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. send_request(Client, Api_request) -> (erlang:element(5, Client))(Api_request). -file("src/telega/client.gleam", 639). -spec set_query( gleam@http@request:request(KTP), gleam@option:option(list({binary(), binary()})) ) -> gleam@http@request:request(KTP). set_query(Api_request, Query) -> case Query of none -> Api_request; {some, Query@1} -> gleam@http@request:set_query(Api_request, Query@1) end. -file("src/telega/client.gleam", 616). -spec api_to_request(telegram_api_request()) -> {ok, gleam@http@request:request(binary())} | {error, telega@error:telega_error()}. api_to_request(Api_request) -> _pipe@7 = case Api_request of {telegram_api_get_request, Url, Query, _} -> _pipe = gleam@http@request:to(Url), gleam@result:map(_pipe, fun(Req) -> _pipe@1 = Req, _pipe@2 = gleam@http@request:set_method(_pipe@1, get), set_query(_pipe@2, Query) end); {telegram_api_post_request, Url@1, Body, _} -> _pipe@3 = gleam@http@request:to(Url@1), gleam@result:map(_pipe@3, fun(Req@1) -> _pipe@4 = Req@1, _pipe@5 = gleam@http@request:set_body(_pipe@4, Body), _pipe@6 = gleam@http@request:set_method(_pipe@5, post), gleam@http@request:set_header( _pipe@6, <<"Content-Type"/utf8>>, <<"application/json"/utf8>> ) end) end, gleam@result:map_error(_pipe@7, fun(_) -> api_to_request_convert_error end). -file("src/telega/client.gleam", 265). -spec apply_transformers( list(fun((telegram_api_request(), fun((telegram_api_request()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()})) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()})), telegram_api_request(), fun((telegram_api_request()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. apply_transformers(Transformers, Request, Terminal) -> case Transformers of [] -> Terminal(Request); [Transformer | Rest] -> Transformer( Request, fun(Request@1) -> apply_transformers(Rest, Request@1, Terminal) end ) end. -file("src/telega/client.gleam", 519). ?DOC(" Wraps a request execution in `telega.api_call` start/stop/exception events.\n"). -spec fetch_with_telemetry( binary(), fun(() -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. fetch_with_telemetry(Method, Run) -> Metadata = [{<<"method"/utf8>>, {string_value, Method}}], Started_at = erlang:monotonic_time(), telega@telemetry:execute( [<<"telega"/utf8>>, <<"api_call"/utf8>>, <<"start"/utf8>>], [{<<"system_time"/utf8>>, erlang:system_time()}], Metadata ), Result = Run(), Duration = erlang:monotonic_time() - Started_at, case Result of {ok, Response} -> telega@telemetry:execute( [<<"telega"/utf8>>, <<"api_call"/utf8>>, <<"stop"/utf8>>], [{<<"duration"/utf8>>, Duration}], [{<<"status"/utf8>>, {int_value, erlang:element(2, Response)}} | Metadata] ); {error, Error} -> telega@telemetry:execute( [<<"telega"/utf8>>, <<"api_call"/utf8>>, <<"exception"/utf8>>], [{<<"duration"/utf8>>, Duration}], [{<<"error"/utf8>>, {string_value, gleam@string:inspect(Error)}} | Metadata] ) end, Result. -file("src/telega/client.gleam", 154). ?DOC( " Send a request to the Telegram Bot API.\n" "\n" " It uses `default` rule for rate limiting (if request [queue](#set_request_queue) is enabled).\n" ). -spec fetch(telegram_api_request(), telegram_client()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. fetch(Api_request, Client) -> fetch_with_telemetry( erlang:element(4, Api_request), fun() -> apply_transformers( erlang:element(8, Client), Api_request, fun(Api_request@1) -> Method = erlang:element(4, Api_request@1), gleam@result:'try'( api_to_request(Api_request@1), fun(Api_request@2) -> case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:execute( Queue, fun() -> send_request(Client, Api_request@2) end ); none -> send_with_retry( Client, Method, Api_request@2, erlang:element(3, Client) ) end end ) end ) end ). -file("src/telega/client.gleam", 226). -spec send_bits_with_retry( telegram_client(), binary(), fun(() -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}), integer() ) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. send_bits_with_retry(Client, Method, Send, Retries) -> Response = Send(), case Retries of 0 -> Response; _ -> case Response of {ok, Response@1} -> case erlang:element(2, Response@1) of 429 -> Retry_delay = retry_delay_from_response(Response@1), emit_api_retry( Method, (erlang:element(3, Client) - Retries) + 1, Retry_delay ), gleam_erlang_ffi:sleep(Retry_delay), send_bits_with_retry( Client, Method, Send, Retries - 1 ); _ -> {ok, Response@1} end; {error, _} -> emit_api_retry( Method, (erlang:element(3, Client) - Retries) + 1, 1000 ), gleam_erlang_ffi:sleep(1000), send_bits_with_retry(Client, Method, Send, Retries - 1) end end. -file("src/telega/client.gleam", 215). -spec stringify_response( {ok, gleam@http@response:response(bitstring())} | {error, telega@error:telega_error()} ) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. stringify_response(Response) -> gleam@result:'try'( Response, fun(Response@1) -> _pipe = gleam@bit_array:to_string(erlang:element(4, Response@1)), _pipe@1 = gleam@result:replace_error( _pipe, {fetch_error, <<"upload response body was not valid UTF-8"/utf8>>} ), gleam@result:map( _pipe@1, fun(_capture) -> gleam@http@response:set_body(Response@1, _capture) end ) end ). -file("src/telega/client.gleam", 700). -spec build_url(telegram_client(), binary()) -> binary(). build_url(Client, Path) -> <<<<<<(erlang:element(4, Client))/binary, (erlang:element(2, Client))/binary>>/binary, "/"/utf8>>/binary, Path/binary>>. -file("src/telega/client.gleam", 177). ?DOC( " Send a `multipart/form-data` POST (a `BitArray` body) to `method`, routed\n" " through the SAME request queue and 429-retry path as JSON calls, using the\n" " configured `FetchBitsClient`. This is how raw file uploads (e.g. sending a\n" " photo by bytes) honor the one-queue rate-limit invariant — there is no\n" " second HTTP client. Errors if no `FetchBitsClient` is configured.\n" ). -spec fetch_multipart(telegram_client(), binary(), binary(), bitstring()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. fetch_multipart(Client, Method, Content_type, Body) -> fetch_with_telemetry( Method, fun() -> gleam@result:'try'(case erlang:element(6, Client) of {some, F} -> {ok, F}; none -> {error, {fetch_error, <<"No FetchBitsClient configured for multipart upload. Use "/utf8, "client.set_fetch_bits_client or an adapter like telega_httpc."/utf8>>}} end, fun(Fetch_bits) -> gleam@result:'try'( begin _pipe = gleam@http@request:to( build_url(Client, Method) ), gleam@result:map_error( _pipe, fun(_) -> api_to_request_convert_error end ) end, fun(Req) -> Bits_req = begin _pipe@1 = Req, _pipe@2 = gleam@http@request:set_body( _pipe@1, Body ), _pipe@3 = gleam@http@request:set_method( _pipe@2, post ), gleam@http@request:set_header( _pipe@3, <<"content-type"/utf8>>, Content_type ) end, Send = fun() -> _pipe@4 = Fetch_bits(Bits_req), stringify_response(_pipe@4) end, case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:execute( Queue, Send ); none -> send_bits_with_retry( Client, Method, Send, erlang:element(3, Client) ) end end ) end) end ). -file("src/telega/client.gleam", 280). ?DOC(" Set the HTTP client to use.\n"). -spec set_fetch_client( telegram_client(), fun((gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}) ) -> telegram_client(). set_fetch_client(Client, Fetch_client) -> {telegram_client, erlang:element(2, Client), erlang:element(3, Client), erlang:element(4, Client), Fetch_client, erlang:element(6, Client), erlang:element(7, Client), erlang:element(8, Client), erlang:element(9, Client)}. -file("src/telega/client.gleam", 289). ?DOC(" Set the binary HTTP client for file downloads.\n"). -spec set_fetch_bits_client( telegram_client(), fun((gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(bitstring())} | {error, telega@error:telega_error()}) ) -> telegram_client(). set_fetch_bits_client(Client, Fetch_bits_client) -> {telegram_client, erlang:element(2, Client), erlang:element(3, Client), erlang:element(4, Client), erlang:element(5, Client), {some, Fetch_bits_client}, erlang:element(7, Client), erlang:element(8, Client), erlang:element(9, Client)}. -file("src/telega/client.gleam", 297). ?DOC(" Get the binary HTTP client, if configured.\n"). -spec get_fetch_bits_client(telegram_client()) -> gleam@option:option(fun((gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(bitstring())} | {error, telega@error:telega_error()})). get_fetch_bits_client(Client) -> erlang:element(6, Client). -file("src/telega/client.gleam", 304). ?DOC(" Set the maximum number of times to retry sending a API message.\n"). -spec set_max_retry_attempts(telegram_client(), integer()) -> telegram_client(). set_max_retry_attempts(Client, Max_retry_attempts) -> {telegram_client, erlang:element(2, Client), Max_retry_attempts, erlang:element(4, Client), erlang:element(5, Client), erlang:element(6, Client), erlang:element(7, Client), erlang:element(8, Client), erlang:element(9, Client)}. -file("src/telega/client.gleam", 312). ?DOC(" Set the Telegram Bot API URL.\n"). -spec set_tg_api_url(telegram_client(), binary()) -> telegram_client(). set_tg_api_url(Client, Tg_api_url) -> {telegram_client, erlang:element(2, Client), erlang:element(3, Client), Tg_api_url, erlang:element(5, Client), erlang:element(6, Client), erlang:element(7, Client), erlang:element(8, Client), erlang:element(9, Client)}. -file("src/telega/client.gleam", 320). ?DOC(" Get the bot token from the client\n"). -spec get_token(telegram_client()) -> binary(). get_token(Client) -> erlang:element(2, Client). -file("src/telega/client.gleam", 461). ?DOC( " Shutdown the client and its request queue\n" "\n" " Only recommended if request queue is enabled.\n" ). -spec shutdown(telegram_client()) -> nil. shutdown(Client) -> case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:shutdown(Queue); none -> nil end. -file("src/telega/client.gleam", 471). ?DOC( " Get the total number of requests waiting in the queue\n" "\n" " Returns 0 if no queue is configured\n" ). -spec get_queue_length(telegram_client()) -> integer(). get_queue_length(Client) -> case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:total_length(Queue); none -> 0 end. -file("src/telega/client.gleam", 481). ?DOC( " Check if the queue is overheated (any rule is at its rate limit)\n" "\n" " Returns False if no queue is configured\n" ). -spec is_queue_overheated(telegram_client()) -> boolean(). is_queue_overheated(Client) -> case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:is_overheated(Queue); none -> false end. -file("src/telega/client.gleam", 488). -spec fetch_with_rule(telegram_api_request(), telegram_client(), binary()) -> {ok, gleam@http@response:response(binary())} | {error, telega@error:telega_error()}. fetch_with_rule(Api_request, Client, Rule_id) -> fetch_with_telemetry( erlang:element(4, Api_request), fun() -> apply_transformers( erlang:element(8, Client), Api_request, fun(Api_request@1) -> Method = erlang:element(4, Api_request@1), gleam@result:'try'( api_to_request(Api_request@1), fun(Api_request@2) -> Request_id = telega@internal@utils:random_string(32), case erlang:element(7, Client) of {some, Queue} -> telega@internal@request_queue:execute_with_rule( Queue, Request_id, Rule_id, fun() -> send_request(Client, Api_request@2) end ); none -> send_with_retry( Client, Method, Api_request@2, erlang:element(3, Client) ) end end ) end ) end ). -file("src/telega/client.gleam", 646). -spec get_api_url(telegram_client()) -> binary(). get_api_url(Client) -> erlang:element(4, Client). -file("src/telega/client.gleam", 660). ?DOC(" Get the Telegram API method name of a request (e.g. \"sendMessage\").\n"). -spec request_method(telegram_api_request()) -> binary(). request_method(Request) -> erlang:element(4, Request). -file("src/telega/client.gleam", 665). ?DOC(" Get the JSON body of a request. Returns `None` for GET requests.\n"). -spec request_body(telegram_api_request()) -> gleam@option:option(binary()). request_body(Request) -> case Request of {telegram_api_post_request, _, Body, _} -> {some, Body}; {telegram_api_get_request, _, _, _} -> none end. -file("src/telega/client.gleam", 673). ?DOC(" Transform the JSON body of a POST request. GET requests are returned unchanged.\n"). -spec map_request_body(telegram_api_request(), fun((binary()) -> binary())) -> telegram_api_request(). map_request_body(Request, Mapper) -> case Request of {telegram_api_post_request, Url, Body, Method} -> {telegram_api_post_request, Url, Mapper(Body), Method}; {telegram_api_get_request, _, _, _} -> Request end. -file("src/telega/client.gleam", 684). -spec new_post_request(telegram_client(), binary(), binary()) -> telegram_api_request(). new_post_request(Client, Path, Body) -> {telegram_api_post_request, build_url(Client, Path), Body, Path}. -file("src/telega/client.gleam", 692). -spec new_get_request( telegram_client(), binary(), gleam@option:option(list({binary(), binary()})) ) -> telegram_api_request(). new_get_request(Client, Path, Query) -> {telegram_api_get_request, build_url(Client, Path), Query, Path}.