-module(telega). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/telega.gleam"). -export([get_bot_subject_internal/1, get_client_internal/1, is_webhook_path/2, is_secret_token_valid/2, get_api_config/1, new/4, new_for_polling/1, with_router/2, with_session_settings/2, with_catch_handler/2, set_drop_pending_updates/2, set_max_connections/2, set_ip_address/2, set_allowed_updates/2, set_certificate/2, set_api_client/2, with_polling_config/4, with_polling_on_stop/2, with_chat_config/4, with_nil_session/1, handle_update/2, get_me/1, get_session/1, log_context/3, log_info/2, log_error/2, wait_any/4, wait_command/5, wait_commands/5, wait_text/4, wait_hears/5, wait_message/4, wait_callback_query/5, wait_audio/4, wait_video/4, wait_voice/4, wait_photos/4, wait_number/6, wait_email/4, wait_for/5, start_polling_default/1, shutdown/1, get_supervisor_pid/1, wait_choice/5, init/1, init_for_polling/1, init_for_polling_nil_session/1]). -export_type([telega/2, telega_builder/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -opaque telega(AGSL, AGSM) :: {telega, telega@internal@config:config(), telega@model@types:user(), gleam@erlang@process:subject(telega@bot:bot_message()), gleam@erlang@process:pid_()} | {gleam_phantom, AGSL, AGSM}. -opaque telega_builder(AGSN, AGSO) :: {telega_builder, telega@internal@config:config(), gleam@option:option(telega@router:router(AGSN, AGSO)), gleam@option:option(telega@bot:session_settings(AGSN, AGSO)), gleam@option:option(fun((telega@bot:context(AGSN, AGSO), AGSO) -> {ok, nil} | {error, AGSO})), gleam@option:option(gleam@erlang@process:subject(telega@bot:bot_message())), gleam@option:option(telega@client:telegram_client()), gleam@option:option(boolean()), gleam@option:option(integer()), gleam@option:option(binary()), gleam@option:option(list(binary())), gleam@option:option(telega@model@types:file()), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(fun((telega@error:telega_error()) -> nil)), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(integer())}. -file("src/telega.gleam", 65). ?DOC(false). -spec get_bot_subject_internal(telega(any(), any())) -> gleam@erlang@process:subject(telega@bot:bot_message()). get_bot_subject_internal(Telega) -> erlang:element(4, Telega). -file("src/telega.gleam", 71). ?DOC(false). -spec get_client_internal(telega(any(), any())) -> telega@client:telegram_client(). get_client_internal(Telega) -> erlang:element(5, erlang:element(2, Telega)). -file("src/telega.gleam", 80). ?DOC( " Check if a path is the webhook path for the bot.\n" "\n" " Useful if you plan to implement own adapter.\n" ). -spec is_webhook_path(telega(any(), any()), binary()) -> boolean(). is_webhook_path(Telega, Path) -> erlang:element(3, erlang:element(2, Telega)) =:= Path. -file("src/telega.gleam", 87). ?DOC( " Check if a secret token is valid.\n" "\n" " Useful if you plan to implement own adapter.\n" ). -spec is_secret_token_valid(telega(any(), any()), binary()) -> boolean(). is_secret_token_valid(Telega, Token) -> erlang:element(4, erlang:element(2, Telega)) =:= Token. -file("src/telega.gleam", 92). ?DOC(" Helper to get the config for API requests.\n"). -spec get_api_config(telega(any(), any())) -> telega@client:telegram_client(). get_api_config(Telega) -> erlang:element(5, erlang:element(2, Telega)). -file("src/telega.gleam", 99). ?DOC( " Create a new Telega instance.\n" "\n" " Requires an `api_client` created by an adapter package like `telega_httpc` or `telega_hackney`.\n" ). -spec new( telega@client:telegram_client(), binary(), binary(), gleam@option:option(binary()) ) -> telega_builder(any(), any()). new(Api_client, Server_url, Webhook_path, Secret_token) -> Url = telega@internal@utils:normalize_url(Server_url), Webhook_path@1 = telega@internal@utils:normalize_webhook_path(Webhook_path), {telega_builder, telega@internal@config:new( Api_client, Url, Webhook_path@1, Secret_token ), none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none}. -file("src/telega.gleam", 134). ?DOC( " Create a new Telega instance optimized for long polling.\n" "\n" " Requires an `api_client` created by an adapter package like `telega_httpc` or `telega_hackney`.\n" " This is a convenience function for polling bots that don't need webhook configuration.\n" ). -spec new_for_polling(telega@client:telegram_client()) -> telega_builder(any(), any()). new_for_polling(Api_client) -> {telega_builder, telega@internal@config:new( Api_client, <<"https://api.telegram.org"/utf8>>, <<"/webhook"/utf8>>, none ), none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none}. -file("src/telega.gleam", 165). ?DOC( " Set the router for handling updates.\n" " This is the primary way to handle updates - use router.new() to create a router\n" " and configure it with command handlers, text handlers, middleware, etc.\n" ). -spec with_router(telega_builder(AGTP, AGTQ), telega@router:router(AGTP, AGTQ)) -> telega_builder(AGTP, AGTQ). with_router(Builder, Router) -> {telega_builder, erlang:element(2, Builder), {some, Router}, erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 173). ?DOC(" Set session settings for the bot.\n"). -spec with_session_settings( telega_builder(AGTX, AGTY), telega@bot:session_settings(AGTX, AGTY) ) -> telega_builder(AGTX, AGTY). with_session_settings(Builder, Session_settings) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), {some, Session_settings}, erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 182). ?DOC( " Set catch handler for system errors (like session persistence failures) and [conversation](/docs/conversation) errors.\n" " This is different from router's catch handler which handles route errors.\n" ). -spec with_catch_handler( telega_builder(AGUF, AGUG), fun((telega@bot:context(AGUF, AGUG), AGUG) -> {ok, nil} | {error, AGUG}) ) -> telega_builder(AGUF, AGUG). with_catch_handler(Builder, Catch_handler) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), {some, Catch_handler}, erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 190). ?DOC(" Set whether to drop pending updates.\n"). -spec set_drop_pending_updates(telega_builder(AGUN, AGUO), boolean()) -> telega_builder(AGUN, AGUO). set_drop_pending_updates(Builder, Drop) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), {some, Drop}, erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 198). ?DOC(" Set max connections for webhook.\n"). -spec set_max_connections(telega_builder(AGUT, AGUU), integer()) -> telega_builder(AGUT, AGUU). set_max_connections(Builder, Max) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), {some, Max}, erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 206). ?DOC(" Set IP address for webhook.\n"). -spec set_ip_address(telega_builder(AGUZ, AGVA), binary()) -> telega_builder(AGUZ, AGVA). set_ip_address(Builder, Ip) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), {some, Ip}, erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 214). ?DOC(" Set allowed updates for webhook.\n"). -spec set_allowed_updates(telega_builder(AGVF, AGVG), list(binary())) -> telega_builder(AGVF, AGVG). set_allowed_updates(Builder, Updates) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), {some, Updates}, erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 222). ?DOC(" Set certificate for webhook.\n"). -spec set_certificate(telega_builder(AGVM, AGVN), telega@model@types:file()) -> telega_builder(AGVM, AGVN). set_certificate(Builder, Cert) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), {some, Cert}, erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 230). ?DOC(" Set a custom API client.\n"). -spec set_api_client( telega_builder(AGVS, AGVT), telega@client:telegram_client() ) -> telega_builder(AGVS, AGVT). set_api_client(Builder, Client) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), {some, Client}, erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 238). ?DOC(" Set polling configuration for the supervised polling worker.\n"). -spec with_polling_config( telega_builder(AGVY, AGVZ), integer(), integer(), integer() ) -> telega_builder(AGVY, AGVZ). with_polling_config(Builder, Timeout, Limit, Poll_interval) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), {some, Timeout}, {some, Limit}, {some, Poll_interval}, erlang:element(16, Builder), erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 253). ?DOC(" Set a callback for when polling stops due to errors.\n"). -spec with_polling_on_stop( telega_builder(AGWE, AGWF), fun((telega@error:telega_error()) -> nil) ) -> telega_builder(AGWE, AGWF). with_polling_on_stop(Builder, On_stop) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), {some, On_stop}, erlang:element(17, Builder), erlang:element(18, Builder), erlang:element(19, Builder)}. -file("src/telega.gleam", 265). ?DOC( " Configure the chat instance factory supervisor.\n" "\n" " - `restart_tolerance_intensity` — max restarts within the period (default: 5)\n" " - `restart_tolerance_period` — period in seconds (default: 10)\n" " - `init_timeout` — chat instance init timeout in ms (default: 10 000)\n" ). -spec with_chat_config( telega_builder(AGWK, AGWL), integer(), integer(), integer() ) -> telega_builder(AGWK, AGWL). with_chat_config(Builder, Intensity, Period, Timeout) -> {telega_builder, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), erlang:element(7, Builder), erlang:element(8, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(12, Builder), erlang:element(13, Builder), erlang:element(14, Builder), erlang:element(15, Builder), erlang:element(16, Builder), {some, Intensity}, {some, Period}, {some, Timeout}}. -file("src/telega.gleam", 280). ?DOC(" Set nil session for the bot.\n"). -spec with_nil_session(telega_builder(nil, AGWQ)) -> telega_builder(nil, AGWQ). with_nil_session(Builder) -> _pipe = Builder, with_session_settings( _pipe, {session_settings, fun(_, _) -> {ok, nil} end, fun(_) -> {ok, none} end, fun() -> nil end} ). -file("src/telega.gleam", 485). ?DOC( " Handle an update.\n" "\n" " This function is useful when you want to handle updates in your own way.\n" ). -spec handle_update(telega(any(), any()), telega@model@types:update()) -> boolean(). handle_update(Telega, Raw_update) -> Update = telega@update:raw_to_update(Raw_update), telega@bot:handle_update(erlang:element(4, Telega), Update). -file("src/telega.gleam", 491). ?DOC(" Get the bot's information.\n"). -spec get_me(telega(any(), any())) -> telega@model@types:user(). get_me(Telega) -> erlang:element(3, Telega). -file("src/telega.gleam", 496). ?DOC(" Get session for the current context.\n"). -spec get_session(telega@bot:context(AGYA, any())) -> AGYA. get_session(Ctx) -> erlang:element(5, Ctx). -file("src/telega.gleam", 501). ?DOC(" Add logging context to the current context.\n"). -spec log_context( telega@bot:context(AGYE, AGYF), binary(), fun((telega@bot:context(AGYE, AGYF)) -> {ok, telega@bot:context(AGYE, AGYF)} | {error, AGYF}) ) -> {ok, telega@bot:context(AGYE, AGYF)} | {error, AGYF}. log_context(Ctx, Prefix, Fun) -> Ctx_with_log = {context, erlang:element(2, Ctx), erlang:element(3, Ctx), erlang:element(4, Ctx), erlang:element(5, Ctx), erlang:element(6, Ctx), erlang:element(7, Ctx), {some, Prefix}, erlang:element(9, Ctx)}, Fun(Ctx_with_log). -file("src/telega.gleam", 511). ?DOC(" Context helpers for logging\n"). -spec log_info(telega@bot:context(any(), any()), binary()) -> nil. log_info(Ctx, Message) -> case erlang:element(8, Ctx) of {some, Prefix} -> telega@internal@log:info_d(Prefix, Message); none -> telega@internal@log:info(Message) end. -file("src/telega.gleam", 518). -spec log_error(telega@bot:context(any(), any()), binary()) -> nil. log_error(Ctx, Message) -> case erlang:element(8, Ctx) of {some, Prefix} -> telega@internal@log:error_d(Prefix, Message); none -> telega@internal@log:error(Message) end. -file("src/telega.gleam", 529). ?DOC( " Pauses the current chat actor's handler and waits for any update.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_any( telega@bot:context(AGZC, AGZD), gleam@option:option(telega@bot:handler(AGZC, AGZD)), gleam@option:option(integer()), fun((telega@bot:context(AGZC, AGZD), telega@update:update()) -> {ok, telega@bot:context(AGZC, AGZD)} | {error, AGZD}) ) -> {ok, telega@bot:context(AGZC, AGZD)} | {error, AGZD}. wait_any(Ctx, Handle_else, Timeout, Handler) -> telega@bot:wait_handler(Ctx, {handle_all, Handler}, Handle_else, Timeout). -file("src/telega.gleam", 548). ?DOC( " Pauses the current chat actor's handler and waits for a specific command.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_command( telega@bot:context(AGZU, AGZV), binary(), gleam@option:option(telega@bot:handler(AGZU, AGZV)), gleam@option:option(integer()), fun((telega@bot:context(AGZU, AGZV), telega@update:command()) -> {ok, telega@bot:context(AGZU, AGZV)} | {error, AGZV}) ) -> {ok, telega@bot:context(AGZU, AGZV)} | {error, AGZV}. wait_command(Ctx, Command, Handle_else, Timeout, Continue) -> telega@bot:wait_handler( Ctx, {handle_command, Command, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 568). ?DOC( " Pauses the current chat actor's handler and waits for one of the specified commands.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_commands( telega@bot:context(AHAM, AHAN), list(binary()), gleam@option:option(telega@bot:handler(AHAM, AHAN)), gleam@option:option(integer()), fun((telega@bot:context(AHAM, AHAN), telega@update:command()) -> {ok, telega@bot:context(AHAM, AHAN)} | {error, AHAN}) ) -> {ok, telega@bot:context(AHAM, AHAN)} | {error, AHAN}. wait_commands(Ctx, Commands, Handle_else, Timeout, Continue) -> telega@bot:wait_handler( Ctx, {handle_commands, Commands, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 588). ?DOC( " Pauses the current chat actor's handler and waits for a text message.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_text( telega@bot:context(AHBF, AHBG), gleam@option:option(telega@bot:handler(AHBF, AHBG)), gleam@option:option(integer()), fun((telega@bot:context(AHBF, AHBG), binary()) -> {ok, telega@bot:context(AHBF, AHBG)} | {error, AHBG}) ) -> {ok, telega@bot:context(AHBF, AHBG)} | {error, AHBG}. wait_text(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler(Ctx, {handle_text, Continue}, Handle_else, Timeout). -file("src/telega.gleam", 607). ?DOC( " Pauses the current chat actor's handler and waits for a message that matches the given `Hears`.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_hears( telega@bot:context(AHBX, AHBY), telega@bot:hears(), gleam@option:option(telega@bot:handler(AHBX, AHBY)), gleam@option:option(integer()), fun((telega@bot:context(AHBX, AHBY), binary()) -> {ok, telega@bot:context(AHBX, AHBY)} | {error, AHBY}) ) -> {ok, telega@bot:context(AHBX, AHBY)} | {error, AHBY}. wait_hears(Ctx, Hears, Handle_else, Timeout, Continue) -> telega@bot:wait_handler( Ctx, {handle_hears, Hears, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 627). ?DOC( " Pauses the current chat actor's handler and waits for any message.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_message( telega@bot:context(AHCP, AHCQ), gleam@option:option(telega@bot:handler(AHCP, AHCQ)), gleam@option:option(integer()), fun((telega@bot:context(AHCP, AHCQ), telega@model@types:message()) -> {ok, telega@bot:context(AHCP, AHCQ)} | {error, AHCQ}) ) -> {ok, telega@bot:context(AHCP, AHCQ)} | {error, AHCQ}. wait_message(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler( Ctx, {handle_message, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 646). ?DOC( " Pauses the current chat actor's handler and waits for a callback query.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_callback_query( telega@bot:context(AHDH, AHDI), gleam@option:option(telega@bot:callback_query_filter()), gleam@option:option(telega@bot:handler(AHDH, AHDI)), gleam@option:option(integer()), fun((telega@bot:context(AHDH, AHDI), binary(), binary()) -> {ok, telega@bot:context(AHDH, AHDI)} | {error, AHDI}) ) -> {ok, telega@bot:context(AHDH, AHDI)} | {error, AHDI}. wait_callback_query(Ctx, Filter, Handle_else, Timeout, Continue) -> Default_re@1 = case gleam@regexp:from_string(<<".*"/utf8>>) of {ok, Default_re} -> Default_re; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"telega"/utf8>>, function => <<"wait_callback_query"/utf8>>, line => 654, value => _assert_fail, start => 20330, 'end' => 20382, pattern_start => 20341, pattern_end => 20355}) end, Filter_value = gleam@option:unwrap( Filter, {callback_query_filter, Default_re@1} ), telega@bot:wait_handler( Ctx, {handle_callback_query, Filter_value, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 669). ?DOC( " Pauses the current chat actor's handler and waits for an audio message.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_audio( telega@bot:context(AHEA, AHEB), gleam@option:option(telega@bot:handler(AHEA, AHEB)), gleam@option:option(integer()), fun((telega@bot:context(AHEA, AHEB), telega@model@types:audio()) -> {ok, telega@bot:context(AHEA, AHEB)} | {error, AHEB}) ) -> {ok, telega@bot:context(AHEA, AHEB)} | {error, AHEB}. wait_audio(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler(Ctx, {handle_audio, Continue}, Handle_else, Timeout). -file("src/telega.gleam", 688). ?DOC( " Pauses the current chat actor's handler and waits for a video message.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_video( telega@bot:context(AHES, AHET), gleam@option:option(telega@bot:handler(AHES, AHET)), gleam@option:option(integer()), fun((telega@bot:context(AHES, AHET), telega@model@types:video()) -> {ok, telega@bot:context(AHES, AHET)} | {error, AHET}) ) -> {ok, telega@bot:context(AHES, AHET)} | {error, AHET}. wait_video(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler(Ctx, {handle_video, Continue}, Handle_else, Timeout). -file("src/telega.gleam", 707). ?DOC( " Pauses the current chat actor's handler and waits for a voice message.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_voice( telega@bot:context(AHFK, AHFL), gleam@option:option(telega@bot:handler(AHFK, AHFL)), gleam@option:option(integer()), fun((telega@bot:context(AHFK, AHFL), telega@model@types:voice()) -> {ok, telega@bot:context(AHFK, AHFL)} | {error, AHFL}) ) -> {ok, telega@bot:context(AHFK, AHFL)} | {error, AHFL}. wait_voice(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler(Ctx, {handle_voice, Continue}, Handle_else, Timeout). -file("src/telega.gleam", 726). ?DOC( " Pauses the current chat actor's handler and waits for photos.\n" " Other chats and users continue to be handled concurrently.\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_photos( telega@bot:context(AHGC, AHGD), gleam@option:option(telega@bot:handler(AHGC, AHGD)), gleam@option:option(integer()), fun((telega@bot:context(AHGC, AHGD), list(telega@model@types:photo_size())) -> {ok, telega@bot:context(AHGC, AHGD)} | {error, AHGD}) ) -> {ok, telega@bot:context(AHGC, AHGD)} | {error, AHGD}. wait_photos(Ctx, Handle_else, Timeout, Continue) -> telega@bot:wait_handler( Ctx, {handle_photos, Continue}, Handle_else, Timeout ). -file("src/telega.gleam", 764). ?DOC( " Wait for a number with validation.\n" "\n" " This function waits for user to send text that can be parsed as an integer,\n" " with optional min/max validation.\n" "\n" " If validation fails and `or` handler is provided, it will be called.\n" " Otherwise, the function will keep waiting for valid input.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " use ctx, age <- wait_number(\n" " ctx,\n" " min: Some(0),\n" " max: Some(120),\n" " or: Some(bot.HandleText(fn(ctx, invalid) {\n" " reply.with_text(ctx, \"Please enter age between 0 and 120\")\n" " })),\n" " timeout: None,\n" " )\n" " ```\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_number( telega@bot:context(AHGV, AHGW), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(telega@bot:handler(AHGV, AHGW)), gleam@option:option(integer()), fun((telega@bot:context(AHGV, AHGW), integer()) -> {ok, telega@bot:context(AHGV, AHGW)} | {error, AHGW}) ) -> {ok, telega@bot:context(AHGV, AHGW)} | {error, AHGW}. wait_number(Ctx, Min, Max, Handle_else, Timeout, Continue) -> Validation_handler = {handle_text, fun(Ctx@1, Text) -> case gleam_stdlib:parse_int(Text) of {ok, Number} -> Min_ok = case Min of {some, Min_val} -> Number >= Min_val; none -> true end, Max_ok = case Max of {some, Max_val} -> Number =< Max_val; none -> true end, case Min_ok andalso Max_ok of true -> Continue(Ctx@1, Number); false -> wait_number( Ctx@1, Min, Max, Handle_else, Timeout, Continue ) end; {error, _} -> wait_number(Ctx@1, Min, Max, Handle_else, Timeout, Continue) end end}, telega@bot:wait_handler(Ctx, Validation_handler, Handle_else, Timeout). -file("src/telega.gleam", 823). ?DOC( " Wait for email with validation.\n" "\n" " This function waits for user to send text that matches email pattern.\n" "\n" " If validation fails and `or` handler is provided, it will be called.\n" " Otherwise, the function will keep waiting for valid input.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " use ctx, email <- wait_email(\n" " ctx,\n" " or: Some(bot.HandleText(fn(ctx, invalid) {\n" " reply.with_text(ctx, \"Invalid email format. Try again.\")\n" " })),\n" " timeout: None,\n" " )\n" " ```\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_email( telega@bot:context(AHHP, AHHQ), gleam@option:option(telega@bot:handler(AHHP, AHHQ)), gleam@option:option(integer()), fun((telega@bot:context(AHHP, AHHQ), binary()) -> {ok, telega@bot:context(AHHP, AHHQ)} | {error, AHHQ}) ) -> {ok, telega@bot:context(AHHP, AHHQ)} | {error, AHHQ}. wait_email(Ctx, Handle_else, Timeout, Continue) -> Email_pattern = <<"^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"/utf8>>, Validation_handler = {handle_text, fun(Ctx@1, Text) -> case gleam@regexp:from_string(Email_pattern) of {ok, Re} -> case gleam@regexp:check(Re, Text) of true -> Continue(Ctx@1, Text); false -> wait_email(Ctx@1, Handle_else, Timeout, Continue) end; {error, _} -> Continue(Ctx@1, Text) end end}, telega@bot:wait_handler(Ctx, Validation_handler, Handle_else, Timeout). -file("src/telega.gleam", 966). ?DOC( " Wait for update matching custom filter.\n" "\n" " This function waits for any update that passes the provided filter function.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " use ctx, photo_update <- wait_for(\n" " ctx,\n" " filter: fn(upd) {\n" " case upd {\n" " update.PhotoUpdate(..) -> True\n" " _ -> False\n" " }\n" " },\n" " or: Some(bot.HandleAll(fn(ctx, wrong_update) {\n" " reply.with_text(ctx, \"Please send a photo\")\n" " })),\n" " timeout: Some(60_000),\n" " )\n" " ```\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_for( telega@bot:context(AHJB, AHJC), fun((telega@update:update()) -> boolean()), gleam@option:option(telega@bot:handler(AHJB, AHJC)), gleam@option:option(integer()), fun((telega@bot:context(AHJB, AHJC), telega@update:update()) -> {ok, telega@bot:context(AHJB, AHJC)} | {error, AHJC}) ) -> {ok, telega@bot:context(AHJB, AHJC)} | {error, AHJC}. wait_for(Ctx, Filter, Handle_else, Timeout, Continue) -> Filter_handler = {handle_all, fun(Ctx@1, Upd) -> case Filter(Upd) of true -> Continue(Ctx@1, Upd); false -> wait_for(Ctx@1, Filter, Handle_else, Timeout, Continue) end end}, telega@bot:wait_handler(Ctx, Filter_handler, Handle_else, Timeout). -file("src/telega.gleam", 987). ?DOC( " Start polling with default configuration for a Telega instance.\n" " This is useful when you want to manually start polling outside the supervision tree.\n" ). -spec start_polling_default(telega(any(), any())) -> {ok, telega@polling:poller()} | {error, telega@error:telega_error()}. start_polling_default(Telega) -> telega@polling:start_polling_default( erlang:element(5, erlang:element(2, Telega)), erlang:element(4, Telega) ). -file("src/telega.gleam", 998). ?DOC( " Graceful shutdown — stops supervisor, cascading to all children.\n" " Children are stopped in reverse start order: polling → bot → chat_factory.\n" ). -spec shutdown(telega(any(), any())) -> nil. shutdown(Telega) -> gleam@erlang@process:send_abnormal_exit( erlang:element(5, Telega), erlang:binary_to_atom(<<"shutdown"/utf8>>) ). -file("src/telega.gleam", 1003). ?DOC(" Get the supervisor PID for the running bot instance.\n"). -spec get_supervisor_pid(telega(any(), any())) -> gleam@erlang@process:pid_(). get_supervisor_pid(Telega) -> erlang:element(5, Telega). -file("src/telega.gleam", 1043). -spec generate_registry_name(binary()) -> binary(). generate_registry_name(Token) -> _pipe = Token, _pipe@1 = gleam@string:slice(_pipe, 0, 8), gleam@string:append( _pipe@1, <<"_"/utf8, (erlang:integer_to_binary(gleam@int:random(1000000)))/binary>> ). -file("src/telega.gleam", 1050). -spec list_at(list(AHKM), integer()) -> {ok, AHKM} | {error, nil}. list_at(List, Index) -> case {List, Index} of {[], _} -> {error, nil}; {[Head | _], 0} -> {ok, Head}; {[_ | Tail], N} -> list_at(Tail, N - 1) end. -file("src/telega.gleam", 868). ?DOC( " Wait for user choice from inline keyboard.\n" "\n" " This function creates an inline keyboard with provided options\n" " and waits for user to select one.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " use ctx, color <- wait_choice(\n" " ctx,\n" " [\n" " #(\"🔴 Red\", Red),\n" " #(\"🔵 Blue\", Blue),\n" " #(\"🟢 Green\", Green),\n" " ],\n" " or: None,\n" " timeout: None,\n" " )\n" " ```\n" "\n" " See [conversation](/docs/conversation)\n" ). -spec wait_choice( telega@bot:context(AHIH, AHII), list({binary(), AHIL}), gleam@option:option(telega@bot:handler(AHIH, AHII)), gleam@option:option(integer()), fun((telega@bot:context(AHIH, AHII), AHIL) -> {ok, telega@bot:context(AHIH, AHII)} | {error, AHII}) ) -> {ok, telega@bot:context(AHIH, AHII)} | {error, AHII}. wait_choice(Ctx, Options, Handle_else, Timeout, Continue) -> Buttons = begin _pipe = Options, gleam@list:index_map( _pipe, fun(Opt, Idx) -> {Label, _} = Opt, Callback_data = erlang:integer_to_binary(Idx), {inline_keyboard_button, Label, none, none, none, {some, Callback_data}, none, none, none, none, none, none, none, none} end ) end, Keyboard = {inline_keyboard_markup, [Buttons]}, Send_params = {send_message_parameters, none, {int, erlang:element(3, erlang:element(3, Ctx))}, none, <<""/utf8>>, none, none, none, none, none, none, none, none, {some, {send_message_reply_inline_keyboard_markup_parameters, Keyboard}}}, _ = telega@api:send_message( erlang:element(5, erlang:element(4, Ctx)), Send_params ), wait_callback_query( Ctx, none, Handle_else, Timeout, fun(Ctx@1, Data, _) -> case gleam_stdlib:parse_int(Data) of {ok, Idx@1} -> case list_at(Options, Idx@1) of {ok, {_, Value}} -> Continue(Ctx@1, Value); {error, _} -> wait_choice( Ctx@1, Options, Handle_else, Timeout, Continue ) end; {error, _} -> wait_choice(Ctx@1, Options, Handle_else, Timeout, Continue) end end ). -file("src/telega.gleam", 1015). -spec build_chat_factory_spec(telega_builder(any(), any())) -> {gleam@otp@supervision:child_specification(gleam@otp@factory_supervisor:supervisor(telega@bot:chat_instance_args(AINH, AINI), gleam@erlang@process:subject(telega@bot:chat_instance_message(AINH, AINI)))), gleam@erlang@process:name(gleam@otp@factory_supervisor:message(telega@bot:chat_instance_args(AINH, AINI), gleam@erlang@process:subject(telega@bot:chat_instance_message(AINH, AINI))))}. build_chat_factory_spec(Builder) -> Intensity = gleam@option:unwrap(erlang:element(17, Builder), 5), Period = gleam@option:unwrap(erlang:element(18, Builder), 10), Timeout = gleam@option:unwrap(erlang:element(19, Builder), 10000), Name = gleam_erlang_ffi:new_name(<<"telega_chat_factory"/utf8>>), Spec = begin _pipe = gleam@otp@factory_supervisor:worker_child( fun telega@bot:start_chat_instance/1 ), _pipe@1 = gleam@otp@factory_supervisor:named(_pipe, Name), _pipe@2 = gleam@otp@factory_supervisor:restart_strategy( _pipe@1, transient ), _pipe@3 = gleam@otp@factory_supervisor:restart_tolerance( _pipe@2, Intensity, Period ), _pipe@4 = gleam@otp@factory_supervisor:timeout(_pipe@3, Timeout), gleam@otp@factory_supervisor:supervised(_pipe@4) end, {Spec, Name}. -file("src/telega.gleam", 309). ?DOC(" Initialize the bot for webhook mode with a supervision tree.\n"). -spec init(telega_builder(AGXC, AGXD)) -> {ok, telega(AGXC, AGXD)} | {error, telega@error:telega_error()}. init(Builder) -> Api_client = gleam@option:unwrap( erlang:element(7, Builder), erlang:element(5, erlang:element(2, Builder)) ), gleam@result:'try'( telega@api:set_webhook( Api_client, {set_webhook_parameters, <<<<(erlang:element(2, erlang:element(2, Builder)))/binary, "/"/utf8>>/binary, (erlang:element(3, erlang:element(2, Builder)))/binary>>, erlang:element(12, Builder), erlang:element(9, Builder), erlang:element(10, Builder), erlang:element(11, Builder), erlang:element(8, Builder), {some, erlang:element(4, erlang:element(2, Builder))}} ), fun(Is_ok) -> gleam@bool:guard( not Is_ok, {error, set_webhook_error}, fun() -> gleam@result:'try'( telega@api:get_me(Api_client), fun(Bot_info) -> Session_settings = gleam@option:to_result( erlang:element(4, Builder), no_session_settings_error ), gleam@result:'try'( Session_settings, fun(Session_settings@1) -> Router = gleam@option:to_result( erlang:element(3, Builder), {router_error, <<"Router is required. Use with_router() to set a router."/utf8>>} ), gleam@result:'try'( Router, fun(Router@1) -> Router_handler = fun(Ctx, Upd) -> telega@router:handle( Router@1, Ctx, Upd ) end, Catch_handler = gleam@option:unwrap( erlang:element(5, Builder), fun(_, Err) -> {error, Err} end ), Config = begin _record = erlang:element( 2, Builder ), {config, erlang:element(2, _record), erlang:element(3, _record), erlang:element(4, _record), Api_client} end, Registry_name = generate_registry_name( telega@client:get_token( erlang:element(5, Config) ) ), gleam@result:'try'( telega@internal@registry:start( Registry_name ), fun(Registry) -> {Chat_factory_spec, Chat_factory_name} = build_chat_factory_spec( Builder ), Bot_name = gleam_erlang_ffi:new_name( <<"telega_bot"/utf8>> ), Bot_subject = gleam@erlang@process:named_subject( Bot_name ), Chat_factory_ref = gleam@otp@factory_supervisor:get_by_name( Chat_factory_name ), Bot_spec = begin _pipe = gleam@otp@supervision:worker( fun() -> telega@bot:start( Registry, Config, Bot_info, Router_handler, Session_settings@1, Catch_handler, Chat_factory_ref, {some, Bot_name} ) end ), gleam@otp@supervision:restart( _pipe, permanent ) end, gleam@result:'try'( begin _pipe@1 = gleam@otp@static_supervisor:new( one_for_one ), _pipe@2 = gleam@otp@static_supervisor:add( _pipe@1, Chat_factory_spec ), _pipe@3 = gleam@otp@static_supervisor:add( _pipe@2, Bot_spec ), _pipe@4 = gleam@otp@static_supervisor:start( _pipe@3 ), gleam@result:map_error( _pipe@4, fun(Field@0) -> {supervisor_start_error, Field@0} end ) end, fun(Sup_started) -> {ok, {telega, Config, Bot_info, Bot_subject, erlang:element( 2, Sup_started )}} end ) end ) end ) end ) end ) end ) end ). -file("src/telega.gleam", 387). ?DOC( " Initialize the bot for long polling with a supervision tree.\n" " Includes a supervised polling worker that auto-starts.\n" ). -spec init_for_polling(telega_builder(AGXK, AGXL)) -> {ok, telega(AGXK, AGXL)} | {error, telega@error:telega_error()}. init_for_polling(Builder) -> Api_client = gleam@option:unwrap( erlang:element(7, Builder), erlang:element(5, erlang:element(2, Builder)) ), gleam@result:'try'( begin _pipe = telega@api:get_me(Api_client), gleam@result:map_error(_pipe, fun(Err) -> case Err of {telegram_api_error, 404, _} -> {telegram_api_error, 404, <<"Bot not found. Please check that your BOT_TOKEN is valid and the bot exists. Get a valid token from @BotFather on Telegram."/utf8>>}; {telegram_api_error, 401, _} -> {telegram_api_error, 401, <<"Unauthorized. Your bot token is invalid. Please get a valid token from @BotFather on Telegram."/utf8>>}; _ -> Err end end) end, fun(Bot_info) -> Session_settings = gleam@option:to_result( erlang:element(4, Builder), no_session_settings_error ), gleam@result:'try'( Session_settings, fun(Session_settings@1) -> Router = gleam@option:to_result( erlang:element(3, Builder), {actor_error, <<"Router is required. Use with_router() to set a router."/utf8>>} ), gleam@result:'try'( Router, fun(Router@1) -> Router_handler = fun(Ctx, Upd) -> telega@router:handle(Router@1, Ctx, Upd) end, Catch_handler = gleam@option:unwrap( erlang:element(5, Builder), fun(_, Err@1) -> {error, Err@1} end ), Config = begin _record = erlang:element(2, Builder), {config, erlang:element(2, _record), erlang:element(3, _record), erlang:element(4, _record), Api_client} end, Registry_name = generate_registry_name( telega@client:get_token( erlang:element(5, Config) ) ), gleam@result:'try'( telega@internal@registry:start(Registry_name), fun(Registry) -> {Chat_factory_spec, Chat_factory_name} = build_chat_factory_spec( Builder ), Bot_name = gleam_erlang_ffi:new_name( <<"telega_bot"/utf8>> ), Bot_subject = gleam@erlang@process:named_subject( Bot_name ), Chat_factory_ref = gleam@otp@factory_supervisor:get_by_name( Chat_factory_name ), Bot_spec = begin _pipe@1 = gleam@otp@supervision:worker( fun() -> telega@bot:start( Registry, Config, Bot_info, Router_handler, Session_settings@1, Catch_handler, Chat_factory_ref, {some, Bot_name} ) end ), gleam@otp@supervision:restart( _pipe@1, permanent ) end, Polling_timeout = gleam@option:unwrap( erlang:element(13, Builder), 30 ), Polling_limit = gleam@option:unwrap( erlang:element(14, Builder), 100 ), Polling_interval = gleam@option:unwrap( erlang:element(15, Builder), 1000 ), Allowed_updates = gleam@option:unwrap( erlang:element(11, Builder), [] ), Polling_spec = telega@polling:supervised( Api_client, Bot_subject, Polling_timeout, Polling_limit, Allowed_updates, Polling_interval, erlang:element(16, Builder) ), gleam@result:'try'( begin _pipe@2 = gleam@otp@static_supervisor:new( one_for_one ), _pipe@3 = gleam@otp@static_supervisor:add( _pipe@2, Chat_factory_spec ), _pipe@4 = gleam@otp@static_supervisor:add( _pipe@3, Bot_spec ), _pipe@5 = gleam@otp@static_supervisor:add( _pipe@4, Polling_spec ), _pipe@6 = gleam@otp@static_supervisor:start( _pipe@5 ), gleam@result:map_error( _pipe@6, fun(Field@0) -> {supervisor_start_error, Field@0} end ) end, fun(Sup_started) -> {ok, {telega, Config, Bot_info, Bot_subject, erlang:element( 2, Sup_started )}} end ) end ) end ) end ) end ). -file("src/telega.gleam", 294). ?DOC(" Initialize the bot for long polling with nil session.\n"). -spec init_for_polling_nil_session(telega_builder(nil, AGWV)) -> {ok, telega(nil, AGWV)} | {error, telega@error:telega_error()}. init_for_polling_nil_session(Builder) -> _pipe = Builder, _pipe@1 = with_session_settings( _pipe, {session_settings, fun(_, _) -> {ok, nil} end, fun(_) -> {ok, none} end, fun() -> nil end} ), init_for_polling(_pipe@1).