Chat admin required telegram что это
Перейти к содержимому

Chat admin required telegram что это

  • автор:

Telegram Bot API возвращает CHAT_ADMIN_REQUIRED, хотя бот имеет все права

Я пишу telegram-бота (библиотека tgbot-cpp), и при вызове promoteChatMember я получаю исключение Bad Request: CHAT_ADMIN_REQUIRED , хотя бот имеет все права так и в группе, так и в настройках через BotFather: Я отправлял такой запрос через https, не используя никаких библиотек, но проблема та же. Что могло пойти не так? Вот сам код:

static void revokeAdmin(BotInfo& botInfo, const TgBot::Message::Ptr& message) < // spdlog::debug("Promoting admin. "); // Я являюсь владельцем группы, поэтому необязательно меня продвигать. // botInfo.bot.getApi().promoteChatMember(message->chat->id, message->from->id, true); botInfo.bot.getApi().promoteChatMember(message->chat->id, message->replyToMessage->from->id); > 

( botInfo содержит самого бота и прочую информацию о нём, все параметры передаются правильно. Его поле bot имеет тип TgBot::Bot ).

Отслеживать
user570514
задан 20 окт в 16:17
user570514 user570514
1 2 2 бронзовых знака
Покажите ваш код.
20 окт в 16:18
Я изменил вопрос, добавил код.
20 окт в 16:26

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Ответ прост: бот не может повышать/понижать администраторов, создателей.

Отслеживать
ответ дан 2 дня назад
user570514 user570514
1 2 2 бронзовых знака

user570514 — новый участник сайта. Будьте снисходительны, задавая уточняющие вопросы, комментируя и отвечая. Почитайте про нормы поведения.

Справочник по Bot API

Bot API представляет из себя HTTP-интерфейс для работы с ботами в Telegram.

Примечание

Подробнее о том, как создать и настроить своего бота, читайте в статье с информацией для разработчиков.

  • Список изменений
  • Авторизация
  • Отправка запросов
  • Получение обновлений
  • Доступные типы
  • Доступные методы

Авторизация бота

Каждому боту при создании присваивается уникальный токен вида 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 . В документации для простоты вместо него будет использоваться . Подробнее о том, как получить или заменить токен для вашего бота, читайте в этой статье.

Отправка запросов

Все запросы к Telegram Bot API должны осуществляться через HTTPS в следующем виде: https://api.telegram.org/bot/НАЗВАНИЕ_МЕТОДА . Например:

https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe

Допускаются GET и POST запросы. Для передачи параметров в Bot API доступны 4 способа:

  • Запрос в URL
  • application/x-www-form-urlencoded
  • application/json (не подходит для загрузки файлов)
  • multipart/form-data (для загрузки файлов)

Ответ придёт в виде JSON-объекта, в котором всегда будет булево поле ok и опциональное строковое поле description , содержащее человекочитаемое описание результата. Если поле ok истинно, то запрос прошёл успешно и результат его выполнения можно увидеть в поле result . В случае ошибки поле ok будет равно false , а причины ошибки будут описаны в поле description . Кроме того, в ответе будет целочисленное поле error_code , но коды ошибок будут изменены в будущем.

Предупреждение

Все методы регистрозависимы и должны быть в кодировке UTF-8.

Отправка запросов при получении обновления

Если ваш бот работает через вебхуки, то вы можете осуществить запрос к Bot API одновременно с отправкой ответа на вебхук. Для передачи параметров нужно использовать один из типов:

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data

Метод для вызова должен быть определён в запросе в поле method . Однако, имейте в виду: невозможно узнать статус и результат такого запроса.

Примеры таких запросов описаны в FAQ.

Получение обновлений

Существует два диаметрально противоположных по логике способа получать обновления от вашего бота: getUpdates и вебхуки. Входящие обновления будут храниться на сервере до тех пор, пока вы их не обработаете, но не дольше 24 часов.

Независимо от способа получения обновлений, в ответ вы получите объект Update, сериализованный в JSON.

Update

Этот объект представляет из себя входящее обновление. Под обновлением подразумевается действие, совершённое с ботом — например, получение сообщения от пользователя.

Только один из необязательных параметров может присутствовать в каждом обновлении.

Поле Тип Описание
update_id Integer The update‘s unique identifier. Update identifiers start from a certain positive number and increase sequentially. This ID becomes especially handy if you’re using Webhooks, since it allows you to ignore repeated updates or to restore the correct update sequence, should they get out of order.
message Message Опционально. New incoming message of any kind — text, photo, sticker, etc.
inline_query InlineQuery Опционально. New incoming inline query
chosen_inline_result ChosenInlineResult Опционально. The result of an inline query that was chosen by a user and sent to their chat partner.
callback_query CallbackQuery Опционально. New incoming callback query

getUpdates

Этот метод используется для получения обновлений через long polling (wiki). Ответ возвращается в виде массива объектов Update.

Параметры Тип Обязательный Описание
offset Integer Необязательный Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.
limit Integer Необязательный Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100.
timeout Integer Необязательный Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling
Примечание:
  1. Этот метод не будет работать, если у вас уже подключен webhook.
  2. Во избежания повторяющихся обновлений, рекомендуется высчитывать offset каждый раз заново.

setWebhook

Этот метод необходим для задания URL вебхука, на который бот будет отправлять обновления. Каждый раз при получении обновления на этот адрес будет отправлен HTTPS POST с сериализованным в JSON объектом Update. При неудачном запросе к вашему серверу попытка будет повторена умеренное число раз.

Для большей безопасности рекомендуется включить токен в URL вебхука, например, так: https://yourwebhookserver.com/ . Так как никто посторонний не знает вашего токена, вы можете быть уверены, что запросы к вашему вебхуку шлёт именно Telegram.

Параметры Тип Обязательный Описание
url String Нет HTTPS url для отправки запросов. Чтобы удалить вебхук, отправьте пустую строку.
certificate InputFile Нет Загрузка публичного ключа для проверки корневого сертификата. Подробнее в разделе про самоподписанные сертификаты.
Примечание:
  1. При подключенном и настроенном вебхуке метод getUpdates не будет работать.
  2. При использовании самоподписанного сертификата, вам необходимо загрузить публичный ключ с помощью параметра certificate .
  3. На текущий момент отправка обновлений через вебхуки доступна только на эти порты: 443, 80, 88, 8443.
getWebhookInfo

Содержит информацию о текущем состоянии вебхука.

Поле Тип Описание
url String URL вебхука, может быть пустым
has_custom_certificate Boolean True, если вебхук использует самозаверенный сертификат
pending_update_count Integer Количество обновлений, ожидающих доставки
last_error_date Integer Опционально. Unix-время самой последней ошибки доставки обновления на указанный вебхук
last_error_message String Опционально. Описание в человекочитаемом формате последней ошибки доставки обновления на указанный вебхук

Доступные типы

Все типы, использующиеся в Bot API, являются JSON-объектами.

Для хранения всех полей типа Integer безопасно использовать 32-битные знаковые целые числа, если не указано иначе.

Необязательные поля могут быть опущены в ответе, если они не относятся к ответу.

User

Этот объект представляет бота или пользователя Telegram.

Поле Тип Описание
id Integer Уникальный идентификатор пользователя или бота
first_name String Имя бота или пользователя
last_name String Опционально. Фамилия бота или пользователя
username String Опционально. Username пользователя или бота

Chat

Этот объект представляет собой чат.

Поле Тип Описание
id Integer Уникальный идентификатор чата. Абсолютное значение не превышает 1e13
type Enum Тип чата: “private”, “group”, “supergroup” или “channel”
title String Опционально. Название, для каналов или групп
username String Опционально. Username, для чатов и некоторых каналов
first_name String Опционально. Имя собеседника в чате
last_name String Опционально. Фамилия собеседника в чате
all_members_are_administrators Boolean Опционально.True, если все участники чата являются администраторами

Message

Этот объект представляет собой сообщение.

Поле Тип Описание
message_id Integer Уникальный идентификатор сообщения
from User Опционально. Отправитель. Может быть пустым в каналах.
date Integer Дата отправки сообщения (Unix time)
chat Chat Диалог, в котором было отправлено сообщение
forward_from User Опционально. Для пересланных сообщений: отправитель оригинального сообщения
forward_date Integer Опционально. Для пересланных сообщений: дата отправки оригинального сообщения
reply_to_message Message Опционально. Для ответов: оригинальное сообщение. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.
text String Опционально. Для текстовых сообщений: текст сообщения, 0-4096 символов
entities Массив из MessageEntity Опционально. Для текстовых сообщений: особые сущности в тексте сообщения.
audio Audio Опционально. Информация об аудиофайле
document Document Опционально. Информация о файле
photo Массив из PhotoSize Опционально. Доступные размеры фото
sticker Sticker Опционально. Информация о стикере
video Video Опционально. Информация о видеозаписи
voice Voice Опционально. Информация о голосовом сообщении
caption String Опционально. Подпись к файлу, фото или видео, 0-200 символов
contact Contact Опционально. Информация об отправленном контакте
location Location Опционально. Информация о местоположении
venue Venue Опционально. Информация о месте на карте
new_chat_member User Опционально. Информация о пользователе, добавленном в группу
left_chat_member User Опционально. Информация о пользователе, удалённом из группы
new_chat_title String Опционально. Название группы было изменено на это поле
new_chat_photo Массив из PhotoSize Опционально. Фото группы было изменено на это поле
delete_chat_photo True Опционально. Сервисное сообщение: фото группы было удалено
group_chat_created True Опционально. Сервисное сообщение: группа создана
supergroup_chat_created True Опционально. Сервисное сообщение: супергруппа создана
channel_chat_created True Опционально. Сервисное сообщение: канал создан
migrate_to_chat_id Integer Опционально. Группа была преобразована в супергруппу с указанным идентификатором. Не превышает 1e13
migrate_from_chat_id Integer Опционально. Cупергруппа была создана из группы с указанным идентификатором. Не превышает 1e13
pinned_message Message Опционально. Указанное сообщение было прикреплено. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply.

MessageEntity

Этот объект представляет одну из особых сущностей в текстовом сообщении. Например: хештеги, имена пользователей, ссылки итд.

Поле Тип Описание
type String Type of the entity. One of mention ( @username ), hashtag, bot_command, url, email, bold (bold text), italic (italic text), code (monowidth string), pre (monowidth block), text_link (for clickable text URLs)
offset Integer Offset in UTF-16 code units to the start of the entity
length Integer Length of the entity in UTF-16 code units
url String Опционально. For “text_link” only, url that will be opened after user taps on the text

PhotoSize

Этот объект представляет изображение определённого размера или превью файла / стикера.

Поле Тип Описание
file_id String Уникальный идентификатор файла
width Integer Photo width
height Integer Photo height
file_size Integer Опционально. Размер файла

Audio

Этот объект представляет аудиозапись, которую клиенты Telegram воспинимают как музыкальный трек.

Поле Тип Описание
file_id String Уникальный идентификатор файла
duration Integer Duration of the audio in seconds as defined by sender
performer String Опционально. Performer of the audio as defined by sender or by audio tags
title String Опционально. Title of the audio as defined by sender or by audio tags
mime_type String Опционально. MIME файла, заданный отправителем
file_size Integer Опционально. Размер файла

Document

Этот объект представляет файл, не являющийся фотографией, голосовым сообщением или аудиозаписью.

Поле Тип Описание
file_id String Unique file identifier
thumb PhotoSize Опционально. Document thumbnail as defined by sender
file_name String Опционально. Original filename as defined by sender
mime_type String Опционально. MIME файла, заданный отправителем
file_size Integer Опционально. Размер файла

Sticker

Этот объект представляет стикер.

Поле Тип Описание
file_id String Уникальный идентификатор файла
width Integer Ширина стикера
height Integer Высота стикера
thumb PhotoSize Опционально. Превью стикера в формате .webp или .jpg
file_size Integer Опционально. Размер файла

Video

Этот объект представляет видеозапись.

