Standard library · Web and services

telegram/bot

Building a bot with the Bot API: messages, buttons, webhooks and a polling loop.

import telegram.bot

To build a bot, get a token from BotFather and make one with NewBot. A bot has two ways of taking messages: Poll, which asks Telegram itself and suits testing and simple servers, or a webhook, where Telegram POSTs the messages to your server.

With a webhook you can send the answer straight in the body of the HTTP response; the Reply... functions build that JSON text. Set a secret with SetWebhookSecret and check its header on every request.

Things that catch people out:

  • Every API call is an HTTP GET with the parameters in the URL. Media therefore go by file_id or by a public URL that Telegram downloads; a file on your disk cannot be uploaded with this package. The URL also contains the token, so do not log request URLs.
  • Poll never returns, and it runs your function for one update at a time. A slow handler delays every chat. When getUpdates fails it writes the reason to standard error and tries again a second later.
  • An answer sent in the webhook response is fire and forget: you do not learn whether it worked or get the new message id. When you need either, call the matching Send... function instead.

Answering commands

Keep the logic of a bot in a function that takes an Update and returns the answer. Then the same function serves a webhook, which sends the answer back in the HTTP response, and a test like this one, which feeds it updates written by hand and needs no network and no token. IsCommand, CommandName and CommandArgs split /add 2 3 into its parts, and CommandName drops the @my_bot suffix Telegram adds in groups.

telegram-bot-guide-router.salam
import telegram.bot
import str

func answer(update: bot.Update): str:
    if not update.has_message:
        ret ""
    end
    m := update.message
    if not bot.IsCommand(m.text):
        ret bot.ReplyMessage(m.chat.id, "You said: " + m.text)
    end
    switch bot.CommandName(m.text):
        "start":
            ret bot.ReplyMessage(m.chat.id, "Hello " + m.from_user.first_name + "! Try /add 2 3")
        end
        "add":
            parts := str.Split(bot.CommandArgs(m.text), " ")
            if parts.len() != 2:
                ret bot.ReplyMessage(m.chat.id, "usage: /add A B")
            end
            sum := str.ToInt(parts.get(0)) + str.ToInt(parts.get(1))
            ret bot.ReplyMessage(m.chat.id, str.FromInt(sum))
        end
    end
    ret bot.ReplyMessage(m.chat.id, "I do not know that command")
end

func main:
    inbox := [`{"update_id":1,"message":{"message_id":1,"text":"/start","chat":{"id":42,"type":"private"},"from":{"id":42,"first_name":"Sara"}}}`,
        `{"update_id":2,"message":{"message_id":2,"text":"/add 2 3","chat":{"id":42,"type":"private"}}}`,
        `{"update_id":3,"message":{"message_id":3,"text":"/add 2","chat":{"id":42,"type":"private"}}}`,
        `{"update_id":4,"message":{"message_id":4,"text":"/weather@my_bot","chat":{"id":42,"type":"private"}}}`,
        `{"update_id":5,"message":{"message_id":5,"text":"good morning","chat":{"id":42,"type":"private"}}}`]
    each raw in inbox:
        println answer(bot.ParseUpdate(raw))
    end
end
Output{"method": "sendMessage", "chat_id": 42, "text": "Hello Sara! Try /add 2 3"} {"method": "sendMessage", "chat_id": 42, "text": "5"} {"method": "sendMessage", "chat_id": 42, "text": "usage: /add A B"} {"method": "sendMessage", "chat_id": 42, "text": "I do not know that command"} {"method": "sendMessage", "chat_id": 42, "text": "You said: good morning"}

The switch has no else, so a command it does not list falls out of it to the line after, which answers that the command is unknown. Always give some answer: a bot that stays silent looks broken to the user.

Inline buttons

An inline keyboard is a list of rows, and each row a list of buttons. InlineButton carries a callback_data string of up to 64 bytes that comes back when the user taps it; InlineButtonURL opens a link instead. A tap arrives as an update with has_callback_query set. Answer it with ReplyAnswerCallbackQuery, or the button keeps showing a spinner, and usually edit the original message so the chat shows what was chosen.

telegram-bot-guide-menu.salam
import telegram.bot

