Skip to content

A Telegram bot bound to one chat. Send text with send, ask a question with buttons and wait for the answer with ask + waitCallback, or wait for a typed answer with waitReply. Messages are represented as tables with message_id, chat_id, text and date; keep the table returned by send/ask to edit the message or wait for its buttons.

How to get one

  1. Telegram .bot()
  2. TelegramBot
local bot = Telegram.bot(token, chatId)

Returned by

Functions

  • me TelegramUser Asks Telegram who the bot is (getMe) and returns its id, username and first name.
  • send TelegramMessage Sends a text message to the chat and returns the sent message.
  • ask TelegramMessage Sends a message with buttons under it and returns the sent message; pass that table to waitCallback to get the pressed button.
  • edit TelegramMessage Changes the text of a message the bot sent in this chat (only its message_id is used) and returns the updated message.
  • waitCallback string | nil Waits until someone presses a button on the given message (a table returned by ask) and returns the callback_data of that button, or nil when the timeout passes first.
  • waitReply TelegramReply | nil Waits for the next text message sent in the bot's chat and returns it, or nil when the timeout passes.
  • ack self Answers a button press so the button stops showing a loading spinner, optionally with a short notification text.
  • poll TelegramUpdate[] Fetches the new updates the bot has received (messages and button presses from any chat, in order) and marks them as read, so each update is returned once.
  • pollTimeout self Sets how long poll() and the wait functions ask Telegram to hold a request open when nothing new has arrived, in seconds (default 30).
  • close self Closes the HTTP client of this bot.
bot.me()→TelegramUser

Asks Telegram who the bot is (getMe) and returns its id, username and first name. Raises an error when the token is no longer valid.

Returns

TelegramUser A Telegram user or bot.
Fields of TelegramUser
id number
Telegram user id
username string
user name without the @
first_name string
first name (only present in the bot info returned by TelegramBot.me)
All table shapes

Example

print(bot.me().username)
bot.send(text: string)→TelegramMessagebot.send(text: string, parseMode: string)→TelegramMessage

Sends a text message to the chat and returns the sent message. The text is limited by Telegram to 4096 characters. Without a parse mode the text is plain; with "HTML" or "Markdown" (or "MarkdownV2") Telegram formats it, and text that is not valid in that mode is rejected with an error, so escape special characters.

Parameters

text string
Message text, up to 4096 characters
parseMode string optional
"HTML", "Markdown" or "MarkdownV2"; plain text when left out

Returns

TelegramMessage A message that was sent to or received from a Telegram chat.
Fields of TelegramMessage
message_id number
Telegram message id
chat_id number
id of the chat the message belongs to
text string
message text
date number
unix timestamp (seconds) when the message was sent
All table shapes

Example

bot.send("<b>Nightly run</b> finished: 42 passed, 0 failed", "HTML")
bot.ask(text: string, buttons: table)→TelegramMessagebot.ask(text: string, buttons: table, parseMode: string)→TelegramMessage

Sends a message with buttons under it and returns the sent message; pass that table to waitCallback to get the pressed button. Buttons are a list of {label, callback_data} pairs. All buttons are in one row, unless you put the string "---" in the list to start a new row. callback_data is what waitCallback returns (Telegram allows 1 to 64 bytes). Anyone in the chat can press the buttons.

Parameters

text string
Message text
buttons table
Buttons: {{"Label", "callback_data"}, ...}; "---" starts a new row
parseMode string optional
"HTML", "Markdown" or "MarkdownV2"; plain text when left out

Returns

TelegramMessage A message that was sent to or received from a Telegram chat.
Fields of TelegramMessage
message_id number
Telegram message id
chat_id number
id of the chat the message belongs to
text string
message text
date number
unix timestamp (seconds) when the message was sent
All table shapes

Example

local question = bot.ask("Deploy build 1.4.2 to production?", {
{ "Deploy", "yes" }, { "Cancel", "no" },
"---",
{ "Ask me later", "later" },
})
local answer = bot.waitCallback(question, 600)
if answer == "yes" then
bot.edit(question, "Deploying build 1.4.2")
else
bot.edit(question, "Not deployed (" .. tostring(answer) .. ")")
end
bot.edit(message: TelegramMessage, text: string)→TelegramMessagebot.edit(message: TelegramMessage, text: string, parseMode: string)→TelegramMessagebot.edit(message: TelegramMessage, text: string, parseMode: string, buttons: table)→TelegramMessage

Changes the text of a message the bot sent in this chat (only its message_id is used) and returns the updated message. The buttons are removed unless you pass new ones as the fourth argument. Telegram rejects an edit that leaves the text unchanged ("message is not modified").

Parameters