Поле Тип Описание
file_id String Уникальный идентификатор файла
width Integer Ширина видео, заданная отправителем
height Integer Высота видео, заданная отправителем
duration Integer Продолжительность видео, заданная отправителем
thumb PhotoSize Опционально. Превью видео
mime_type String Опционально. MIME файла, заданный отправителем
file_size Integer Опционально. Размер файла

Voice

Этот объект представляет голосовое сообщение.

Поле Тип Описание
file_id String Уникальный идентификатор файла
duration Integer Продолжительность аудиофайла, заданная отправителем
mime_type String Опционально. MIME-тип файла, заданный отправителем
file_size Integer Опционально. Размер файла

Contact

Этот объект представляет контакт с номером телефона.

Поле Тип Описание
phone_number String Номер телефона
first_name String Имя
last_name String Опционально. Фамилия
user_id Integer Опционально. Идентификатор пользователя в Telegram

Location

Этот объект представляет точку на карте.

Поле Тип Описание
longitude Float Долгота, заданная отправителем
latitude Float Широта, заданная отправителем

Venue

Этот объект представляет объект на карте.

Поле Тип Описание
location Location Координаты объекта
title String Название объекта
address String Адрес объекта
foursquare_id String Опционально. Идентификатор объекта в Foursquare

UserProfilePhotos

Этот объект содержит фотографии профиля пользователя.

Поле Тип Описание
total_count Integer Общее число доступных фотографий профиля
photos Массив массивов с объектами PhotoSize Запрошенные изображения, каждое в 4 разных размерах.

File

Этот объект представляет файл, готовый к загрузке. Он может быть скачан по ссылке вида https://api.telegram.org/file/bot/ . Ссылка будет действительна как минимум в течение 1 часа. По истечении этого срока она может быть запрошена заново с помощью метода getFile.

Максимальный размер файла для скачивания — 20 МБ

Поле Тип Описание
file_id String Уникальный идентификатор файла
file_size Integer Опционально. Размер файла, если известен
file_path String Опционально. Расположение файла. Для скачивания воспользуйтейсь ссылкой вида https://api.telegram.org/file/bot/

ReplyKeyboardMarkup

Этот объект представляет клавиатуру с опциями ответа (см. описание ботов).

KeyboardButton

Этот объект представляет одну кнопку в клавиатуре ответа. Для обычных текстовых кнопок этот объект может быть заменён на строку, содержащую текст на кнопке.

Поле Тип Описание
text String Текст на кнопке. Если ни одно из опциональных полей не использовано, то при нажатии на кнопку этот текст будет отправлен боту как простое сообщение.
request_contact Boolean Опционально. Если значение True , то при нажатии на кнопку боту отправится контакт пользователя с его номером телефона. Доступно только в диалогах с ботом.
request_location Boolean Опционально. Если значение True , то при нажатии на кнопку боту отправится местоположение пользователя. Доступно только в диалогах с ботом.
Внимание:

Параметры request_contact и request_location будут работать только в версиях Telegram, выпущенных позже 9 апреля 2016 года. Более старые клиенты проигнорируют это поле.

ReplyKeyboardHide

После получения сообщения с этим объектом, приложение Telegram свернёт клавиатуру бота и отобразит стандартную клавиатуру устройства (с буквами). По умолчанию клавиатуры бота отображаются до тех пор, пока не будет принудительно отправлена новая или скрыта старая клавиатура. Исключение составляют одноразовые клавиатуры, которые скрываются сразу после нажатия на какую-либо кнопку (см. ReplyKeyboardMarkup).

InlineKeyboardMarkup

Этот объект представляет встроенную клавиатуру, которая появляется под соответствующим сообщением.

Поле Тип Описание
inline_keyboard Массив массивов с InlineKeyboardButton Массив строк, каждая из которых является массивом объектов InlineKeyboardButton.
Внимание:

Эти параметры будут работать только в версиях Telegram, выпущенных позже 9 апреля 2016 года. Более старые клиенты покажут ошибку вместо сообщения.

InlineKeyboardButton

Этот объект представляет одну кнопку встроенной клавиатуры. Вы обязательно должны задействовать ровно одно опциональное поле.

Внимание:

Эти параметры будут работать только в версиях Telegram, выпущенных позже 9 апреля 2016 года. Более старые клиенты покажут ошибку вместо сообщения.

CallbackQuery

Этот объект представляет входящий запрос обратной связи от инлайн-кнопки с заданным callback_data .

Если кнопка, создавшая этот запрос, была привязана к сообщению, то в запросе будет присутствовать поле message .

Если кнопка была показана в сообщении, отправленном при помощи встроенного режима, в запросе будет присутствовать поле inline_message_id .

Поле Тип Описание
id String Уникальный идентификатор запроса
from User Отправитель
message Message Опционально. Сообщение, к которому была привязана вызвавшая запрос кнопка. Обратите внимание: если сообщение слишком старое, содержание сообщения и дата отправки будут недоступны.
inline_message_id String Опционально. Идентификатор сообщения, отправленного через вашего бота во встроенном режиме
data String Данные, связанные с кнопкой. Обратите внимание, что клиенты могут добавлять свои данные в это поле.

ForceReply

Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot‘s message and tapped ’Reply’). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode.

Поле Тип Описание
force_reply True Shows reply interface to the user, as if they manually selected the bot‘s message and tapped ’Reply’
selective Boolean Опционально. Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot’s message is a reply (has reply_to_message_id), sender of the original message.
Пример:

A poll bot for groups runs in privacy mode (only receives commands, replies to its messages and mentions). There could be two ways to create a new poll:

  • Explain the user how to send a command with parameters (e.g. /newpoll question answer1 answer2). May be appealing for hardcore users but lacks modern day polish.
  • Guide the user through a step-by-step process. ‘Please send me your question’, ‘Cool, now let’s add the first answer option‘, ’Great. Keep adding answer options, then send /done when you‘re ready’.

The last option is definitely more attractive. And if you use ForceReply in your bot‘s questions, it will receive the user’s answers even if it only receives replies, commands and mentions — without any extra work for the user.

ResponseParameters

Содержит информацию о том, почему запрос не был успешен.

Field Type Description
migrate_to_chat_id Integer Optional. The group has been migrated to a supergroup with the specified identifier. This number may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier.
retry_after Integer Optional. In case of exceeding flood control, the number of seconds left to wait before the request can be repeated

InputFile

This object represents the contents of a file to be uploaded. Must be posted using multipart/form-data in the usual way that files are uploaded via the browser.

Resending files without reuploading

There are two ways of sending a file (photo, sticker, audio etc.). If it‘s a new file, you can upload it using multipart/form-data. If the file is already on our servers, you don’t need to reupload it: each file object has a file_id field, you can simply pass this file_id as a parameter instead.

  • It is not possible to change the file type when resending by file_id. I.e. a video can’t be sent as a photo, a photo can’t be sent as a document, etc.
  • It is not possible to resend thumbnails.
  • Resending a photo by file_id will send all of its sizes.

Inline mode objects

Objects and methods used in the inline mode are described in the Inline mode section.

Доступные методы

All methods in the Bot API are case-insensitive. We support GET and POST HTTP methods. Use either URL query string or application/json or application/x-www-form-urlencoded or multipart/form-data for passing parameters in Bot API requests.
On successful call, a JSON-object containing the result will be returned.

getMe

A simple method for testing your bot’s auth token. Requires no parameters. Returns basic information about the bot in form of a User object.

sendMessage

Use this method to send text messages. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
text String Yes Text of the message to be sent
parse_mode String Необязательный Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot’s message.
disable_web_page_preview Boolean Необязательный Disables link previews for links in this message
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

Formatting options

The Bot API supports basic formatting for messages. You can use bold and italic text, as well as inline links and pre-formatted code in your bots’ messages. Telegram clients will render them accordingly. You can use either markdown-style or HTML-style formatting.

Note that Telegram clients will display an alert to the user before opening an inline link (‘Open this link?’ together with the full URL).

Markdown style

To use this mode, pass Markdown in the parse_mode field when using sendMessage. Use the following syntax in your message:

*bold text* _italic text_ [text](URL) `inline fixed-width code` ```pre-formatted fixed-width code block```
HTML style

To use this mode, pass HTML in the parse_mode field when using sendMessage. The following tags are currently supported:

bold, bold italic, italic inline URL inline fixed-width code 
pre-formatted fixed-width code block

  • Only the tags mentioned above are currently supported.
  • Tags must not be nested.
  • All < , >and & symbols that are not a part of a tag or an HTML entity must be replaced with the corresponding HTML entities ( < with < , >with > and & with & ).
  • All numerical HTML entities are supported.
  • The API currently supports only the following named HTML entities: < , > , & and " .

forwardMessage

Use this method to forward messages of any kind. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
from_chat_id Integer or String Yes Unique identifier for the chat where the original message was sent (or channel username in the format @channelusername )
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
message_id Integer Yes Unique message identifier

sendPhoto

Use this method to send photos. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
photo InputFile or String Yes Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo using multipart/form-data.
caption String Необязательный Photo caption (may also be used when resending photos by file_id), 0-200 characters
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendAudio

Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. On success, the sent Message is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.

For sending voice messages, use the sendVoice method instead.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
audio InputFile or String Yes Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data.
caption Integer Необязательный Название аудио, 0-200 символов
duration Integer Необязательный Duration of the audio in seconds
performer String Необязательный Performer
title String Необязательный Track name
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendDocument

Use this method to send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
document InputFile or String Yes File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file using multipart/form-data.
caption String Необязательный Document caption (may also be used when resending documents by file_id), 0-200 characters
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendSticker

Use this method to send .webp stickers. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
sticker InputFile or String Yes Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker using multipart/form-data.
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendVideo

Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
video InputFile or String Yes Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
duration Integer Необязательный Duration of sent video in seconds
width Integer Необязательный Video width
height Integer Необязательный Video height
caption String Необязательный Video caption (may also be used when resending videos by file_id), 0-200 characters
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendVoice

Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Audio or Document). On success, the sent Message is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
voice InputFile or String Yes Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data.
caption Integer Необязательный Название аудиосообщения, 0-200 символов
duration Integer Необязательный Duration of sent audio in seconds
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendLocation

Use this method to send point on the map. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
latitude Float number Yes Latitude of location
longitude Float number Yes Longitude of location
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendVenue

Use this method to send information about a venue. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
latitude Float number Yes Latitude of the venue
longitude Float number Yes Longitude of the venue
title String Yes Name of the venue
address String Yes Address of the venue
foursquare_id String Необязательный Foursquare identifier of the venue
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide reply keyboard or to force a reply from the user.

sendContact

Use this method to send phone contacts. On success, the sent Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
phone_number String Yes Contact’s phone number
first_name String Yes Contact’s first name
last_name String Необязательный Contact’s last name
disable_notification Boolean Необязательный Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Необязательный If the message is a reply, ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or ForceReply Необязательный Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to hide keyboard or to force a reply from the user.

sendChatAction

Use this method when you need to tell the user that something is happening on the bot’s side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).

Пример:

The ImageBot needs some time to process a request and upload the image. Instead of sending a text message along the lines of “Retrieving image, please wait…”, the bot may use sendChatAction with action = upload_photo. The user will see a “sending photo” status for the bot.

We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername )
action String Yes Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location data.

getUserProfilePhotos

Use this method to get a list of profile pictures for a user. Returns a UserProfilePhotos object.

Параметры Тип Обязательный Описание
user_id Integer Yes Unique identifier of the target user
offset Integer Необязательный Sequential number of the first photo to be returned. By default, all photos are returned.
limit Integer Необязательный Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100.

getFile

Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. On success, a File object is returned. The file can then be downloaded via the link https://api.telegram.org/file/bot/ , where is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling getFile again.

Параметры Тип Обязательный Описание
file_id String Yes File identifier to get info about

kickChatMember

Use this method to kick a user from a group or a supergroup. In the case of supergroups, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. The bot must be an administrator in the group for this to work. Returns True on success.

Внимание:

This will method only work if the ‘All Members Are Admins’ setting is off in the target group. Otherwise members may only be removed by the group’s creator or by the member that added them.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername )
user_id Integer Yes Unique identifier of the target user

unbanChatMember

Use this method to unban a previously kicked user in a supergroup. The user will not return to the group automatically, but will be able to join via link, etc. The bot must be an administrator in the group for this to work. Returns True on success.

Параметры Тип Обязательный Описание
chat_id Integer or String Yes Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername )
user_id Integer Yes Unique identifier of the target user

answerCallbackQuery

Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. On success, True is returned.

Параметры Тип Обязательный Описание
callback_query_id String Yes Unique identifier for the query to be answered
text String Необязательный Text of the notification. If not specified, nothing will be shown to the user
show_alert Boolean Необязательный If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false.
url String Необязательный URL, который будет открыт у пользователя. Если вы создали игру, приняв условия @Botfather, укажите адрес, на котором расположена ваша игра. Учтите, что это будет работать только если запрос исходит от кнопки callback_game.
В остальных случаях вы можете использовать параметр для создания ссылок вида telegram.me/your_bot?start=XXXX

Inline mode methods

Methods and objects used in the inline mode are described in the Inline mode section.

Updating messages

The following methods allow you to change an existing message in the message history instead of sending a new one with a result of an action. This is most useful for messages with inline keyboards using callback queries, but can also help reduce clutter in conversations with regular chat bots.

Please note, that it is currently only possible to edit messages without reply_markup or with inline keyboards.

editMessageText

Use this method to edit text messages sent by the bot or via the bot (for inline bots). On success, the edited Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String No Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername )
message_id Integer No Required if inline_message_id is not specified. Unique identifier of the sent message
inline_message_id String No Required if chat_id and message_id are not specified. Identifier of the inline message
text String Yes New text of the message
parse_mode String Необязательный Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot’s message.
disable_web_page_preview Boolean Необязательный Disables link previews for links in this message
reply_markup InlineKeyboardMarkup Необязательный A JSON-serialized object for an inline keyboard.

editMessageCaption

Use this method to edit captions of messages sent by the bot or via the bot (for inline bots). On success, the edited Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String No Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername )
message_id Integer No Required if inline_message_id is not specified. Unique identifier of the sent message
inline_message_id String No Required if chat_id and message_id are not specified. Identifier of the inline message
caption String Необязательный New caption of the message
reply_markup InlineKeyboardMarkup Необязательный A JSON-serialized object for an inline keyboard.

editMessageReplyMarkup

Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). On success, the edited Message is returned.

Параметры Тип Обязательный Описание
chat_id Integer or String No Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername )
message_id Integer No Required if inline_message_id is not specified. Unique identifier of the sent message
inline_message_id String No Required if chat_id and message_id are not specified. Identifier of the inline message
reply_markup InlineKeyboardMarkup Необязательный A JSON-serialized object for an inline keyboard.

Inline-режим

The following methods and objects allow your bot to work in inline mode.
Please see our Introduction to Inline bots for more details.

To enable this option, send the /setinline command to @BotFather and provide the placeholder text that the user will see in the input field after typing your bot’s name.

InlineQuery

This object represents an incoming inline query. When the user sends an empty query, your bot could return some default or trending results.

Поле Тип Описание
id String Unique identifier for this query
from User Sender
location Location Опционально. Sender location, only for bots that request user location
query String Text of the query
offset String Offset of the results to be returned, can be controlled by the bot

answerInlineQuery

Use this method to send answers to an inline query. On success, True is returned.
No more than 50 results per query are allowed.

InlineQueryResult

This object represents one result of an inline query. Telegram clients currently support results of the following 19 types:

  • InlineQueryResultCachedAudio
  • InlineQueryResultCachedDocument
  • InlineQueryResultCachedGif
  • InlineQueryResultCachedMpeg4Gif
  • InlineQueryResultCachedPhoto
  • InlineQueryResultCachedSticker
  • InlineQueryResultCachedVideo
  • InlineQueryResultCachedVoice
  • InlineQueryResultArticle
  • InlineQueryResultAudio
  • InlineQueryResultContact
  • InlineQueryResultDocument
  • InlineQueryResultGif
  • InlineQueryResultLocation
  • InlineQueryResultMpeg4Gif
  • InlineQueryResultPhoto
  • InlineQueryResultVenue
  • InlineQueryResultVideo
  • InlineQueryResultVoice

InlineQueryResultArticle

Represents a link to an article or web page.

Поле Тип Описание
type String Type of the result, must be article
id String Unique identifier for this result, 1-64 Bytes
title String Title of the result
input_message_content InputMessageContent Content of the message to be sent
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
url String Опционально. URL of the result
hide_url Boolean Опционально. Pass True, if you don’t want the URL to be shown in the message
description String Опционально. Short description of the result
thumb_url String Опционально. Url of the thumbnail for the result
thumb_width Integer Опционально. Thumbnail width
thumb_height Integer Опционально. Thumbnail height

InlineQueryResultPhoto

Represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo.

Поле Тип Описание
type String Type of the result, must be photo
id String Unique identifier for this result, 1-64 bytes
photo_url String A valid URL of the photo. Photo must be in jpeg format. Photo size must not exceed 5MB
thumb_url String URL of the thumbnail for the photo
photo_width Integer Опционально. Width of the photo
photo_height Integer Опционально. Height of the photo
title String Опционально. Title for the result
description String Опционально. Short description of the result
caption String Опционально. Caption of the photo to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the photo

InlineQueryResultGif

Represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.

Поле Тип Описание
type String Type of the result, must be gif
id String Unique identifier for this result, 1-64 bytes
gif_url String A valid URL for the GIF file. Размер файла must not exceed 1MB
gif_width Integer Опционально. Width of the GIF
gif_height Integer Опционально. Height of the GIF
thumb_url String URL of the static thumbnail for the result (jpeg or gif)
title String Опционально. Title for the result
caption String Опционально. Caption of the GIF file to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content inputMessageContent Опционально. Content of the message to be sent instead of the GIF animation

InlineQueryResultMpeg4Gif

Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.

Поле Тип Описание
type String Type of the result, must be mpeg4_gif
id String Unique identifier for this result, 1-64 bytes
mpeg4_url String A valid URL for the MP4 file. Размер файла must not exceed 1MB
mpeg4_width Integer Опционально. Video width
mpeg4_height Integer Опционально. Video height
thumb_url String URL of the static thumbnail (jpeg or gif) for the result
title String Опционально. Title for the result
caption String Опционально. Caption of the MPEG-4 file to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the video animation

InlineQueryResultVideo

Represents a link to a page containing an embedded video player or a video file. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video.

Поле Тип Описание
type String Type of the result, must be video
id String Unique identifier for this result, 1-64 bytes
video_url String A valid URL for the embedded video player or video file
mime_type String Mime type of the content of video url, “text/html” or “video/mp4”
thumb_url String URL of the thumbnail (jpeg only) for the video
title String Title for the result
caption String Опционально. Caption of the video to be sent, 0-200 characters
video_width Integer Опционально. Video width
video_height Integer Опционально. Video height
video_duration Integer Опционально. Video duration in seconds
description String Опционально. Short description of the result
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the video

InlineQueryResultAudio

Represents a link to an mp3 audio file. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio.

Поле Тип Описание
type String Type of the result, must be audio
id String Unique identifier for this result, 1-64 bytes
audio_url String A valid URL for the audio file
title String Title
caption Integer Необязательный Название аудио, 0-200 символов
performer String Опционально. Performer
audio_duration Integer Опционально. Audio duration in seconds
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the audio

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultVoice

Represents a link to a voice recording in an .ogg container encoded with OPUS. By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the the voice message.

Поле Тип Описание
type String Type of the result, must be voice
id String Unique identifier for this result, 1-64 bytes
voice_url String A valid URL for the voice recording
title String Recording title
caption Integer Необязательный Название голосового сообщения, 0-200 символов
voice_duration Integer Опционально. Recording duration in seconds
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the voice recording

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultDocument

Represents a link to a file. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method.

Поле Тип Описание
type String Type of the result, must be document
id String Unique identifier for this result, 1-64 bytes
title String Title for the result
caption String Опционально. Caption of the document to be sent, 0-200 characters
document_url String A valid URL for the file
mime_type String Mime type of the content of the file, either “application/pdf” or “application/zip”
description String Опционально. Short description of the result
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the file
thumb_url String Опционально. URL of the thumbnail (jpeg only) for the file
thumb_width Integer Опционально. Thumbnail width
thumb_height Integer Опционально. Thumbnail height

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultLocation

Represents a location on a map. By default, the location will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the location.

Поле Тип Описание
type String Type of the result, must be location
id String Unique identifier for this result, 1-64 Bytes
latitude Float number Location latitude in degrees
longitude Float number Location longitude in degrees
title String Location title
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the location
thumb_url String Опционально. Url of the thumbnail for the result
thumb_width Integer Опционально. Thumbnail width
thumb_height Integer Опционально. Thumbnail height

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultVenue

Represents a venue. By default, the venue will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the venue.

Поле Тип Описание
type String Type of the result, must be venue
id String Unique identifier for this result, 1-64 Bytes
latitude Float Latitude of the venue location in degrees
longitude Float Longitude of the venue location in degrees
title String Title of the venue
address String Address of the venue
foursquare_id String Опционально. Foursquare identifier of the venue if known
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the venue
thumb_url String Опционально. Url of the thumbnail for the result
thumb_width Integer Опционально. Thumbnail width
thumb_height Integer Опционально. Thumbnail height

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultContact

Represents a contact with a phone number. By default, this contact will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the contact.

Поле Тип Описание
type String Type of the result, must be contact
id String Unique identifier for this result, 1-64 Bytes
phone_number String Contact’s phone number
first_name String Contact’s first name
last_name String Опционально. Contact’s last name
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the contact
thumb_url String Опционально. Url of the thumbnail for the result
thumb_width Integer Опционально. Thumbnail width
thumb_height Integer Опционально. Thumbnail height

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultCachedPhoto

Represents a link to a photo stored on the Telegram servers. By default, this photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo.

Поле Тип Описание
type String Type of the result, must be photo
id String Unique identifier for this result, 1-64 bytes
photo_file_id String A valid file identifier of the photo
title String Опционально. Title for the result
description String Опционально. Short description of the result
caption String Опционально. Caption of the photo to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the photo

InlineQueryResultCachedGif

Represents a link to an animated GIF file stored on the Telegram servers. By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with specified content instead of the animation.

Поле Тип Описание
type String Type of the result, must be gif
id String Unique identifier for this result, 1-64 bytes
gif_file_id String A valid file identifier for the GIF file
title String Опционально. Title for the result
caption String Опционально. Caption of the GIF file to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the GIF animation

InlineQueryResultCachedMpeg4Gif

Represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.

Поле Тип Описание
type String Type of the result, must be mpeg4_gif
id String Unique identifier for this result, 1-64 bytes
mpeg4_file_id String A valid file identifier for the MP4 file
title String Опционально. Title for the result
caption String Опционально. Caption of the MPEG-4 file to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the video animation

InlineQueryResultCachedSticker

Represents a link to a sticker stored on the Telegram servers. By default, this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the sticker.

Поле Тип Описание
type String Type of the result, must be sticker
id String Unique identifier for this result, 1-64 bytes
sticker_file_id String A valid file identifier of the sticker
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the sticker

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultCachedDocument

Represents a link to a file stored on the Telegram servers. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only pdf-files and zip archives can be sent using this method.

Поле Тип Описание
type String Type of the result, must be document
id String Unique identifier for this result, 1-64 bytes
title String Title for the result
document_file_id String A valid file identifier for the file
description String Опционально. Short description of the result
caption String Опционально. Caption of the document to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the file

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultCachedVideo

Represents a link to a video file stored on the Telegram servers. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video.

