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, 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 => <<?FILEPATH/utf8>>,
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).