telega/polling
Long polling implementation for Telegram Bot API.
This module provides long polling as an alternative to webhooks for receiving updates. A polling worker actor continuously fetches updates from Telegram and dispatches them to the bot’s message handlers.
Supervised mode (recommended)
When using telega.init_for_polling(), the polling worker is automatically started
inside the supervision tree as a Permanent child. No manual setup is needed:
let assert Ok(_bot) =
telega.new_for_polling(token: "BOT_TOKEN")
|> telega.with_router(router)
|> telega.init_for_polling_nil_session()
process.sleep_forever()
Use telega.with_polling_config() on the builder to customize timeout, limit,
and poll interval before calling init_for_polling().
Manual mode
For advanced use cases (custom offsets, separate lifecycle management), start polling manually:
let assert Ok(poller) =
polling.start_polling_default(
client: telega.get_api_config(bot),
bot: telega.get_bot_subject_internal(bot),
)
Error handling
The polling worker uses exponential backoff for transient errors (network issues,
rate limits, server errors). Critical errors (invalid token, bot deleted, or
10+ consecutive failures) stop polling and invoke the optional on_stop callback.
Types
Status of the poller
pub type PollerStatus {
Starting
Running
Stopped
Failed(String)
}
Constructors
-
Starting -
Running -
Stopped -
Failed(String)
Messages for the polling worker actor
pub type PollingMessage {
StartPolling(offset: option.Option(Int))
StopPolling
PollNext(offset: Int)
InjectUpdates(updates: List(types.Update), offset: Int)
SetSelf(subject: process.Subject(PollingMessage))
HandleError(error: error.TelegaError, offset: Int)
}
Constructors
-
StartPolling(offset: option.Option(Int)) -
StopPolling -
PollNext(offset: Int) -
InjectUpdates(updates: List(types.Update), offset: Int) -
SetSelf(subject: process.Subject(PollingMessage)) -
HandleError(error: error.TelegaError, offset: Int)
Values
pub fn calculate_new_offset(
updates: List(types.Update),
current_offset: Int,
) -> Int
Calculate the next offset based on received updates
pub fn get_config_info(
poller: Poller,
) -> #(Int, Int, List(String), Int)
Get the polling configuration metadata
pub fn get_status(poller: Poller) -> PollerStatus
Get the current status of the poller
pub fn start_polling(
client client: client.TelegramClient,
bot bot: process.Subject(bot.BotMessage),
timeout timeout: Int,
limit limit: Int,
allowed_updates allowed_updates: List(String),
poll_interval poll_interval: Int,
) -> Result(Poller, error.TelegaError)
Start polling with the given client and bot subject.
pub fn start_polling_default(
client client: client.TelegramClient,
bot bot: process.Subject(bot.BotMessage),
) -> Result(Poller, error.TelegaError)
Start polling with default configuration.
pub fn start_polling_with_notify(
client client: client.TelegramClient,
bot bot: process.Subject(bot.BotMessage),
timeout timeout: Int,
limit limit: Int,
allowed_updates allowed_updates: List(String),
poll_interval poll_interval: Int,
on_stop on_stop: fn(error.TelegaError) -> Nil,
) -> Result(Poller, error.TelegaError)
Start polling with a notification callback for when polling stops due to errors. The callback will be invoked with the error that caused polling to stop.
pub fn start_polling_with_offset(
client client: client.TelegramClient,
bot bot: process.Subject(bot.BotMessage),
offset offset: Int,
timeout timeout: Int,
limit limit: Int,
allowed_updates allowed_updates: List(String),
poll_interval poll_interval: Int,
) -> Result(Poller, error.TelegaError)
Start polling with a custom offset.
pub fn supervised(
client client: client.TelegramClient,
bot bot: process.Subject(bot.BotMessage),
timeout timeout: Int,
limit limit: Int,
allowed_updates allowed_updates: List(String),
poll_interval poll_interval: Int,
on_stop on_stop: option.Option(fn(error.TelegaError) -> Nil),
) -> supervision.ChildSpecification(
process.Subject(PollingMessage),
)
Create a ChildSpecification for running polling inside a supervision tree.
The polling worker will automatically delete the webhook and start polling.
pub fn wait_finish(poller: Poller) -> Nil
Wait for the poller to finish This function blocks indefinitely until the polling worker stops