Поле Тип Описание
type String Type of the result, must be video
id String Unique identifier for this result, 1-64 bytes
video_file_id String A valid file identifier for the video file
title String Title for the result
description String Опционально. Short description of the result
caption String Опционально. Caption of the video to be sent, 0-200 characters
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the video

InlineQueryResultCachedVoice

Represents a link to a voice message stored on the Telegram servers. By default, this voice message will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the voice message.

Поле Тип Описание
type String Type of the result, must be voice
id String Unique identifier for this result, 1-64 bytes
voice_file_id String A valid file identifier for the voice message
title String Voice message title
caption Integer Необязательный Название аудиосообщения, 0-200 символов
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the voice message

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InlineQueryResultCachedAudio

Represents a link to an mp3 audio file stored on the Telegram servers. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio.

Поле Тип Описание
type String Type of the result, must be audio
id String Unique identifier for this result, 1-64 bytes
caption Integer Необязательный Название аудио, 0-200 символов
audio_file_id String A valid file identifier for the audio file
reply_markup InlineKeyboardMarkup Опционально. An Inline keyboard attached to the message
input_message_content InputMessageContent Опционально. Content of the message to be sent instead of the audio

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InputMessageContent

This object represents the content of a message to be sent as a result of an inline query. Telegram clients currently support the following 4 types:

  • InputTextMessageContent
  • InputLocationMessageContent
  • InputVenueMessageContent
  • InputContactMessageContent

InputTextMessageContent

Represents the content of a text message to be sent as the result of an inline query.

Поле Тип Описание
message_text String Text of the message to be sent, 1-4096 characters
parse_mode String Опционально. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot’s message.
disable_web_page_preview Boolean Опционально. Disables link previews for links in the sent message

InputLocationMessageContent

Represents the content of a location message to be sent as the result of an inline query.

Поле Тип Описание
latitude Float Latitude of the location in degrees
longitude Float Longitude of the location in degrees

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InputVenueMessageContent

Represents the content of a venue message to be sent as the result of an inline query.

Поле Тип Описание
latitude Float Latitude of the venue in degrees
longitude Float Longitude of the venue in degrees
title String Name of the venue
address String Address of the venue
foursquare_id String Опционально. Foursquare identifier of the venue, if known

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

InputContactMessageContent

Represents the content of a contact message to be sent as the result of an inline query.

Поле Тип Описание
phone_number String Contact’s phone number
first_name String Contact’s first name
last_name String Опционально. Contact’s last name

Note: This will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.

ChosenInlineResult

Represents a result of an inline query that was chosen by the user and sent to their chat partner.

Поле Тип Описание
result_id String The unique identifier for the result that was chosen
from User The user that chose the result
location Location Опционально. Sender location, only for bots that require user location
inline_message_id String Опционально. Identifier of the sent inline message. Available only if there is an inline keyboard attached to the message. Will be also received in callback queries and can be used to edit the message.
query String The query that was used to obtain the result

Игры

Боты теперь умеют предоставлять пользователям возможность поиграть в HTML5-игры. Создать игру можно при помощи бота @BotFather и команды /newgame. Обратите внимание, что для создания игры вам нужно принять соглашение.

  • Игры — новый тип контента, представленный объектами Game и InlineQueryResultGame.
  • Как только вы создали игру с помощью бота BotFather, вы сможее отправлять игры в чаты или при помощи метода sendGame, или используя встроенный режим с методом InlineQueryResultGame.
  • Если вы отправите сообщение с игрой без каких-либо кнопок, к нему автоматически добавится кнопка ‘Играть в ИмяИгры‘. Когда кто-то нажмёт на эту кнопку, вашему боту придёт CallbackQuery с параметром game_short_name. После этого вы должны предоставить корректный URL страницы с игрой, который автоматически откроется во встроенном браузере у пользователя.
  • Вы можете сами добавить сколько угодно кнопок к сообщению с игрой. Пожалуйста, обратите внимание, что первая кнопка в первом ряду всегда должна открывать игру. Для этого существует поле callback_game в объекте InlineKeyboardButton. Остальные кнопки могут быть какими угодно: ссылки на сайт игры, вызов правил, и т. д.
  • Чтобы описание игры выглядело более привлекательно, вы можете загрузить GIF-анимацию с геймплеем игры. Сделать это можно при помощи бота BotFather (пример такой игры: Lumberjack).
  • В сообщении с игрой также будет отображаться таблица рекордов для текущего чата. Чтобы отображать рекорды в чате с игрой, вы можете использовать метод setGameScore. Добавьте параметр edit_message, чтобы автоматически обновлять сообщение с таблицей рекордов.
  • Чтобы отобразить таблицу рекордов прямо в вашем приложении, используйте метод getGameHighScores.
  • Вы можете добавить кнопки «Поделиться», которые позволят пользователям отправлять свои результаты в чаты или группы.
sendGame

Этот метод используется для отправки игры в виде обычного сообщения. В случае успеха возвращает объект с отправленным сообщением Message.

Параметры Тип Обязательный? Описание
chat_id Integer или String Да Уникальный идентификатор целевого чата или юзернейм целевого канала (в формате @channelusername )
game_short_name String Да Короткое название игры, служит уникальным идентификатором игры. Задаётся в Botfather.
disable_notification Boolean Optional Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
reply_to_message_id Integer Нет Если сообщение является ответом, ID оригинального сообщения
reply_markup InlineKeyboardMarkup или ReplyKeyboardMarkup или ReplyKeyboardHide или ForceReply Нет Дополнительные параметры интерфейса. Сериализованные в JSON встроенные клавиатуры, обычные клавиатуры, инструкция скрыть клавиатуру или принудительного ответа.
Game

Этот объект представляет собой игру.

Поле Тип Описание
title String Название игры
description String Описание игры
photo Массив объектов PhotoSize Изображение, которое будет показываться в качестве обложки игры.
text String Опционально. Краткое описание игры или таблицы рекордов в сообщении с игрой. Может быть автоматически отредактировано, чтобы показывать текущую таблицу рекордов для игры при вызове ботом метода setGameScore, или ручном редактировании методом editMessageText. 0-4096 символов.
text_entities Массив объектов MessageEntity Опционально. Сущности в сообщении, типа имён пользователей, ссылок, команд и т. д.
animation Animation Опционально. Анимация, которая будет показана в опиании игры в сообщении.
Animation

Чтобы сообщение с игрой выглядело более привлекательно, вы можете загрузить для игры анимацию с геймплее. Этот объект представляет собой файл анимации, который будет отображён в сообщении с игрой.

Поле Тип Описание
file_id String Уникальный идентификатор файла
thumb PhotoSize Опционально. Превью анимации, заданное отправителем
file_name String Опционально. Название файла анимации, заданное отправителем
mime_type String Опционально. MIME-тип файла анимации, заданное отправителем
file_size Integer Опционально. Размер файла/td>
CallbackGame

Заглушка, пока не содержит никакой информации.

setGameScore

Используйте этот метод, чтобы обновить игровой счёт определённого пользователя. Если сообщение было отправлено ботом, вернёт отредактированное сообщение Message, иначе True. Вернёт ошибку, если вы попытаетесь установить новый счёт меньше, чем текущий.

Параметры Тип Обязательный? Описание
user_id Integer Да Идентификатор пользователя
score Integer Да Новый счёт, больше нуля
chat_id Integer или String Нет Необходим, если не указан inline_message_id. Уникальный идентификатор чата или имя пользователя канала (в формате @channelusername ).
message_id Integer Нет Необходим, если не указан inline_message_id. Уникальный идентификатор отправленного сообщения
inline_message_id String Нет Необходим, если не указан chat_id или inline_message_id. Идентификатор встроенного сообщения
edit_message Boolean Нет Передайте True, чтобы в сообщение была автоматически встроена таблица рекордов
getGameHighScores

Используйте этот метод, чтобы получить данные для таблицы рекордов. Этот метод возвращает счёт указанного пользователя и нескольких его соседей по таблице. В случает успеха вернёт массив объектов GameHighScore.

На текущий момент этот метод возвращает счёт пользователя и двух его ближайших соседей сверху и снизу. Кроме того вернёт топ-3 результатов, если запрошенный пользователь не находится среди них.
В ближайшем будущем количество отдаваемых данных будет изменено.

Параметры Тип Обязательный? Описание
user_id Integer Да Идентификатор пользователя
chat_id Integer или String Нет Необходим, если не указан inline_message_id. Уникальный идентификатор чата или имя пользователя канала (в формате @channelusername ).
message_id Integer Нет Необходим, если не указан inline_message_id. Уникальный идентификатор отправленного сообщения
inline_message_id String Нет Необходим, если не указан chat_id или inline_message_id. Идентификатор встроенного сообщения
GameHighScore

Этот объект представляет собой один из рядов таблицы рекордов игры.

Поле Тип Описание
position Integer Место в таблице результатов
user User Пользователь
score Integer Счёт

Сайт про Telegram на русском (неофициальный).

Здесь собраны приложения на базе MTProto, переведена некоторая документация с официального сайта, а также работает Webogram.

Ошибка с кодом 400: CHAT_ADMIN_REQUIRED

Для этого в указанном чате требуются права администратора чата (например, чтобы отправить сообщение в канале, который не принадлежит вам), или используются недопустимые разрешения для канала или группы.

Решение проблемы:

Если Вы работаете с Вашим аккаунтом и Вашей группой (пабликом), выдайте Вашему аккаунту в этой группе права администратора!

Выше предоставлено описание и возможное решение ошибки Телеграм с кодом 400 «CHAT_ADMIN_REQUIRED».

Вам, как пользователю программы стоит понимать, что данная ошибка может возникнуть как внезапно (например, если Ваш аккаунт уткнется в лимит Телеграм) так и прогнозируемо (например, если Вы не добавите аккаунт в Телеграм, или если Вы забыли добавить текст сообщения).

Однако, Вам стоить помнить что предложенный способ решения проблемы может не всегда быть подходящим для Вас. Но вы всегда можете найти эту ошибку в интернете. Возможно, там вы найдете более точный способ решения Вашей проблемы.

Так же, Вам нужно понимать что автор программы Telegram-Spam-Master может не знать, как решить вашу ошибку. Так что если в процессе поисков Вы найдете решение самостоятельно, было бы очень хорошо, если бы Вы поделились с ним этим решением!

Телеграм-боты на NodeJS

Несколько месяцев назад как-то больше по приколу написал телеграм-бота с интеграцией GPT. Это было, кстати, ещё до того, как весь телеграм утонул в этих ботах. После этого решил, что можно попробовать эту область на фрилансе. За эти месяцы сделал миллион всяких телеграм-ботов с GPT, другими нейронками с доступным API (и даже недоступным в случае с Midjourney), всякие магазины и тому прочих ботов. Этот опыт позволил прошариться немного за телеграм-ботов и в этом материале расскажу об основных моментах, с которыми Вы скорее всего столкнётесь при написании телеграм-ботов на NodeJS. Если есть чем меня дополнить или, возможно, поправить, то буду рад обратной связи.

Начало работы

Для начала создадим NodeJS проект и установим туда пакет для работы с телеграм-ботом через npm:

npm init
npm i node-telegram-bot-api

И инициализируем библиотеку для работы с телеграм-ботом в проект:

const TelegramBot = require('node-telegram-bot-api');

Далее нам нужно создать экземпляр класса TelegramBot. В конструктор нам необходимо передать токен нашего бота (создать бота и получить токен для него можно в BotFather):

const bot = new TelegramBot(process.env.API_KEY_BOT, < polling: true >);

Я для хранения таких переменных, как токен бота, использую модуль dotenv, однако, это можно представить в следующем виде:

const API_KEY_BOT = 'Токен от Вашего бота'; const bot = new TelegramBot(API_KEY_BOT, < polling: true >);

Polling

Обратите внимание, что вместе с токеном бота я передаю объект, в котором включаю polling — это клиент-серверная технология, которая позволяет нам получать обновления с серверов телеграма. Если пользователь что-то написал боту, мы должны об этом как-то узнать и для этого мы будем с определенной периодичностью опрашивать сервер на предмет наличия новых действий пользователя с ботом. Polling можно просто включить указав ему значение true, но его можно настроить передав в значение объект с настройками, например:

const API_KEY_BOT = 'Токен от Вашего бота'; const bot = new TelegramBot(API_KEY_BOT, < polling: < interval: 300, autoStart: true >>);

В данном примере я установил интервал между запросами с клиента на сервер в миллисекундах. autoStart отвечает за то, что наш бот отвечает на те сообщения, которые он пропустил за то время, когда был выключен. Однако, у polling есть ещё настройки, например, можно передать в значение params объект с параметрами такими, как timeout.

Также давайте добавим наш первый слушатель боту — обработаем ошибку polling’а, выведем в консоль сообщение ошибки, если она вообще будет:

bot.on("polling_error", err => console.log(err.data.error.message));

Стоит отметить, что получать наш бот информацию о действиях с ним может не только с помощью технологии polling, но и с помощью webhook.

Обработка и отправка текстового сообщения

Далее обработаем сообщения от пользователей. Для этого сначала добавим слушатель текстового сообщения:

bot.on('text', async msg => < console.log(msg); >)

В данном примере мы добавили слушатель типа ‘text’. Он возвращает нам следующий объект:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: 1686255759, text: ТЕКСТ_СООБЩЕНИЯ, >

Данный объект мы получаем в переменную msg и выводим в консоль. Расскажу немного подробнее про то, какие данные возвращает этот объект и на что стоит обратить внимание. В переменной text содержится само сообщение, которое нам написал пользователь. message_id определяет id сообщения, благодаря чему мы сможем далее обратиться к этому сообщению в обработчике слушателя, а объекты from и chat содержат информацию о том, какой пользователь написал это сообщение и в каком чате — чаще всего, например, id чата и id пользователя будут совпадать, однако, пользователи могут добавить бота в чат и писать ему туда — это тоже стоит учесть. Также бывают случаи, когда имя и ник пользователя могут до нас не дойти через слушатель, например, если пользователь закрыл это дело настройками конфиденциальности в телеграме — это тоже стоит учесть, например, в случае если мы хотим как-то обращаться к пользователю по нику или имени от лица бота.

Теперь мы принимаем какую-то информацию, когда пользователь пишет сообщение боту. Давайте с помощью этой информации построим примитивного эхо-бота — наш бот будет отвечать тем же текстом, что и написал нам пользователь. Для этого используем метод sendMessage, в который передадим id чата, в который мы будем отправлять сообщение, и содержание этого сообщения:

bot.on('text', async msg => < await bot.sendMessage(msg.chat.id, msg.text); >)

Вот так это дело работает:

Эхо-бот отвечает

Давайте немного усложним нашу конструкцию. Практически это смысла иметь не будет, но позволит нам разобрать ещё несколько методов для работы с ботом. Попробуем сначала выводить пользователю сообщение о том, что бот генерирует ответ на сообщение, а затем через 5 секунд бот будет удалять сообщение о генерации ответа и будет скидывать ответ, в нашем случае то же сообщение, что и скинул нам пользователь:

bot.on('text', async msg => < const msgWait = await bot.sendMessage(msg.chat.id, `Бот генерирует ответ. `); setTimeout(async () =>< await bot.deleteMessage(msgWait.chat.id, msgWait.message_id); await bot.sendMessage(msg.chat.id, msg.text); >, 5000); >)

В данном примере, мы скидываем пользователю сообщение о генерации и записываем ответ сервера на запрос отправки сообщения в переменную msgWait. Ответ сервера будет объектом того же вида, что и объект msg. Далее, через пять секунд, используем метод deleteMessage для удаления сообщения о генерации и скидываем сам ответ.

Бот отвечает сообщением о генерации ответаПрошло 5 секунд и бот удалил сообщение о генерации, и ответил тем же текстом

Попробуем немного изменить это дело. Вместо удаления сообщения и отправки нового сделаем отправку сообщения о генерации, а затем через 5 секунд отредактируем это сообщение на наш ответ:

bot.on('text', async msg => < const msgWait = await bot.sendMessage(msg.chat.id, `Бот генерирует ответ. `); setTimeout(async () =>< await bot.editMessageText(msg.text, < chat_id: msgWait.chat.id, message_id: msgWait.message_id >); >, 5000); >)

Для этого мы используем метод editMessageText, в который передаём строку на которую изменим наше сообщение, а также объект с данными о том, в каком чате и какое именно сообщение надо изменить.

Также хочу обратить Ваше внимание на то, что по-хорошему необходимо все наши методы обернуть в конструкцию try/catch, потому что возможен вариант, при котором наш код отлично отрабатывает, всё хорошо написано, однако, пользователь заблокировал бота, и если бот попытается ему написать сообщение, то сервер нам вернёт ошибку и весь бот может крашнуться.

bot.on('text', async msg => < try < await bot.sendMessage(msg.chat.id, msg.text); >catch(error) < console.log(error); >>)

Обрабатываем запуск бота

Далее поговорим про обработку запуска бота. Каждый раз, когда новый пользователь заходит в бота перед ним появляется кнопка «Запустить», вот так это выглядит:

Кнопка запуска бота

Нажав эту кнопку пользователь отправит боту текстовую команду «/start». Сразу встаёт вопрос о том, как обработать это дело, чтобы поприветствовать нового пользователя и возможно записать какую-то информацию о пользователе в базу данных. Конечно, это можно сделать банальным способом и в слушателе текстового сообщения проверять, является ли сообщение пользователя текстовой командой «/start». Выглядеть это будет так:

bot.on('text', async msg => < try < if(msg.text == '/start') < await bot.sendMessage(msg.chat.id, `Вы запустили бота!`); >else < await bot.sendMessage(msg.chat.id, msg.text); >> catch(error) < console.log(error); >>)

Однако, у этого способа есть один минус, с которым лично я столкнулся. В ссылку на запуск бота мы можем передавать параметры и потом читать их. Это полезно, если мы, допустим, захотим сделать реферальную систему. Давайте я покажу, как это будет выглядеть, и в чем проблема. Для этого сделаем обработчик ещё одной команды, назовём её «/ref» и будем по этой команде отдавать пользователю уникальную ссылку на запуск бота:

bot.on('text', async msg => < try < if(msg.text == '/start') < await bot.sendMessage(msg.chat.id, `Вы запустили бота!`); >else if(msg.text == '/ref') < await bot.sendMessage(msg.chat.id, `$?start=$`); > else < await bot.sendMessage(msg.chat.id, msg.text); >> catch(error) < console.log(error); >>)

Обратите внимание, для того чтобы передать какую-то информацию при запуске бота, я передаю в ссылку на запуск бота get-параметр с id пользователя, который получил эту ссылку.

Теперь, когда если мы перейдем по ссылке, у нас будет та же самая кнопка «Запустить», которая отправит «/start» боту. Однако, пользователь видит, что он отправил команду «/start», но нам в боте возвращается уже немного другой объект, выглядеть он будет так:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, text: '/start ID_ПОЛЬЗОВАТЕЛЯ_ИЗ_РЕФЕРАЛЬНОЙ_ССЫЛКИ', entities: [ < offset: 0, length: 6, type: 'bot_command' >] >

В текст сообщения нам возвращается уже не просто «/start», а вместе с ним то, что мы передали в get-параметр в ссылке на запуск. Следовательно, нам надо кое-что изменить в обработчике команды «/start».

bot.on('text', async msg => < try < if(msg.text.startsWith('/start')) < await bot.sendMessage(msg.chat.id, `Вы запустили бота!`); if(msg.text.length >6) < const refID = msg.text.slice(7); await bot.sendMessage(msg.chat.id, `Вы зашли по ссылке пользователя с ID $`); > > else if(msg.text == '/ref') < await bot.sendMessage(msg.chat.id, `$?start=$`); > else < await bot.sendMessage(msg.chat.id, msg.text); >> catch(error) < console.log(error); >>)

Как видите, сначала мы изменили проверку с равенства текста сообщения команде «/start», на проверку, начинается ли текст сообщения с команды «/start». Затем проверяем есть ли ещё какие-то параметры в команде запуска, проверяя длину сообщения (6 в данном случае это длина строки «/start»), а затем вырезаем из текста сообщения команду «/start» вместе с пробелом после неё методом slice и записываем то, что мы передаём в ссылке на запуск бота в переменную.

Сделать это можно и другим способом, используя слушатель onText и регулярные выражения:

bot.onText(/\/start/, async msg => < try < await bot.sendMessage(msg.chat.id, `Вы запустили бота!`); if(msg.text.length >6) < const refID = msg.text.slice(7); await bot.sendMessage(msg.chat.id, `Вы зашли по ссылке пользователя с ID $`); > > catch(error) < console.log(error); >>)

Слушатель принимает регулярное выражение, по которому будет проверять сообщение. Однако, если Вы будете применять данный способ, учтите, что если пользователь запустит бота, то сработает и слушатель onText с регулярным выражением, и слушатель on с типом ‘text’.

Меню команд для бота

Поговорим о том, как создать меню команду для бота. Выглядит меню команд следующим образом:

Меню команд бота

Создать это меню можно в BotFather или с помощью метода setMyCommands. Второй способ мне кажется удобнее и быстрее. В этот метод нам нужно передать массив объектов, в которых указаны сами команды и их описания в меню.

const commands = [ < command: "start", description: "Запуск бота" >, < command: "ref", description: "Получить реферальную ссылку" >, < command: "help", description: "Раздел помощи" >, ] bot.setMyCommands(commands);

Сначала мы задаём массив объектов с нашими командами, а затем передаём его в метод setMyCommands. Я создал команды, которые мы уже использовали до этого, а также создал новую команду help, давайте обработаем её в слушателе:

bot.on('text', async msg => < try < if(msg.text.startsWith('/start')) < await bot.sendMessage(msg.chat.id, `Вы запустили бота!`); if(msg.text.length >6) < const refID = msg.text.slice(7); await bot.sendMessage(msg.chat.id, `Вы зашли по ссылке пользователя с ID $`); > > else if(msg.text == '/ref') < await bot.sendMessage(msg.chat.id, `$?start=$`); > else if(msg.text == '/help') < await bot.sendMessage(msg.chat.id, `Раздел помощи`); >else < await bot.sendMessage(msg.chat.id, msg.text); >> catch(error) < console.log(error); >>)

Форматирование текста

Далее разберемся в форматировании текста в сообщениях. Разберем на примере обработки команды «/help». Для форматирования, стилизации, текста можно использовать либо HTML-верстку, либо Markdown-верстку. Для этого необходимо передавать в строку сообщения текст с тегами, а также передать объект с параметром parse_mode в метод sendMessage. Выглядеть это будет примерно так:

else if(msg.text == '/help') < await bot.sendMessage(msg.chat.id, `Раздел помощи HTML\n\nЖирный Текст\nТекст Курсивом\nТекст с Копированием\nПеречеркнутый текст\nПодчеркнутый текст\n
код на c++

\nГиперссылка`, < parse_mode: "HTML" >); await bot.sendMessage(msg.chat.id, 'Раздел помощи Markdown\n\n*Жирный Текст*\n_Текст Курсивом_\n`Текст с Копированием`\n~Перечеркнутый текст~\n``` код ```\n||скрытый текст||\n[Гиперссылка](t.me)', < parse_mode: "MarkdownV2" >); >

Тогда команда «help» будет выводить нам следующее:

Стилизация текста

Вот список тегов с помощью которых Вы можете стилизовать текст в телеграм-ботах:

HTML:

  • Текст — Жирный текст
  • Текст — Текст курсивом
  • Текст — Текст, который можно скопировать нажатием на него
  • Текст — Перечеркнутый текст
  • Текст — Подчеркнутый текст
  • Текст

    — Текст с оформлением кода

  • Текст — Текст-гиперссылка