message TelegramMessage
The message table returned by send or ask
text string
New text
parseMode string optional
"HTML", "Markdown" or "MarkdownV2"; plain text when left out
buttons table optional
New buttons in the format of ask; nil removes the buttons

Returns

TelegramMessage A message that was sent to or received from a Telegram chat.
Fields of TelegramMessage
message_id number
Telegram message id
chat_id number
id of the chat the message belongs to
text string
message text
date number
unix timestamp (seconds) when the message was sent
All table shapes

Example

local message = bot.send("Run started")
bot.edit(message, "Run finished: <b>OK</b>", "HTML")
bot.waitCallback(message: TelegramMessage, timeout: number)→string | nilbot.waitCallback(message: TelegramMessage, timeout: number, userId?: number)→string | nil

Waits until someone presses a button on the given message (a table returned by ask) and returns the callback_data of that button, or nil when the timeout passes first. The press is acknowledged to Telegram automatically (no need for ack). Presses on other messages are skipped. With a user id only that user's presses count; a press by anyone else is answered with a "Not allowed" notice and ignored. Without it anyone in the chat can answer. The buttons stay visible after the answer; use edit to remove them. A timeout of 0 returns nil without checking.

Parameters

message TelegramMessage
Message table returned by ask
timeout number
Seconds to wait before giving up
userId number optional
Telegram user id; only this user's button presses are accepted

Returns

string | nil can be nil The callback_data of the pressed button, or nil on timeout

Example

local question = bot.ask("Continue?", { { "Yes", "yes" }, { "No", "no" } })
local answer = bot.waitCallback(question, 300)
if answer == nil then
bot.edit(question, "No answer, aborting")
end
bot.waitReply(timeout: number)→TelegramReply | nilbot.waitReply(timeout: number, userId?: number)→TelegramReply | nil

Waits for the next text message sent in the bot's chat and returns it, or nil when the timeout passes. Messages from other chats and messages without text (photos, stickers) are skipped. Messages that arrived before this call are ignored (they are marked as read), so an old message cannot be mistaken for the answer. With a user id only messages from that user count; anyone else in the chat is ignored.

Parameters

timeout number
Seconds to wait before giving up
userId number optional
Telegram user id; only messages from this user are accepted

Returns

TelegramReply | nil can be nil A text reply received in the chat.
Fields of TelegramReply
message_id number
Telegram message id
chat_id number
id of the chat the reply was sent in
text string
reply text
from TelegramUser
the sender, when known
All table shapes

Example

bot.send("Which environment should I test? (reply with a name)")
local reply = bot.waitReply(300)
if reply then
print("Testing " .. reply.text .. " as requested by " .. (reply.from and reply.from.username or "?"))
end
bot.ack(callbackId: string)→selfbot.ack(callbackId: string, text: string)→selfbot.ack(callbackId: string, text: string, showAlert: boolean)→self

Answers a button press so the button stops showing a loading spinner, optionally with a short notification text. Only needed for callbacks you read yourself with poll(); waitCallback already does it.

Parameters

callbackId string
The id field of the callback query
text string optional
Short text shown to the user
showAlert boolean optional
true for a popup the user must dismiss, false for a brief toast

Returns

self chainable The bot itself, so calls can be chained.

Example

for _, update in ipairs(bot.poll()) do
if update.callback_query then
bot.ack(update.callback_query.id, "Got it")
end
end
bot.poll()→TelegramUpdate[]

Fetches the new updates the bot has received (messages and button presses from any chat, in order) and marks them as read, so each update is returned once. It waits up to the long polling time (30 seconds unless changed with pollTimeout) when there is nothing new, and returns an empty list then. Use it to find a chat id or to discard old messages; waitReply and waitCallback are easier for conversations. Messages in updates have no sender information.

Returns

TelegramUpdate[] One update from the Telegram bot API.
Fields of TelegramUpdate
update_id number
update id
message TelegramMessage
the new message, when the update is a message
callback_query TelegramCallback
the button press, when the update is a callback
All table shapes

Example

bot.pollTimeout(5)
for _, update in ipairs(bot.poll()) do
if update.message then
print("chat id " .. update.message.chat_id .. ": " .. update.message.text)
end
end
bot.pollTimeout(seconds: number)→self

Sets how long poll() and the wait functions ask Telegram to hold a request open when nothing new has arrived, in seconds (default 30). waitReply and waitCallback never wait longer than their own timeout. Raises an error unless the value is from 1 to 60.

Parameters

seconds number
Seconds, from 1 to 60

Returns

self chainable The bot itself, so calls can be chained.
bot.close()→self

Closes the HTTP client of this bot. The bot cannot be used afterwards; create a new one with Telegram.bot.

Returns

self chainable The bot itself, so calls can be chained.