func menu(): str:
    mut first := Vector {} as Vector<str>
    first.push(bot.InlineButton("Tea", "order:tea"))
    first.push(bot.InlineButton("Coffee", "order:coffee"))
    mut second := Vector {} as Vector<str>
    second.push(bot.InlineButtonURL("Opening hours", "https://example.com/hours"))
    mut rows := Vector {} as Vector<str>
    rows.push(bot.Row(first))
    rows.push(bot.Row(second))
    ret bot.InlineKeyboardMarkup(rows)
end

func main:
    mut opts := bot.SendOptions {}
    opts.reply_markup = menu()
    println bot.ReplyMessageOptions(42, "What would you like?", opts)

    click := bot.ParseUpdate(`{"update_id":7,"callback_query":{"id":"cq7","data":"order:tea","from":{"id":42,"first_name":"Sara"},"message":{"message_id":31,"chat":{"id":42,"type":"private"}}}}`)
    if click.has_callback_query:
        q := click.callback_query
        println bot.ReplyAnswerCallbackQuery(q.id, "Got it", false)
        if q.has_message:
            println bot.ReplyEditMessageText(q.message.chat.id, q.message.message_id, "One tea for " + q.from_user.first_name, "")
        end
    end
end
Output{"method": "sendMessage", "chat_id": 42, "text": "What would you like?", "reply_markup": {"inline_keyboard": [[{"text": "Tea", "callback_data": "order:tea"}, {"text": "Coffee", "callback_data": "order:coffee"}], [{"text": "Opening hours", "url": "https://example.com/hours"}]]}} {"method": "answerCallbackQuery", "callback_query_id": "cq7", "text": "Got it"} {"method": "editMessageText", "chat_id": 42, "message_id": 31, "text": "One tea for Sara"}

Give callback_data a small format of your own, such as order:tea, and split it with str when it arrives. Never trust it: anyone can send any data to your bot, so check that the order exists before acting on it.

A bot that runs with long polling

Polling needs no public address, so it is the easiest way to run a bot from your own computer. Poll asks Telegram for new updates, waits up to the given number of seconds when there are none, calls your function for each one and remembers the offset, so every update is handled once. A bot can use either polling or a webhook, not both, which is why the program removes any webhook first. SetMyCommands fills the command menu Telegram shows next to the text box.

telegram-bot-guide-poll.salam
import telegram.bot
import env

func main:
    token := env.Get("TELEGRAM_TOKEN")
    if token.len() == 0:
        println "set TELEGRAM_TOKEN to the token BotFather gave you"
        ret 1
    end
    robot := bot.NewBot(token)
    me := bot.GetMe(robot)
    if not bot.Ok(me):
        println "the token was refused:", me.error_code, me.description, me.http_err
        ret 1
    end
    _ := bot.DeleteWebhook(robot)
    mut commands := Vector {} as Vector<str>
    commands.push(bot.BotCommand("start", "say hello"))
    commands.push(bot.BotCommand("echo", "repeat your text"))
    _ := bot.SetMyCommands(robot, commands)
    println "polling, press Ctrl+C to stop"
    bot.Poll(robot, 30, (update: bot.Update):
        if not update.has_message:
            ret
        end
        m := update.message
        _ := bot.SendChatAction(robot, m.chat.id, "typing")
        if bot.CommandName(m.text) == "echo":
            _ := bot.SendMessage(robot, m.chat.id, bot.CommandArgs(m.text))
        else:
            _ := bot.SendMessage(robot, m.chat.id, "Hello " + m.from_user.first_name + ", send /echo something")
        end
    end)
end

Run it with the token from BotFather in the environment:

TELEGRAM_TOKEN=123456:ABC... salam run telegram-bot-guide-poll.salam

Every Send... call returns an ApiResponse. Check it with Ok: when it fails, error_code and description hold Telegram's reason (429 means you are sending too fast) and http_err is set when Telegram could not be reached at all.

A webhook server

In production a webhook is the usual choice: Telegram sends each update to your HTTPS address as soon as it arrives, so nothing has to poll. SetWebhookSecret registers the address and a secret, and Telegram then puts that secret in the X-Telegram-Bot-Api-Secret-Token header (the constant SECRET_HEADER) of every request. Anything without it did not come from Telegram and gets a 401.

telegram-bot-guide-webhook.salam
import telegram.bot
import net.http
import net.router
import env

mut secret := ""

func hook(ctx: i64):
    if http.Header(ctx, bot.SECRET_HEADER) != secret:
        http.SetStatus(ctx, 401)
        http.Text(ctx, "")
        ret
    end
    update := bot.ParseUpdate(http.Body(ctx))
    if not update.has_message:
        http.Text(ctx, "")
        ret
    end
    m := update.message
    http.SetHeader(ctx, "Content-Type", "application/json")
    http.Text(ctx, bot.ReplyMessage(m.chat.id, "Got it: " + m.text))
end

func main:
    token := env.Get("TELEGRAM_TOKEN")
    public_url := env.Get("PUBLIC_URL")
    secret = env.Get("WEBHOOK_SECRET")
    if token.len() == 0 or public_url.len() == 0 or secret.len() == 0:
        println "set TELEGRAM_TOKEN, PUBLIC_URL and WEBHOOK_SECRET"
        ret 1
    end
    robot := bot.NewBot(token)
    set := bot.SetWebhookSecret(robot, public_url + "/telegram", secret)
    if not bot.Ok(set):
        println "setWebhook failed:", set.error_code, set.description
        ret 1
    end
    mut r := router.NewRouter()
    router.Post(r, "/telegram", hook)
    mut s := http.NewServer(8443)
    http.Use(s, r)
    println "webhook on port 8443"
    http.Run(s)
end

The answer goes back in the response body: ReplyMessage builds the JSON for a sendMessage call, and Telegram runs it. Reply with an empty body when there is nothing to say, and answer quickly, because Telegram waits for the response before it sends the next update for that chat. Telegram only calls HTTPS addresses on ports 443, 80, 88 or 8443, so run the program behind a proxy with a certificate, or behind a tunnel while you develop. SetWebhookSecret also drops updates that were waiting, so a restart does not replay old messages.

Types

User

struct User
One Telegram user.
NameTypeDescription
idi64 = 0The id.
is_botbool = falseIt is a bot.
first_namestr = ""The first name.
last_namestr = ""The last name.
usernamestr = ""The user name.
language_codestr = ""The language of the user, such as fa.
telegram-bot-Parse.salam
import telegram.bot

func main:
    text := `{"update_id":10,"message":{"message_id":5,"date":1700000000,"text":"/start hello","chat":{"id":42,"type":"private","first_name":"Maryam","username":"maryam"},"from":{"id":42,"is_bot":false,"first_name":"Maryam","language_code":"en"},"reply_to_message":{"message_id":4,"from":{"id":7,"first_name":"Ali"}}}}`
    update := bot.ParseUpdate(text)
    println update.update_id, update.has_message, update.has_callback_query
    m := update.message
    println m.message_id, m.date, m.text, m.chat.id, m.chat.chat_type, m.chat.first_name, m.chat.username
    println m.from_user.id, m.from_user.is_bot, m.from_user.language_code, m.reply_to.message_id, m.reply_to.user_id, m.reply_to.user_name
    println bot.IsCommand(m.text), bot.CommandName(m.text), bot.CommandArgs(m.text)
    println bot.IsCommand("hello"), bot.CommandName("/help@my_bot")

    all := bot.ParseUpdates(`{"ok":true,"result":[{"update_id":11,"callback_query":{"id":"cq1","data":"yes","from":{"id":42,"first_name":"Maryam"},"message":{"message_id":9,"chat":{"id":42,"type":"private"}}}},{"update_id":12,"inline_query":{"id":"iq1","query":"book","offset":"","from":{"id":42,"first_name":"Maryam"}}}]}`)
    println all.len()
    q := all[0].callback_query
    println all[0].has_callback_query, q.id, q.data, q.from_user.first_name, q.has_message, q.message.message_id
    typed := all[1].inline_query
    println all[1].has_inline_query, typed.id, typed.query, typed.offset.len()
    println bot.ParseUser(`{"id":1,"first_name":"x","last_name":"y","is_bot":true}`).last_name
    println bot.ParseChat(`{"id":-100,"type":"supergroup","title":"the group"}`).title
    println bot.ParseMessage(`{"message_id":1,"caption":"a photo","chat":{"id":1}}`).caption
    println bot.ParseCallbackQuery(`{"id":"q","data":"d"}`).data, bot.ParseInlineQuery(`{"id":"i","query":"q"}`).query
    println bot.ParseUpdate(`{"update_id":13,"channel_post":{"message_id":1,"text":"news","chat":{"id":-5}}}`).channel_post.text

    mut row1 := Vector {} as Vector<str>
    row1.push(bot.InlineButton("yes", "yes"))
    row1.push(bot.InlineButton("no", "no"))
    mut row2 := Vector {} as Vector<str>
    row2.push(bot.InlineButtonURL("the site", "https://salamlang.ir"))
    mut rows := Vector {} as Vector<str>
    rows.push(bot.Row(row1))
    rows.push(bot.Row(row2))
    println bot.InlineKeyboardMarkup(rows)
    mut plain := Vector {} as Vector<str>
    plain.push(bot.KeyboardButton("menu"))
    mut plain_rows := Vector {} as Vector<str>
    plain_rows.push(bot.Row(plain))
    println bot.ReplyKeyboardMarkup(plain_rows)
    println bot.RemoveKeyboard(), bot.ForceReply()
    println bot.BotCommand("start", "start it")

    robot := bot.NewBot("123:ABC")
    println bot.FileURL(robot, "photos/file_1.jpg")
    println bot.ReplyMessage(42, "hello")
    mut options := bot.SendOptions {}
    options.parse_mode = "HTML"
    options.reply_to_message_id = 5
    options.disable_notification = true
    println bot.ReplyMessageOptions(42, "<b>hello</b>", options)
    println bot.ReplyAnswerCallbackQuery("cq1", "noted", false)
    println bot.ReplyChatAction(42, "typing")
    println bot.ReplyEditMessageText(42, 9, "updated", bot.RemoveKeyboard())
    println bot.SECRET_HEADER
end

Chat

struct Chat
One chat: private, a group or a channel.
NameTypeDescription
idi64 = 0The id; negative for groups.
chat_typestr = ""The type: private, group, supergroup or channel.
titlestr = ""The title of the group or channel.
usernamestr = ""The user name.
first_namestr = ""The first name.
last_namestr = ""The last name.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ReplyTo

struct ReplyTo
The message this one is a reply to.
NameTypeDescription
message_idi64 = 0The id of that message.
user_idi64 = 0The id of its sender.
user_namestr = ""The name of its sender.
telegram-bot-Bot.salam
import telegram.bot
import env

func handle(update: bot.Update):
    if not update.has_message:
        ret
    end
    println update.message.from_user.first_name, update.message.text
end

func main:
    robot := bot.NewBot(env.Get("TELEGRAM_TOKEN"))
    me := bot.GetMe(robot)
    if not bot.Ok(me):
        println me.error_code, me.description, me.http_status, me.http_err
        ret
    end
    println me.ok, me.result
    chat := 42 as i64
    _ := bot.SendMessage(robot, chat, "hello")
    _ := bot.SendMessage(robot, "@my_channel", "fresh news")
    mut options := bot.SendOptions {}
    options.parse_mode = "Markdown"
    options.reply_markup = bot.RemoveKeyboard()
    _ := bot.SendMessageOptions(robot, chat, "*important*", options)
    _ := bot.SendPhoto(robot, chat, "https://example.com/a.jpg", "a photo")
    _ := bot.SendDocument(robot, chat, "BQACAgQAAx", "")
    _ := bot.SendVideo(robot, chat, "https://example.com/v.mp4", "")
    _ := bot.SendAudio(robot, chat, "https://example.com/a.mp3", "")
    _ := bot.SendVoice(robot, chat, "AwACAgQ", "")
    _ := bot.SendSticker(robot, chat, "CAACAgI")
    _ := bot.SendLocation(robot, chat, 35.6997, 51.338)
    _ := bot.SendContact(robot, chat, "+989120000000", "Ali")
    _ := bot.SendChatAction(robot, chat, "typing")
    _ := bot.EditMessageText(robot, chat, 10, "edited")
    _ := bot.ForwardMessage(robot, chat, 43, 11)
    _ := bot.PinChatMessage(robot, chat, 10)
    _ := bot.UnpinChatMessage(robot, chat, 10)
    _ := bot.DeleteMessage(robot, chat, 10)
    _ := bot.AnswerCallbackQuery(robot, "cq1", "noted")
    _ := bot.AnswerInlineQuery(robot, "iq1", "[]")
    file := bot.GetFile(robot, "AgACAgQ")
    println file.result.len() > 0
    _ := bot.GetChat(robot, chat)
    _ := bot.GetChatMemberCount(robot, chat)
    _ := bot.GetChatMember(robot, chat, 7)
    _ := bot.BanChatMember(robot, chat, 7)
    _ := bot.UnbanChatMember(robot, chat, 7)
    _ := bot.LeaveChat(robot, -100)
    mut commands := Vector {} as Vector<str>
    commands.push(bot.BotCommand("start", "start it"))
    _ := bot.SetMyCommands(robot, commands)
    _ := bot.SetWebhook(robot, "https://example.com/hook")
    _ := bot.SetWebhookSecret(robot, "https://example.com/hook", "my-secret")
    _ := bot.GetWebhookInfo(robot)
    _ := bot.DeleteWebhook(robot)
    mut params := HashMap {} as HashMap<str, str>
    params.insert("chat_id", "42")
    _ := bot.Call(robot, "getChatAdministrators", params)
    updates := bot.GetUpdates(robot, 0, 10, 30)
    println bot.ParseUpdates(updates.result).len(), robot.token.len() > 0
    bot.Poll(robot, 30, (update: bot.Update):
        handle(update)
    end)
end

Message

struct Message
One message.
NameTypeDescription
message_idi64 = 0The id.
datei64 = 0The time in Unix seconds.
chatChatThe chat.
from_userUserThe sender.
textstr = ""The text.
captionstr = ""The caption of a photo or file.
reply_toReplyToThe message that was replied to.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

CallbackQuery

struct CallbackQuery
One press of an inline button.
NameTypeDescription
idstr = ""The id; answer with it.
from_userUserThe user.
messageMessageThe message the button was in.
has_messagebool = falseIt has a message.
datastr = ""The data of the button.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

InlineQuery

struct InlineQuery
An inline query, from when a user types @bot.
NameTypeDescription
idstr = ""The id.
from_userUserThe user.
querystr = ""The text.
offsetstr = ""The paging position.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Update

struct Update
One event from Telegram; only one of its parts is filled in.
NameTypeDescription
update_idi64 = 0The id; pass one more than it to the next GetUpdates.
messageMessageThe message.
has_messagebool = falseIt has a message.
channel_postMessageA channel post.
has_channel_postbool = falseIt has a channel post.
callback_queryCallbackQueryA button press.
has_callback_querybool = falseIt has a button press.
inline_queryInlineQueryAn inline query.
has_inline_querybool = falseIt has an inline query.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ApiResponse

struct ApiResponse
A Bot API response.
NameTypeDescription
okbool = falseIt succeeded.
resultstr = ""The result as JSON.
descriptionstr = ""The error description.
error_codei64 = 0The Telegram error code.
http_statusint = 0The HTTP status code.
http_errstr = ""The network error.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendOptions

struct SendOptions
The options for sending a message.
NameTypeDescription
parse_modestr = ""The text format: HTML or MarkdownV2.
disable_notificationbool = falseSend it silently.
reply_to_message_idi64 = 0Reply to this message.
reply_markupstr = ""The keyboard as JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Bot

struct Bot
One bot.
NameTypeDescription
tokenstr = ""The token from BotFather; keep it secret.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Constants and variables

SECRET_HEADER

const SECRET_HEADER: str = "X-Telegram-Bot-Api-Secret-Token"
The name of the header the webhook secret arrives in.
telegram-bot-Webhook.salam
import telegram.bot
import net.http
import net.router

func webhook(ctx: i64):
    if http.Header(ctx, bot.SECRET_HEADER) != "my-secret":
        http.SetStatus(ctx, 403)
        http.Text(ctx, "forbidden")
        ret
    end
    update := bot.ParseUpdate(http.Body(ctx))
    if update.has_message and bot.IsCommand(update.message.text):
        answer := "the command " + bot.CommandName(update.message.text) + " arrived"
        http.Json(ctx, bot.ReplyMessage(update.message.chat.id, answer))
    else update.has_callback_query:
        http.Json(ctx, bot.ReplyAnswerCallbackQuery(update.callback_query.id, "all right", true))
    else:
        http.Text(ctx, "ok")
    end
end

func main:
    mut r := router.NewRouter()
    router.Post(r, "/hook", webhook)
    mut s := http.NewServer(19632)
    http.Use(s, r)
    _ := http.RunBackground(s)

    mut headers := http.NewHeaders()
    headers.insert(bot.SECRET_HEADER, "my-secret")
    headers.insert("Content-Type", "application/json")
    a := http.PostWith("http://127.0.0.1:19632/hook", `{"update_id":1,"message":{"message_id":2,"text":"/start","chat":{"id":42,"type":"private"}}}`, headers)
    println http.Status(a), http.Body(a)
    b := http.PostWith("http://127.0.0.1:19632/hook", `{"update_id":2,"callback_query":{"id":"cq9","data":"x","from":{"id":42}}}`, headers)
    println http.Body(b)
    c := http.Post("http://127.0.0.1:19632/hook", "{}")
    println http.Status(c)
end

Functions

SetWebhookSecret

func SetWebhookSecret(bot: Bot, url: str, secret_token: str): ApiResponse
A webhook with a secret that Telegram sends in the SECRET_HEADER header; reject forged requests with it.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

ReplyMessage

func ReplyMessage(chat_id: i64, text: str): str
A webhook reply that sends a message; make it the body of the HTTP response and no separate request is needed.

The example for this item is shown with the ones above: telegram-bot-Webhook.salam

ReplyMessageOptions

func ReplyMessageOptions(chat_id: i64, text: str, opts: SendOptions): str
The same, with options.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ReplyEditMessageText

func ReplyEditMessageText(chat_id: i64, message_id: i64, text: str, reply_markup: str): str
A webhook reply that edits the text of a message.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ReplyAnswerCallbackQuery

func ReplyAnswerCallbackQuery(callback_query_id: str, text: str, show_alert: bool): str
A webhook reply to a button press.

The example for this item is shown with the ones above: telegram-bot-Webhook.salam

ReplyChatAction

func ReplyChatAction(chat_id: i64, action: str): str
A webhook reply with a chat action.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseUser

func ParseUser(raw: str): User
Reads a user from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseChat

func ParseChat(raw: str): Chat
Reads a chat from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseMessage

func ParseMessage(raw: str): Message
Reads a message from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseCallbackQuery

func ParseCallbackQuery(raw: str): CallbackQuery
Reads a button press from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseInlineQuery

func ParseInlineQuery(raw: str): InlineQuery
Reads an inline query from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseUpdate

func ParseUpdate(raw: str): Update
Reads one update from JSON.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ParseUpdates

func ParseUpdates(raw: str): Vector<Update>
Turns the result of getUpdates into a list of updates.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

NewBot

func NewBot(token: str): Bot
A bot with a token.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Ok

func Ok(resp: ApiResponse): bool
The response succeeded.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

Call

func Call(bot: Bot, method: str, params: HashMap<str, str>): ApiResponse
Calls any Bot API method with its parameters.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetMe

func GetMe(bot: Bot): ApiResponse
The details of the bot itself; for testing the token.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetUpdates

func GetUpdates(bot: Bot, offset: i64, limit: i64, timeout: i64): ApiResponse
Takes the updates from the given position, with long polling.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendMessage

func SendMessage(bot: Bot, chat_id: i64, text: str): ApiResponse
Sends a text message; the chat by numeric id or by channel name, such as @channel.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendMessage

func SendMessage(bot: Bot, chat_id: str, text: str): ApiResponse
Sends a text message; the chat by numeric id or by channel name, such as @channel.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendMessageOptions

func SendMessageOptions(bot: Bot, chat_id: i64, text: str, opts: SendOptions): ApiResponse
A message with options.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendPhoto

func SendPhoto(bot: Bot, chat_id: i64, photo: str, caption: str): ApiResponse
Sends a photo by public URL or by the file_id of a photo Telegram already has, with a caption. Uploading a local file is not supported.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendDocument

func SendDocument(bot: Bot, chat_id: i64, document: str, caption: str): ApiResponse
Sends a file by public URL or file_id, with a caption. Uploading a local file is not supported.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendVideo

func SendVideo(bot: Bot, chat_id: i64, video: str, caption: str): ApiResponse
Sends a video by address or file id, with a caption.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendAudio

func SendAudio(bot: Bot, chat_id: i64, audio: str, caption: str): ApiResponse
Sends a song by address or file id, with a caption.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendVoice

func SendVoice(bot: Bot, chat_id: i64, voice: str, caption: str): ApiResponse
Sends a voice message by address or file id, with a caption.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendSticker

func SendSticker(bot: Bot, chat_id: i64, sticker: str): ApiResponse
A sticker.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendLocation

func SendLocation(bot: Bot, chat_id: i64, latitude: f64, longitude: f64): ApiResponse
A geographic location.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendContact

func SendContact(bot: Bot, chat_id: i64, phone_number: str, first_name: str): ApiResponse
A contact.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SendChatAction

func SendChatAction(bot: Bot, chat_id: i64, action: str): ApiResponse
Shows a status such as "typing".

The example for this item is shown with the ones above: telegram-bot-Bot.salam

EditMessageText

func EditMessageText(bot: Bot, chat_id: i64, message_id: i64, text: str): ApiResponse
Edits the text of a message that was sent.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

DeleteMessage

func DeleteMessage(bot: Bot, chat_id: i64, message_id: i64): ApiResponse
Deletes the message.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

ForwardMessage

func ForwardMessage(bot: Bot, chat_id: i64, from_chat_id: i64, message_id: i64): ApiResponse
Forwards a message from another chat.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

PinChatMessage

func PinChatMessage(bot: Bot, chat_id: i64, message_id: i64): ApiResponse
Pins the message.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

UnpinChatMessage

func UnpinChatMessage(bot: Bot, chat_id: i64, message_id: i64): ApiResponse
Unpins it.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

AnswerCallbackQuery

func AnswerCallbackQuery(bot: Bot, callback_query_id: str, text: str): ApiResponse
Answers a button press; until you answer, the button stays in its loading state.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

AnswerInlineQuery

func AnswerInlineQuery(bot: Bot, inline_query_id: str, results: str): ApiResponse
Sends the results of an inline query.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetFile

func GetFile(bot: Bot, file_id: str): ApiResponse
The file details, for downloading.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

FileURL

func FileURL(bot: Bot, file_path: str): str
The download address of a file.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

GetChat

func GetChat(bot: Bot, chat_id: i64): ApiResponse
The details of a chat.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetChatMemberCount

func GetChatMemberCount(bot: Bot, chat_id: i64): ApiResponse
The number of members.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetChatMember

func GetChatMember(bot: Bot, chat_id: i64, user_id: i64): ApiResponse
The status of one member.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

LeaveChat

func LeaveChat(bot: Bot, chat_id: i64): ApiResponse
The bot leaves the chat.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

BanChatMember

func BanChatMember(bot: Bot, chat_id: i64, user_id: i64): ApiResponse
Bans a member.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

UnbanChatMember

func UnbanChatMember(bot: Bot, chat_id: i64, user_id: i64): ApiResponse
Lifts the ban.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

SetWebhook

func SetWebhook(bot: Bot, url: str): ApiResponse
Sets the webhook address, so Telegram sends the updates to it.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

DeleteWebhook

func DeleteWebhook(bot: Bot): ApiResponse
Takes the webhook away.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

GetWebhookInfo

func GetWebhookInfo(bot: Bot): ApiResponse
The state of the webhook.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

BotCommand

func BotCommand(command: str, description: str): str
One command for the bot menu.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

SetMyCommands

func SetMyCommands(bot: Bot, commands: Vector<str>): ApiResponse
Sets the command menu of the bot.

The example for this item is shown with the ones above: telegram-bot-Bot.salam

InlineButton

func InlineButton(text: str, callback_data: str): str
An inline button with data.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

InlineButtonURL

func InlineButtonURL(text: str, url: str): str
An inline button with a link.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

KeyboardButton

func KeyboardButton(text: str): str
A reply keyboard button.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Row

func Row(buttons: Vector<str>): str
One row of buttons.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

InlineKeyboardMarkup

func InlineKeyboardMarkup(rows: Vector<str>): str
An inline keyboard from rows.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ReplyKeyboardMarkup

func ReplyKeyboardMarkup(rows: Vector<str>): str
A reply keyboard from rows.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

RemoveKeyboard

func RemoveKeyboard(): str
Takes the reply keyboard away.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

ForceReply

func ForceReply(): str
Makes the user reply.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

IsCommand

func IsCommand(text: str): bool
The text starts with a /.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

CommandName

func CommandName(text: str): str
The command name, without the / and without @bot.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

CommandArgs

func CommandArgs(text: str): str
The rest of the text after the command.

The example for this item is shown with the ones above: telegram-bot-Parse.salam

Poll

func Poll(bot: Bot, timeout: i64, handler: func(Update))
The polling loop: it takes the updates with long polling and calls the function for each one; it does not return. Updates are handled one at a time, and a failed request is retried after one second.

The example for this item is shown with the ones above: telegram-bot-Bot.salam