Markdown:

  • *Текст* — Жирный текст
  • _Текст_ — Текст курсивом
  • `Текст` — Текст, который можно скопировать нажатием на него
  • ~Текст~ — Перечеркнутый текст
  • «` Текст «` — Текст с оформлением кода
  • || Текст || — Скрытый текст
  • [Текст](Ссылка) — Текст-гиперссылка

Стоит отметить, что все теги должны быть обязательно закрыты, иначе бот не отправит сообщение и вернёт ошибку. В этом плане, я советую делать стилизацию именно с помощью HTML-тегов, так как могут быть проблемы, если вы делаете админку или взаимодействие пользователей со стилизованным текстом. Например, если закинуть ссылку обычным текстом, а не гиперссылкой в сообщение, у которого parse_mode стоит на Markdown, то все нижние подчеркивания будут именно тегами, не отобразятся пользователю, и если их нечетное количество, то сообщение вообще не отправится. Также обратите внимание на то, что переход на следующую строку выполняется при помощи «\n» и в стилизации HTML, и в стилизации Markdown, здесь нельзя использовать тег
из HTML.

Также если мы хотим вставить эмодзи в наше сообщение, то можно просто скопировать эмодзи из телеграмма и вставить в нашу строку в коде, например:

await bot.sendMessage(msg.chat.id, `Вы запустили бота! ����`);

Эмодзи в сообщении

Также ещё подробнее поговорим про ссылки. Если мы укажем ссылку в сообщении, то сообщение придёт пользователю с превью ссылки. Добавлю для этого команду «/link» и её обработчик. Выглядит это так:

else if(msg.text == '/link') < await bot.sendMessage(msg.chat.id, `https://habr.com/`); >

Превью ссылки в сообщении

Если мы хотим убрать превью в сообщении, то нам необходимо передать в метод sendMessage объект с параметром disable_web_page_preview со значением true:

else if(msg.text == '/link') < await bot.sendMessage(msg.chat.id, `https://habr.com/`, < disable_web_page_preview: true, >); >

Сообщение без превьюОтправить без звука

Кстати, в этот же объект, помимо parse_mode и disable_web_page_preview, мы можем передать параметр disable_notification — это позволит отправить сообщение пользователю без уведомления:

else if(msg.text == '/link') < await bot.sendMessage(msg.chat.id, `https://habr.com/`, < disable_web_page_preview: true, disable_notification: true >); >

Меню-клавиатура

Разные меню в боте

Далее обсудим меню-клавиатуру. Меню-клавиатуры делятся на два типа: то меню, которое находится рядом с вводом текста, и меню, которое привязано к сообщению. Между ними есть некоторая разница, о которой мы поговорим дальше. Давайте для начала попробуем создать меню, которое не привязано к сообщению — для удобства я буду его дальше называть просто клавиатура. Для этого создадим ещё одну команду «menu» и обработаем её:

else if(msg.text == '/menu') < await bot.sendMessage(msg.chat.id, `Меню бота`, < reply_markup: < keyboard: [ ['⭐️ Картинка', '⭐️ Видео'], ['⭐️ Аудио', '⭐️ Голосовое сообщение'] ] >>) >

В объект, в который мы раньше передавали параметры disable_web_page_preview, disable_notification, parse_mode теперь передаём reply_markup, который содержит массив массивов keyboard. Обратите внимание, что каждый массив в keyboard — это отдельная строка сверху вниз. То есть мы задаём массивами строки меню, а внутри строк задаём сами кнопки с помощью строк. Выглядеть то, что написано выше, в боте будет так:

Меню-клавиатура

Можем заметить, что кнопки получились какими-то большими. Для того, чтобы задать им адекватные размеры, можно в объект reply_markup передать параметр resize_keyboard со значением true. Давайте так и сделаем, и добавим в меню ещё несколько кнопок:

else if(msg.text == '/menu') < await bot.sendMessage(msg.chat.id, `Меню бота`, < reply_markup: < keyboard: [ ['⭐️ Картинка', '⭐️ Видео'], ['⭐️ Аудио', '⭐️ Голосовое сообщение'], ['⭐️ Контакт', '⭐️ Геолокация'], ['❌ Закрыть меню'] ], resize_keyboard: true >>) >

Меню-клавиатура с параметром resize_keyboard

Далее встаёт вопрос о том, как обработать нажатие кнопки в нашей клавиатуре. Тут всё на самом деле просто. Когда пользователь нажимает на кнопку в меню, он скидывает боту текстовое сообщение с тем текстом, который написан на кнопке, который мы указывали в строках внутри массивов. Следовательно, будем обрабатывать нажатие на кнопку, как обычное текстовое сообщение:

else if(msg.text == '❌ Закрыть меню') < await bot.sendMessage(msg.chat.id, 'Меню закрыто', < reply_markup: < remove_keyboard: true >>) >

В данном примере, мы обработали нажатие кнопки закрытия меню. Обратите внимание на то, что если Вы просто отправите сообщение пользователю, клавиатура у него никуда не пропадёт. Для того, чтобы выключить клавиатуру, передаём параметр remove_keyboard со значением true в reply_markup. Как видим, клавиатура у нас пропала:

Выключение клавиатуры

О том, как создать меню привязанное к сообщению поговорим чуть дальше.

Скидываем и обрабатываем изображение

Сейчас поговорим о том, как скинуть пользователю картинку, и как обработать сообщение с картинкой от пользователя.

Давайте будем скидывать картинку пользователю по нажатию кнопки «⭐️ Картинка» в меню. Саму кнопку мы уже создали, давайте обработаем её нажатие и с помощью метода sendPhoto, в который передадим ссылку на изображение, которое хотим скинуть пользователю:

else if(msg.text == '⭐️ Картинка')

В данном случае, мы скидываем пользователю картинку с помощью ссылки на изображение, однако, мы можем скинуть картинку и просто указав путь до картинки:

else if(msg.text == '⭐️ Картинка') < await bot.sendPhoto(msg.chat.id, './image.jpg'); >

Также можно скинуть картинку используя модуль fs:

else if(msg.text == '⭐️ Картинка') < //Скидываем изображение ссылкой await bot.sendPhoto(msg.chat.id, process.env.URL_TO_IMG); //Скидываем изображение указав путь await bot.sendPhoto(msg.chat.id, './image.jpg'); //Скидываем изображение с помощью Readable Stream const imageStream = fs.createReadStream('./image.jpg'); await bot.sendPhoto(msg.chat.id, imageStream); //Скидываем изображение с помощью буфера const imageBuffer = fs.readFileSync('./image.jpg'); await bot.sendPhoto(msg.chat.id, imageBuffer); >

Теперь наш бот будет вести себя примерно так:

Бот скидывает картинку

Бот скидывает только картинку. Однако, нам может понадобится добавить какую-то подпись к этой картинке. Для этого передаем в метод sendPhoto объект с опциями, надпись можно передать в параметр caption, также можем задать parse_mode, как и в обычном текстовом сообщении:

const imageStream = fs.createReadStream('./image.jpg'); await bot.sendPhoto(msg.chat.id, imageStream, < caption: '⭐️ Картинка', parse_mode: 'HTML' >);

Далее разберемся с тем, как обработать сообщение с изображением от пользователя. Для этого используем слушатель с типом «photo»:

bot.on('photo', async img => < console.log(img); >)

Теперь, когда пользователь скинет сообщение с картинкой, телеграм вернёт нам объект следующего вида:

< message_id: 500, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, photo: [ < file_id: ID_ФАЙЛА, file_unique_id: УНИКАЛЬНЫЙ_ID_ФАЙЛА, file_size: РАЗМЕР_ФАЙЛА, width: ШИРИНА_КАРТИНКИ, height: ВЫСОТА_КАРТИНКИ >, < file_id: ID_ФАЙЛА, file_unique_id: УНИКАЛЬНЫЙ_ID_ФАЙЛА, file_size: РАЗМЕР_ФАЙЛА, width: ШИРИНА_КАРТИНКИ, height: ВЫСОТА_КАРТИНКИ >, < file_id: ID_ФАЙЛА, file_unique_id: УНИКАЛЬНЫЙ_ID_ФАЙЛА, file_size: РАЗМЕР_ФАЙЛА, width: ШИРИНА_КАРТИНКИ, height: ВЫСОТА_КАРТИНКИ >, < file_id: ID_ФАЙЛА, file_unique_id: УНИКАЛЬНЫЙ_ID_ФАЙЛА, file_size: РАЗМЕР_ФАЙЛА, width: ШИРИНА_КАРТИНКИ, height: ВЫСОТА_КАРТИНКИ >] >

Мы похожее уже видели, когда обрабатывали текстовое сообщение. Только теперь мы имеем дело не со строкой text, а с массивом объектов photo. В этом массиве содержится наша картинка. Телеграм принял картинку, хранит у себя на сервере, и вернул нам несколько вариантов нашей картинки в разных размерах. Последний объект в этом массиве — это наш оригинал, а другие объекты содержат нашу картинку, только в сжатом виде. Но как же получить картинку, которую скидывал пользователь по информации содержащейся в объектах? Мы можем получить доступ к нашей картинке по file_id, который возвращает нам телеграм. Например, мы можем скачать файл по file_id с серверов телеграм используя метод downloadFile, в который передаём file_id, который нужно скачать, и директорию в которую будем скачивать файл. Выглядеть это будет так:

bot.on('photo', async img => < try < await bot.downloadFile(img.photo[img.photo.length-1].file_id, './image'); >catch(error) < console.log(error); >>)

Обратите внимание, что для того, чтобы выбрать наш оригинал в индексе массива я указал длину массива минус один — не будем забывать, что мы, программисты, считаем с нуля.

Давайте теперь сделаем следующее: когда пользователь скидывает нам изображение, будем скидывать ему в ответ несколько изображений объединенных в одно сообщение. Эти несколько изображений — это наш оригинал и сжатые его варианты. Для этого воспользуемся методом sendMediaGroup:

bot.on('photo', async img => < try < const photoGroup = []; for(let index = 0; index < img.photo.length; index++) < const photoPath = await bot.downloadFile(img.photo[index].file_id, './image'); photoGroup.push(< type: 'photo', media: photoPath, caption: `Размер файла: $байт\nШирина: $\nВысота: $` >) > await bot.sendMediaGroup(img.chat.id, photoGroup); for(let index = 0; index < photoGroup.length; index++) < fs.unlink(photoGroup[index].media, error => < if(error) < console.log(error); >>) > > catch(error) < console.log(error); >>)

Остановимся на этом поподробнее. В самом начале мы инициализируем массив. Он нам нужен для того, чтобы передать несколько картинок в метод sendMediaGroup и соответственно скинуть эти картинки пользователю. Метод sendMediaGroup принимает массив объектов, в которых мы указываем первым делом тип медиа-контента, в нашем случае это «photo». Также в объекте медиа-контента мы должны передать путь до нашего контента, этим путём могут служить, также как и в случае с методом sendPhoto: url, stream, buffer или путь до контента. Также мы можем указать file_id — его можно тоже указывать при отправке через sendPhoto или через sendMediaGroup, однако, в данном случае этот способ нам не подходит, так как какой бы file_id мы не указали, мы всегда будем скидывать оригинал картинки, а нас интересуют именно сжатые картинки. Дополнительно в объект медиа-контента мы можем передать caption — подпись под картинкой. В данном случае, я добавил в подпись под каждой картинкой её размер в байтах, ширину и высоту в пикселях — всё это нам возвращает телеграм. Теперь пройдясь циклом по всем вариантам нашей картинки, скачав все варианты и записав всю необходимую информацию, передаём наш массив объектов в метод sendMediaGroup, а затем удаляем все картинки, которые только что скачали. И теперь имеем следующее:

Бот скидывает все варианты сжатых картинок и оригиналПодпись под изображением

Скидываем и обрабатываем видео

Далее поговорим о том, как скинуть видео. Тут в общем-то всё аналогично фото, обработаем нажатие на кнопку на «⭐️ Видео» в нашем меню:

else if(msg.text == '⭐️ Видео') < await bot.sendVideo(msg.chat.id, './video.mp4'); >

