Skip to content

zhyu/nadia

Repository files navigation

Nadia

Elixir CI Module Version Hex Docs Total Download License Last Updated

Nadia is an Elixir client for the Telegram Bot API and Telegraph API. It combines complete Bot API method coverage with small, explicit helpers for building bots in an OTP application.

  • Call every Telegram Bot API method through Nadia.
  • Receive updates with supervised polling or framework-neutral webhooks.
  • Route commands, text, and callback queries without a macro DSL.
  • Use explicit clients for multi-bot applications and fake HTTP adapters for offline tests.
  • Upload paths, bounded iodata, and known-size streams with explicit Nadia.InputFile values, including nested media attachments.
  • Build current outgoing media, poll options, rich messages, and story areas with fixed-shape typed helpers while retaining raw compatibility inputs.
  • Stream Telegram downloads to files under a mandatory byte limit, without returning token-bearing URLs.
  • Add optional conversation state without requiring a persistence dependency.

Installation

Nadia requires Elixir 1.20 or later and Erlang/OTP 27 or later.

Add :nadia to mix.exs:

def deps do
  [
    {:nadia, "~> 1.6"}
  ]
end

Then run:

mix deps.get

Quick Start

Create a bot with @BotFather. Read its token at runtime instead of committing it to application configuration:

# config/runtime.exs
import Config

config :nadia,
  token: {:system, "TELEGRAM_BOT_TOKEN"}

Direct Bot API calls return {:ok, result} or {:error, %Nadia.Model.Error{}}:

case Nadia.get_me() do
  {:ok, bot} -> IO.puts("Connected as @#{bot.username}")
  {:error, error} -> IO.warn("Telegram error: #{inspect(error.reason)}")
end

Nadia.send_message(chat_id, "Hello from Nadia")

For an OTP bot, generate a handler and offline test:

mix nadia.gen.bot MyApp.Bot --polling

Then supervise long polling:

children = [
  {Nadia.Polling,
   handler: MyApp.Bot,
   allowed_updates: ["message"],
   timeout: 30}
]

Run the app with the token in its environment:

TELEGRAM_BOT_TOKEN=123:token mix run --no-halt

The Build Your First Bot guide walks through the complete setup.

Learn By Example

The Examples And Learning Paths page connects Nadia's API reference to complete bot-building tasks.

Build Guide
A generated polling bot Build Your First Bot
Commands and inline buttons Commands And Inline Keyboards
A multi-step conversation Conversation State
Durable conversation state Persistent Session Backends
Media uploads and downloads Media And Files
Rich messages and clickable story areas Rich Messages And Stories
Bounded Telegram retries Errors And Rate Limits
An HTTP endpoint Receive Webhook Updates
Several bot identities Run Multiple Bots
Credential-free tests Test Bot Handlers
A production deployment Production Checklist
Telegraph pages Use The Telegraph API

Tested, copyable handler modules live in the examples directory.

Configuration

The top-level token config is the default client used by calls such as Nadia.get_me/0 and Nadia.send_message/3. Applications with more than one bot can configure named clients:

config :nadia,
  bots: [
    support: [
      token: {:system, "SUPPORT_BOT_TOKEN"},
      recv_timeout: 10
    ],
    alerts: [
      token: {:system, "ALERTS_BOT_TOKEN"}
    ]
  ]
support = Nadia.Client.from_config(:support)
Nadia.send_message(support, support_chat_id, "How can we help?")

See Run Multiple Bots before supervising several pollers; each worker needs a distinct child ID.

Nadia uses Req as its HTTP transport. Optional HTTP or HTTPS proxy settings are passed to Req/Mint:

config :nadia,
  proxy: "http://proxy.example.com:8080",
  proxy_auth: {"user", "password"},
  recv_timeout: 10

Custom Bot API, file, or Telegraph endpoints can be configured with :base_url, :file_base_url, and :graph_base_url. Most applications should use the defaults.

A trusted local Bot API server started in local mode can return absolute file paths instead of remote download paths. Opt into local filesystem copying explicitly:

config :nadia,
  base_url: "http://bot-api.internal/bot",
  file_mode: :local

The path must be accessible in Nadia's filesystem namespace. Leave file_mode: :remote at its default for Telegram's hosted API and for local servers that still use HTTP file downloads.

Testing

Nadia's normal test suite is offline and credential-free:

mix test

The Test Bot Handlers guide shows how application tests can inject a fake Nadia.HTTPClient and assert outgoing requests.

Optional maintainer smoke tests against Telegram are tagged :telegram_live. They require the two-bot environment documented in .env.live.local.example and are run with:

mix test --only telegram_live

Contributing

See the contributing guide for local checks, changelog expectations, Bot API maintenance notes, and the GitHub Actions release process.

API Coverage

Since Nadia 1.0.0, the wrapper covers all 180 official methods in Telegram Bot API 10.1, published on June 11, 2026. Current releases preserve that complete method coverage. Modeled response fields are parsed into Nadia structs; unknown future fields are ignored until Nadia explicitly models them.

Use the Nadia reference for Elixir signatures and the official Telegram Bot API documentation for Telegram's field semantics.

Typed outgoing-content helpers include Nadia.InputMedia, Nadia.InputPaidMedia, Nadia.InputPollMedia, Nadia.InputPollOption, Nadia.InputProfilePhoto, Nadia.InputRichMessage, Nadia.InputRichMessageContent, Nadia.InputTextMessageContent, Nadia.InputInvoiceMessageContent, Nadia.InputLocationMessageContent, Nadia.InputVenueMessageContent, Nadia.InputContactMessageContent, Nadia.InputStoryContent, Nadia.InputSticker, Nadia.LabeledPrice, Nadia.ReactionType, and Nadia.StoryArea. Their constructors reject locally detectable mistakes; raw maps, keyword lists, structs, mixed lists, and pre-encoded JSON remain available as compatibility escape hatches.

License

Copyright (c) 2015 Yu Zhang

Nadia is released under the MIT License.

About

Telegram Bot API Wrapper written in Elixir

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages