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 stop_worker(
worker worker: process.Subject(PollingMessage),
) -> Nil
Stop a supervised polling worker by its subject.
Sends StopPolling, which makes the worker stop fetching new updates after
its current batch. Used by graceful shutdown to halt intake before draining.
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),
name name: process.Name(PollingMessage),
) -> 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