Также мы туда можем добавить caption и parse_mode, и другие параметры, вроде disable_notification:

else if(msg.text == '⭐️ Видео') < await bot.sendVideo(msg.chat.id, './video.mp4', < caption: '⭐️ Видео', parse_mode: 'HTML' >); >

Бот скидывает видео

Теперь давайте обработаем сообщение пользователя с видео. Делаем это также с помощью слушателя с типом «video»:

bot.on("video", async video => < console.log(video); >)

Телеграм присылает нам следующее, когда пользователь отправляет сообщение с видео:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_СООБЩЕНИЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, video: < duration: ДЛИТЕЛЬНОСТЬ_ВИДЕО, width: ВЫСОТА_ВИДЕО, height: ШИРИНА_ВИДЕО, file_name: ИМЯ_ФАЙЛА, mime_type: ТИП_ФАЙЛА, thumbnail: < file_id: ID_ИЗОБРАЖЕНИЯ, file_unique_id: УНИКАЛЬНОЕ_ID_ИЗОБРАЖЕНИЯ, file_size: РАЗМЕР_ИЗОБРАЖЕНИЯ, width: ШИРИНА_ИЗОБРАЖЕНИЯ, height: ВЫСОТА_ИЗОБРАЖЕНИЯ >, thumb: < file_id: ID_ИЗОБРАЖЕНИЯ, file_unique_id: УНИКАЛЬНОЕ_ID_ИЗОБРАЖЕНИЯ, file_size: РАЗМЕР_ИЗОБРАЖЕНИЯ, width: ШИРИНА_ИЗОБРАЖЕНИЯ, height: ВЫСОТА_ИЗОБРАЖЕНИЯ >, file_id: ID_ВИДЕО, file_unique_id: УНИКАЛЬНОЕ_ID_ВИДЕО, file_size: РАЗМЕР_ВИДЕО > >

Как видим, телеграм предоставляет нам информацию о видео и изображениях. Изображения — это миниатюры видео. Давайте сделаем следующее: когда пользователь скидывает видео, бот будет в ответ кидать само видео, миниатюру и информацию о видео. Выглядеть это будет следующим образом:

bot.on("video", async video => < try < const thumbPath = await bot.downloadFile(video.video.thumbnail.file_id, './image'); await bot.sendMediaGroup(video.chat.id, [ < type: 'video', media: video.video.file_id, caption: `Название файла: $\nВес файла: $ байт\nДлительность видео: $ секунд\nШирина кадра в видео: $\nВысота кадра в видео: $` >, < type: 'photo', media: thumbPath, >]); fs.unlink(thumbPath, error => < if(error) < console.log(error); >>) > catch(error) < console.log(error); >>)

Обратите внимание, что видео-файл я скидываю по его file_id, а миниатюру скачиваю, скидываю и затем удаляю, потому что телеграм не даёт скинуть миниатюру методом sendPhoto по file_id. Также важно, что в этот раз я добавил в методе sendMediaGroup параметр caption лишь к одному медиа-файлу и надпись отобразилась в сообщении.

Также есть важный момент, который нужно учесть. Иногда, когда пользователь скидывает видео, допустим в том же .mp4, телеграм может это сжать и скинуть в .gif.

Скидываем и обрабатываем аудио

Ситуация уже знакомая нам, скидываем аудио также, как видео и фото, обрабатывая кнопку «⭐️ Аудио»:

else if(msg.text == '⭐️ Аудио') < await bot.sendAudio(msg.chat.id, './audio.mp3', < caption: '⭐️ Аудио', parse_mode: 'HTML' >); >

Обработка аудио выполняется тоже похожим образом, только используем слушатель с типом «audio»:

bot.on('audio', async audio => < try < await bot.sendAudio(audio.chat.id, audio.audio.file_id, < caption: `Название файла: $\nВес файла: $ байт\nДлительность аудио: $ секунд` >) > catch(error) < console.log(error); >>)

Бот отвечает на сообщение с аудио-файлом

Телеграм-сервер возвращает похожий на предыдущие примеры объект:

< message_id: 653, from: < id: 764548588, is_bot: false, first_name: 'shavrin', username: 'zloishavrin', language_code: 'ru' >, chat: < id: 764548588, first_name: 'shavrin', username: 'zloishavrin', type: 'private' >, date: 1686339341, audio: < duration: 1, file_name: 'audio.mp3', mime_type: 'audio/mpeg', file_id: 'CQACAgIAAxkBAAICjWSDfw0AAZdXcrZjG-2n840P-NqNIQACOzEAAi3wIUh2fGtPn59fBi8E', file_unique_id: 'AgADOzEAAi3wIUg', file_size: 19776 >>

Хочу обратить внимание на то, что если пользователь скинет несколько видео, фото или аудио одним сообщением, то они не вернутся Вам одним сообщением с массивом audio или video-объектов, просто сработают несколько слушателей и эти файлы будут считаться отдельными сообщениями и обрабатываться будут также отдельно.

С голосовыми ситуация аналогичная, ничего интересного:

else if(msg.text == '⭐️ Голосовое сообщение') < await bot.sendVoice(msg.chat.id, './audio.mp3', < caption: '⭐️ Голосовое сообщение', parse_mode: 'HTML' >); >

И также обрабатываем голосовые сообщения:

bot.on('voice', async voice => < try < await bot.sendAudio(voice.chat.id, voice.voice.file_id, < caption: `Вес файла: $байт\nДлительность аудио: $ секунд` >) > catch(error) < console.log(error); >>)

Бот отвечает на голосовые сообщения

Скидываем, запрашиваем и обрабатываем контакт

Дальше разберемся с тем, как скинуть пользователю контакт. Для этого обработаем кнопку «⭐️ Контакт», используя метод sendContact, в который передадим строку с номером телефона и именем контакта:

else if(msg.text == '⭐️ Контакт') < //Скидываем контакт await bot.sendContact(msg.chat.id, process.env.CONTACT, `Контакт`, < reply_to_message_id: msg.message_id >); >

Обратите внимание, что в телеграме стоит проверка на формат номера, и если мы укажем не номер, то телеграм вернёт нам ошибку.

Также я добавил параметр reply_to_message_id — в этот параметр мы можем передать message_id сообщения, на которое мы хотим ответить сообщением, в которое передаем message_id.

Бот скидывает контакт

Теперь давайте немного изменим нашу кнопку. И вместо того, чтобы просто скидывать контакт, мы сначала будем его запрашивать, а затем обрабатывать. Для этого изменим обработку команды «/menu», в которой мы присылаем пользователю нашу клавиатуру:

else if(msg.text == '/menu') < await bot.sendMessage(msg.chat.id, `Меню бота`, < reply_markup: < keyboard: [ ['⭐️ Картинка', '⭐️ Видео'], ['⭐️ Аудио', '⭐️ Голосовое сообщение'], [, '⭐️ Геолокация'], ['❌ Закрыть меню'] ], resize_keyboard: true > >) >

Как видите, теперь передаём вместо просто строки ‘⭐️ Контакт’ объект с параметрами text и request_contact, тем самым запрашивая контакт пользователя при нажатии на кнопку:

Бот запрашивает контакт пользователя

Теперь обработаем контакт. Для этого добавляем слушатель с типом «contact». Этот слушатель вернёт нам следующий объект, если пользователь скинул контакт:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, reply_to_message: < message_id: ID_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ, from: < id: ID_БОТА, is_bot: true, first_name: ИМЯ_БОТА, username: НИК_БОТА >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ, text: ТЕКСТ_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ >, contact: < phone_number: НОМЕР_КОНТАКТА, first_name: ИМЯ_КОНТАКТА, user_id: ID_ПОЛЬЗОВАТЕЛЯ >>

Давайте обработаем это следующим образом: когда боту приходит контакт, бот скидывает номер и имя контакта, отвечая на сообщение с контактом:

bot.on('contact', async contact => < try < await bot.sendMessage(contact.chat.id, `Номер контакта: $\nИмя контакта: $`); > catch(error) < console.log(error); >>)

Выглядеть это будет так:

Бот обрабатывает сообщение с контактом

Скидываем, запрашиваем и обрабатываем геолокацию

Обработаем нажатие кнопки «⭐️ Геолокация» и будем скидывать пользователю геолокацию Красной Площади, указав широту и долготу нужной нам координаты:

else if(msg.text == '⭐️ Геолокация') < const latitudeOfRedSquare = 55.753700; const longitudeOfReadSquare = 37.621250; await bot.sendLocation(msg.chat.id, latitudeOfRedSquare, longitudeOfReadSquare, < reply_to_message_id: msg.message_id >) >

Бот скидывает геолокацию

Теперь провернём тоже самое, что мы делали с контактами, только для геолокации — сделаем запрос геолокации по кнопке и будем возвращать в ответ на сообщение с геолокацией координаты геолокации (широту и долготу). Начнём с того, что изменим кнопку «⭐️ Геолокация»:

else if(msg.text == '/menu') < await bot.sendMessage(msg.chat.id, `Меню бота`, < reply_markup: < keyboard: [ ['⭐️ Картинка', '⭐️ Видео'], ['⭐️ Аудио', '⭐️ Голосовое сообщение'], [, ], ['❌ Закрыть меню'] ], resize_keyboard: true > >) >

Бот запрашивает геолокацию

Далее обработаем сообщение пользователя с геолокацией. Сообщение с геолокацией возвращает следующий объект:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, reply_to_message: < message_id: ID_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ, from: < id: ID_БОТА, is_bot: true, first_name: ИМЯ_БОТА, username: НИК_БОТА >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ, text: ТЕКСТ_СООБЩЕНИЯ_В_КОТОРОМ_СКИДЫВАЛИ_КНОПКУ >, location: < latitude: ШИРОТА_ГЕОЛОКАЦИИ, longitude: ДОЛГОТА_ГЕОЛОКАЦИИ >>

Сделаем следующий слушатель:

bot.on('location', async location => < try < await bot.sendMessage(location.chat.id, `Широта: $\nДолгота: $`); > catch(error) < console.log(error); >>)

Бот отвечает на сообщение с геолокацией

Делаем ещё одно меню

Выше я уже говорил, что меню можно создать нескольких видов. Выше мы уже создали меню-клавиатуру и меню команд. Теперь создадим меню, как я писал выше, привязанное к сообщению. Далее будем называть это инлайн-клавиатура. Для этого создадим новую команду и обработаем её:

else if(msg.text == '/second_menu') < await bot.sendMessage(msg.chat.id, `Второе меню`, < reply_markup: < inline_keyboard: [ [, ], [], [], [] ] > >) >

Как видим мы также, как с обычной клавиатурой, создаём массив массивов в объекте reply_markup. Каждый массив в inline_keyboard — это новая строка в меню. В отличие от обычной клавиатуры, мы передаём в массив не строки, а объекты с текстом и callback_data. Обрабатывать мы будем нажатия кнопок не обычным текстовым сообщением, а уже коллбеками. Вот так будет выглядеть созданная нами инлайн-клавиатура:

Инлайн-клавиатура

Теперь давайте попробуем обработать кнопку «Закрыть Меню». Для этого будем использовать слушатель с типом «callback_query»:

bot.on('callback_query', async ctx => < try < console.log(ctx); >catch(error) < console.log(error); >>)

Коллбеки возвращают нам с серверов телеграм следующий объект:

< id: ID_КОЛЛБЕКА, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, message: < message_id: ID_СООБЩЕНИЯ, from: < id: ID_БОТА, is_bot: true, first_name: ИМЯ_БОТА, username: НИК_БОТА >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, text: ТЕКСТ_СООБЩЕНИЯ, reply_markup: < inline_keyboard: [Array] >>, chat_instance: ЗАВИСИМЫЙ_ЧАТ, data: КОЛЛБЕК_ДАТА >

Как видим, в объекте возвращается информация о сообщении, к которому привязана кнопка, на которую нажали, информация о пользователе, который нажал кнопку, и самое важное — callback_data, которую мы указывали в кнопке. С помощью вот этого параметра callback_data будем обрабатывать нажатие на кнопку:

bot.on('callback_query', async ctx => < try < switch(ctx.data) < case "closeMenu": await bot.deleteMessage(ctx.message.chat.id, ctx.message.message_id); break; >> catch(error) < console.log(error); >>)

В данном случае, мы удаляем сообщение с нашей инлайн-клавиатурой по нажатию кнопки «Закрыть Меню». Дальше в этом же слушателе будем обрабатывать нажатия других кнопок по параметру callback_data.

Теперь давайте немного модифицируем всё это дело. И наше меню будем скидывать не просто сообщением по команде, а в ответ на сообщение-команду:

else if(msg.text == '/second_menu') < await bot.sendMessage(msg.chat.id, `Второе меню`, < reply_markup: < inline_keyboard: [ [, ], [], [], [] ] >, reply_to_message_id: msg.message_id >) >

Теперь мы можем сделать следующее: в обработчике закрытия меню удалять не только сообщение с самим меню, а ещё и удалять сообщение-команду, по которому было вызвано меню:

case "closeMenu": await bot.deleteMessage(ctx.message.chat.id, ctx.message.message_id); await bot.deleteMessage(ctx.message.reply_to_message.chat.id, ctx.message.reply_to_message.message_id); break;

Мы можем такое сделать, потому что тогда наш коллбек будет возвращать следующий объект:

< id: ID_КОЛЛБЕКА, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, message: < message_id: ID_СООБЩЕНИЯ, from: < id: ID_БОТА, is_bot: true, first_name: ИМЯ_БОТА, username: НИК_БОТА >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, reply_to_message: < message_id: ID_СООБЩЕНИЯ_2, from: [Object], chat: [Object], date: ДАТА, text: КОМАНДА_ВЫЗОВА_МЕНЮ, entities: [Array] >, text: ТЕКСТ_СООБЩЕНИЯ, reply_markup: < inline_keyboard: [Array] >>, chat_instance: ЗАВИСИМЫЙ_ЧАТ, data: КОЛЛБЕК_ДАТА >

Скидываем и обрабатываем стикеры

Далее обработаем нажатие кнопки «Стикер» на нашей инлайн-клавиатуре. Для этого будем использовать метод sendSticker:

case "sticker": await bot.sendSticker(ctx.message.chat.id, `./image.jpg`); break;

Хочу обратить ваше внимание на то, что мы можем скинуть любое изображение стикером, аналогично тому, как мы это делали с методом sendPhoto.

Теперь обработаем сообщение пользователя со стикером с помощью слушателя с типом «sticker», который будет возвращать нам следующий объект:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, sticker: < width: ШИРИНА_СТИКЕРА, height: ДЛИНА_СТИКЕРА, emoji: '��', //ЭМОДЗИ К КОТОРОМУ ПРИВЯЗАН СТИКЕР set_name: ИМЯ_СТИКЕРА, is_animated: false, //БУЛЕВА ПЕРЕМЕННАЯ, КОТОРАЯ ОТОБРАЖАЕТ АНИМИРОВАН СТИКЕР ИЛИ НЕТ is_video: false, //БУЛЕВА ПЕРЕМЕННАЯ, КОТОРАЯ ОТОБРАЖАЕТ СТИКЕР ВИДЕОФОРМАТА ИЛИ НЕТ type: 'regular', thumbnail: < file_id: ID_МИНИАТЮРЫ, file_unique_id: УНИКАЛЬНЫЙ_ID_МИНИАТЮРЫ, file_size: РАЗМЕР_МИНИАТЮРЫ, width: ШИРИНА_МИНИАТЮРЫ, height: ДЛИНА_МИНИАТЮРЫ >, thumb: < file_id: ID_МИНИАТЮРЫ, file_unique_id: УНИКАЛЬНЫЙ_ID_МИНИАТЮРЫ, file_size: РАЗМЕР_МИНИАТЮРЫ, width: ШИРИНА_МИНИАТЮРЫ, height: ДЛИНА_МИНИАТЮРЫ >, file_id: ID_ФАЙЛА_СТИКЕРА, file_unique_id: УНИКАЛЬНЫЙ_ID_ФАЙЛА_СТИКЕРА, file_size: РАЗМЕР_ФАЙЛА_СТИКЕРА > >

Давайте теперь сделаем следующее: когда пользователь скидывает стикер, будем проверять, какого вида стикер используя информацию из объекта (булевы переменные) и будем скидывать стикер пользователю картинкой, видео или анимацией:

bot.on('sticker', async sticker => < try < const stickerPath = await bot.downloadFile(sticker.sticker.file_id, './image'); if(sticker.sticker.is_video) < await bot.sendVideo(sticker.chat.id, stickerPath); >else if(sticker.sticker.is_animated) < await bot.sendAnimation(sticker.chat.id, stickerPath); >else < await bot.sendPhoto(sticker.chat.id, stickerPath); >fs.unlink(stickerPath, error => < if(error) < console.log(error); >>) > catch(error) < console.log(error); >>)

Бот отвечает на сообщение со стикером

Обратите внимание, что я сделал некрасиво: в любом случае, будь стикер анимацей, видео или картинкой скачиваю файл в папку с названием «image» — так лучше, конечно, не делать. Также я не отправляю файлы по file_id, а скачиваю и затем их отправляю, потому что если попробовать скинуть стикер-файл по file_id используя методы sendPhoto или sendVideo, телеграм вернёт ошибку о том, что нельзя скинуть файл типа «стикер», как «фото» или «видео», однако, метод sendAnimation позволяет отправлять стикеры анимацией по их file_id, тогда это будет выглядеть следующим образом:

else if(sticker.sticker.is_animated)

Круглое видео

Обработаем кнопку «Круглое Видео», по нажатию на которую будем скидывать пользователю видео круглого формата. Сделать это можно с помощью метода sendVideoNote:

case "circleVideo": await bot.sendVideoNote(ctx.message.chat.id, './video.mp4'); break;

В общем-то с круглыми видео ничего интересного нету — всё аналогично обычному видео. Кстати, в объект опций мы можем передать параметр protect_content со значением true и пользователь не сможет пересылать сообщение:

case "circleVideo": await bot.sendVideoNote(ctx.message.chat.id, './video.mp4', < protect_content: true >); break;

Проверка подписки на канал

Далее разберемся с тем, как сделать, чтобы бот проверял подписку на канал. Для этого необходимо поставить бота админом канала, на который он будет проверять подписку и использовать метод getChatMember:

case "checkSubs": const subscribe = await bot.getChatMember(process.env.ID_CHAT, ctx.from.id); console.log(subscribe); break;

В этот метод передаём ID нашего канала или чата — получить этот ID можно, например, скинув ссылку на канал или чат в специального бота, который возвращает ID, он будет в формате «-100XXXXXXXXXX», и также передаём в этот метод ID пользователя, подписку которого будем проверять. Данный метод вернёт объект такого вида:

< user: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, status: СТАТУС_ПОЛЬЗОВАТЕЛЯ, is_anonymous: false >

Будем обращаться к статусу пользователя. Статусы бывают следующие:

  • left — пользователь не подписан
  • kicked — пользователь заблокирован
  • member — пользователь подписан
  • administrator — пользователь является администратором
  • creator — пользователь является создателем

Обработаем статус пользователя и в зависимости от него будем выводить пользователю сообщение:

case "checkSubs": const subscribe = await bot.getChatMember(process.env.ID_CHAT, ctx.from.id); if(subscribe.status == 'left' || subscribe.status == 'kicked') < await bot.sendMessage(ctx.message.chat.id, `Вы не являетесь подписчиком!`, < parse_mode: 'HTML' >) > else < await bot.sendMessage(ctx.message.chat.id, 'Вы являетесь подписчиком!', < parse_mode: 'HTML' >) > break;

Подключаем оплату

Для того, чтобы подключить оплату к своему бота для начала стоит определиться с платежной системой через которую будут совершаться платежи. У телеграма есть хороший выбор стандартных платежный систем, однако, никто не запрещает Вам подключить стороннюю платежную систему, но сейчас разберемся именно со стандартными телеграмовскими платежными системами. Для их подключения необходимо перейти в BotFather, выбрать своего бота, перейти в раздел Payments, а дальше в выбранной Вами платежной системе получить provider token — ключ, по которому мы будем подключать оплату.

Давайте отправим счёт на оплату пользователю по нажатию кнопки «Купить Файл». Для этого будем использовать метод sendInvoice:

case "buyFile": await bot.sendInvoice(ctx.message.chat.id, 'Купить Файл', 'Покупка файла', 'file', process.env.PROVIDER_TOKEN, 'RUB', [< label: 'Файл', amount: 20000 >]); break;

В этот метод мы передаём название платежа, описание платежа, payload — это информация, которая передаётся в платеж, по ней мы будем отслеживать нужный платеж, а у пользователя она нигде не отобразится, провайдер-токен, валюта (в разных платежках поддерживаются разные валюты) и также массив объектов с товарами, которые будет оплачивать пользователь. Обратите внимание, что валютой я указал рубли (код валюты в ISO 4217), а цену на товар указал в копейках. Также можно в метод передать другие параметры, можно добавить миниатюру платежа, включить необходимость ввода некоторых данных для пользователя, а также данные для фискализации платежа.

Далее по кнопке «Купить Файл» пользователю отправится следующее сообщение:

Бот отправляет счёт на оплату

Далее пользователь нажмёт кнопку оплаты, введёт свои данные, и когда подтвердит введённые данные, бот должен отправить окончательное подтверждение перед оформлением заказа. Сделать это можно при помощи обработки такого слушателя:

bot.on('pre_checkout_query', async ctx => < try < await bot.answerPreCheckoutQuery(ctx.id, true); >catch(error) < console.log(error); >>)

Когда мы окончательно подтвердили оформление заказа, пользователь может совершить платеж и мы должны его как-то обработать. Для этого будем использовать слушатель с типом «successful_payment», который возвращает объект следующего вида:

< message_id: ID_СООБЩЕНИЯ, from: < id: ID_ПОЛЬЗОВАТЕЛЯ, is_bot: false, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, language_code: 'ru' >, chat: < id: ID_ЧАТА, first_name: ИМЯ_ПОЛЬЗОВАТЕЛЯ, username: НИК_ПОЛЬЗОВАТЕЛЯ, type: 'private' >, date: ДАТА, successful_payment: < currency: КОД_ВАЛЮТЫ, total_amount: СУММА_ПЛАТЕЖА, invoice_payload: PAYLOAD, telegram_payment_charge_id: ID_ПЛАТЕЖА_ТЕЛЕГРАМ, provider_payment_charge_id: ID_ПЛАТЕЖА_ПЛАТЕЖНАЯ_СИСТЕМА >>

Исходя из этой информации мы можем обработать совершённый платеж, например:

bot.on('successful_payment', async ctx => < try < await bot.sendDocument(ctx.chat.id, `./$.txt`, < caption: `Спасибо за оплату $!` >) > catch(error) < console.log(error); >>)

Используем метод sendDocument для того, чтобы скинуть пользователю файл, который мы находим благодаря информации из payload, и в подписи к нему выводим информацию из payload, которую мы изначально передали в методе sendInvoice. Пользователь увидит следующее:

Бот отвечает на успешный платеж

Заключение

В этом материале постарался максимально просто и с примерами рассказать об основных возможностях телеграм-ботов и как ими управлять с помощью NodeJS. Тут в принципе есть ещё о чем рассказать: веб-хуки для телеграм ботов, управление чатами, каналами, игры и веб-приложения в телеграм-ботах. Если кому-то будет интересна эта тема, то продолжу об этом писать.

Также выложил код всего, что было написано в этой статье на GitHub с комментариями, посмотреть и скачать можно здесь.

  • телеграм бот
  • телеграм бот javascript
  • телеграм бот nodejs
  • телеграм боты
  • telegram
  • telegrambot
  • telegram bot
  • telegram bots
  • javascript
  • nodejs

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *