Nadia
View SourceTelegram Bot API Wrapper written in Elixir (document)
API Coverage
As of Nadia 1.0.0, the Telegram Bot API wrapper covers all 180 official methods in Telegram Bot API 10.1, published on June 11, 2026. Nadia keeps response parsing strict: modeled response fields are parsed into Nadia structs, while unknown future fields are ignored until the library explicitly models them.
Installation
Nadia requires Elixir 1.20 or later and Erlang/OTP 27 or later.
Add :nadia to your mix.exs dependencies:
def deps do
[
{:nadia, "~> 1.0"}
]
endAnd run $ mix deps.get.
Configuration
In config/config.exs, add your Telegram Bot token like this
config :nadia,
token: "bot token"You can also add an optional recv_timeout in seconds (defaults to 5s):
config :nadia,
recv_timeout: 10You can also add a proxy support:
config :nadia,
proxy: "http://proxy_host:proxy_port",
proxy_auth: {"user", "password"}Nadia uses Req as its HTTP client. Proxy configuration supports HTTP and HTTPS proxies accepted by Req/Mint; hackney-specific SOCKS options are no longer supported.
You can also configure the the base url for the api if you need to for some reason:
config :nadia,
# Telegram API. Default: https://api.telegram.org/bot
base_url: "http://my-own-endpoint.com/whatever/",
# Telegram Graph API. Default: https://api.telegra.ph
graph_base_url: "http://my-own-endpoint.com/whatever/"Environment variables may be used as well:
config :nadia,
token: {:system, "ENVVAR_WITH_MYAPP_TOKEN", "default_value_if_needed"}For applications that need more than one bot, configure named bots and build explicit clients from those names:
config :nadia,
bots: [
support: [
token: {:system, "SUPPORT_BOT_TOKEN"},
recv_timeout: 10
],
alerts: [
token: {:system, "ALERTS_BOT_TOKEN"},
proxy: "http://proxy_host:proxy_port"
]
]support_bot = Nadia.Client.from_config(:support)
alerts_bot = Nadia.Client.from_config(:alerts)
Nadia.send_message(support_bot, support_chat_id, "How can we help?")
Nadia.send_message(alerts_bot, alerts_chat_id, "Alert triggered")The top-level :token configuration remains the default client for existing
calls such as Nadia.get_me() and Nadia.send_message(chat_id, text).
Usage
get_me
iex> Nadia.get_me
{:ok,
%Nadia.Model.User{first_name: "Nadia", id: 666, last_name: nil,
username: "nadia_bot"}}get_updates
iex> Nadia.get_updates limit: 5
{:ok, []}
iex> {:ok,
[%Nadia.Model.Update{callback_query: nil, chosen_inline_result: nil,
edited_message: nil, inline_query: nil,
message: %Nadia.Model.Message{audio: nil, caption: nil,
channel_chat_created: nil,
chat: %Nadia.Model.Chat{first_name: "Nadia", id: 123,
last_name: "TheBot", title: nil, type: "private", username: "nadia_the_bot"},
contact: nil, date: 1471208260, delete_chat_photo: nil, document: nil,
edit_date: nil, entities: nil, forward_date: nil, forward_from: nil,
forward_from_chat: nil,
from: %Nadia.Model.User{first_name: "Nadia", id: 123,
last_name: "TheBot", username: "nadia_the_bot"}, group_chat_created: nil,
left_chat_member: nil, location: nil, message_id: 543,
migrate_from_chat_id: nil, migrate_to_chat_id: nil, new_chat_member: nil,
new_chat_photo: [], new_chat_title: nil, photo: [], pinned_message: nil,
reply_to_message: nil, sticker: nil, supergroup_chat_created: nil,
text: "rew", venue: nil, video: nil, voice: nil}, update_id: 98765}]}send_message
iex> case Nadia.send_message(tlg_id, "The message text goes here") do
{:ok, _result} ->
:ok
{:error, %Nadia.Model.Error{reason: "Please wait a little"}} ->
:wait
end
:okRefer to Nadia document and Telegram Bot API document for more details.
Testing
The default test suite is offline and credential-free:
mix test
Optional live Telegram smoke tests are tagged with :telegram_live and are not
run by default:
mix test --only telegram_live
Live tests require two bots with Bot-to-Bot Communication Mode enabled in BotFather. Configure credentials by copying the committed seed file to the ignored local env file, then edit the local file:
cp .env.live.local.example .env.live.local
chmod 600 .env.live.local
${EDITOR:-vi} .env.live.local
The local .env.live.local file should define:
export NADIA_LIVE_BOT_A_TOKEN="123:bot-a-token"
export NADIA_LIVE_BOT_A_USERNAME="bot_a_username"
export NADIA_LIVE_BOT_B_TOKEN="456:bot-b-token"
export NADIA_LIVE_BOT_B_USERNAME="bot_b_username"
Then source the local file and run the live suite from the same shell:
source .env.live.local
mix test --only telegram_live
Set NADIA_LIVE_API_ENV=test in .env.live.local to route live smoke tests
through Telegram's Bot API test environment.
Copyright and License
Copyright (c) 2015 Yu Zhang
This library licensed under the MIT license.