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

Opaque type representing a running poller instance

pub opaque type Poller

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

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 is_running(poller: Poller) -> Bool

Check if poller is running

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(poller: Poller) -> Nil

Stop polling

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

Search Document