Боты в Телеграм – это программы, помогающие установить контакт с аудиторией или упростить действия, которые ранее приходилось выполнять вручную. Эти программы пишутся специально для платформы мессенджера. Боты работают таким образом: пользователь отправляет команду через строку ввода, а система отвечает текстовым или интерактивным сообщением. Иногда программа даже имитирует действия реального человека – такой бот вызывает больше доверия у клиентов.
Существует несколько видов систем для автоматической помощи пользователям. Одни боты просто общаются с клиентами, другие – регулярно поставляют информацию. Четко разделить программы на типы нельзя – разработчики нередко сочетают несколько функций в одном боте.
Написать несложный бот для Телеграма с интерактивными элементами в виде экранных кнопок можно за 9 шагов. Рассмотрим каждый из них в подробностях и ответим на несколько вопросов:
- как запустить бот;
- как прописать встроенную клавиатуру из одной или нескольких кнопок;
- как запрограммировать кнопки на нужные функции;
- что такое встроенный режим и как настроить его для уже существующего бота.
- Шаг 0: теоретическая база об API Telegram-ботов
- Шаг 1: реализация запросов курсов валют
- Шаг 2: создание Telegram-бота с помощью @BotFather
- Шаг 3: настройка и запуск бота
- Шаг 4: написание обработчика команды /start
- Шаг 5: создание обработчика команды /help
- Шаг 6: добавление обработчика команды /exchange
- Шаг 7: написание обработчика для кнопок встроенной клавиатуры
- Шаг 8: реализация обработчика кнопки обновления
- Шаг 9: реализация встроенного режима
- Заключение
Шаг 0: теоретическая база об API Telegram-ботов
Основной инструмент, который используют при создании Телеграм-ботов – это интерфейс прикладного программирования HTML, или API HTML. Этот элемент принимает запросы посетителей и отправляет ответы в виде информации. Готовые конструкции упрощают работу над программой. Чтобы написать бот для Телеграма, необходимо воспользоваться этим электронным адресом: https://api.telegram.org/bot<token>/METHOD_NAME
Для правильного функционирования бота также нужен токен – комбинация символов, защищающая программу и открывающая доступ к ней доверенным разработчикам. Каждый токен уникален. Строка присваивается боту при создании. Методы могут быть разными: getUpdates, getChat и прочие. Выбор метода зависит от того, какого алгоритма работы разработчики ожидают от бота. Пример токена:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
В ботах используются запросы GET и POST. Параметры методов нередко приходится дополнять – к примеру, когда по задумке метод sendMessage должен отправить id чата и какой-либо текст. Параметры для доработки метода можно передать строкой запроса URL с помощью application/x-www-form-urlencoded или через application-json. Эти способы не подходят для загрузки файлов. Также обязательна кодировка UTF-8. Отправив запрос к API, можно получить результат в JSON-формате. Взгляните на ответ программы на извлечение информации через метод getME:
GET https://api.telegram.org/bot<token>/getMe{ ok: true, result: { id: 231757398, first_name: "Exchange Rate Bot", username: "exchangetestbot" }
}
Результат будет получен, если ok равняется true. В ином случае система укажет на ошибку.
Существует два способа получить пользовательские сообщения в ботах. Обе методики действенны, но подходят в разных случаях. Чтобы получить сообщения, можно вручную написать запрос с методом getUpdates – программа выдаст на экран массив данных Update. Запросы нужно отправлять регулярно, после анализа каждого массива отправка повторяется. Избежать повторного появления проверенных объектов поможет offset – параметр, определяющий количество пропущенных записей перед загрузкой нового результата. Преимущества метода getUpdates проявятся, если:
- нет возможности настроить HTTPS;
- используются сложные языки сценариев;
- сервер бота время от времени меняется;
- бот нагружен пользователями.
Второй метод, который можно прописать для получения пользовательских сообщений – setWebhook. Он используется один раз, не нужно постоянно отправлять новые запросы. Webhook пересылает обновления данных на указанный адрес URL. Для применения этого способа потребуется SSL-сертификат. Webhook будет полезен в этих случаях:
- используются веб-языки программирования;
- бот не перегружен, пользователей не слишком много;
- сервер не меняется, программа остается на одном сервере на долгое время.
В дальнейших инструкциях применим getUpdates.
Telegram-сервис @BotFather предназначен для создания чат-ботов. Основные настройки также устанавливаются через эту систему – BotFather поможет сделать описание, поставить фотографию профиля, добавить инструменты поддержки. Библиотеки – наборы HTML-запросов для Телеграм-ботов – доступны в интернете, их достаточно много. При создании программы-примера применена pyTelegramBotApi.
Шаг 1: реализация запросов курсов валют
Для начала необходимо написать код, выполняющий запросы. Воспользуемся при написании API ПриватБанка, ниже расположена ссылка на него: https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5. В коде нужно использовать эти методы:
- load_exchange – находит курсы валют и выводит закодированную информацию;
- get_exchange – выводит данные об определенной валюте;
- get_exchanges – показывает перечисление валют согласно образцу.
В результате код в файле pb.py выглядит так:
import re import requests import json URL = 'https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5' def load_exchange(): return json.loads(requests.get(URL).text) def get_exchange(ccy_key): for exc in load_exchange(): if ccy_key == exc['ccy']: return exc return False def get_exchanges(ccy_pattern): result = [] ccy_pattern = re.escape(ccy_pattern) + '.*' for exc in load_exchange(): if re.match(ccy_pattern, exc['ccy'], re.IGNORECASE) is not None: result.append(exc) return result
Программа может выдать такой ответ на указанные запросы:
[ { ccy:"USD", base_ccy:"UAH", buy:"25.90000", sale:"26.25000" }, { ccy:"EUR", base_ccy:"UAH", buy:"29.10000", sale:"29.85000" }, { ccy:"RUR", base_ccy:"UAH", buy:"0.37800", sale:"0.41800" }, { ccy:"BTC", base_ccy:"USD", buy:"11220.0384", sale:"12401.0950" }
]
Шаг 2: создание Telegram-бота с помощью @BotFather
Создать программу для приема сообщений и ответа на них можно через сервис @BotFather. Переходим на его страницу в Telegram и вводим команду /newbot. В чате появятся инструкции, согласно которым нужно записать сначала имя бота, а после – его адрес. Когда аккаунт-бот будет создан, на экране появится приветственное сообщение, содержащее токен. Для дальнейшей настройки воспользуемся этими командами:
- /setdescription – описание;
- /setabouttext – информация о новом боте;
- /setuserpic – фотография профиля;
- /setinline – встроенный режим;
- /setcommands – описание команд.
На последнем шаге настройки описываем /help и /exchange. Когда все этапы пройдены, пора перейти к составлению кода.
Шаг 3: настройка и запуск бота
Создадим файл config.py. В нем нужно указать уникальный код бота и часовую зону, в которой программа найдет информацию.
TOKEN = '<bot token>' # заменить на токен своего ботаTIMEZONE = 'Europe/Kiev' TIMEZONE_COMMON_NAME = 'Kiev'
Далее создаем еще один файл с импортом ранее написанного pb.py, библиотек и других необходимых компонентов. Недостающие библиотеки устанавливаются из системы управления пакетами (pip).
import telebotimport configimport pbimport datetimeimport pytzimport jsonimport traceback P_TIMEZONE = pytz.timezone(config.TIMEZONE) TIMEZONE_COMMON_NAME = config.TIMEZONE_COMMON_NAME
Воспользуемся содержимым pyTelegramBotApi, чтобы создать бот. Отправляем полученный токен с помощью такого кода:
bot = telebot.TeleBot(config.TOKEN) bot.polling(none_stop=True)
Параметр none_stop обеспечивает постоянную отправку запросов. На действие параметра не повлияют ошибки метода.
Шаг 4: написание обработчика команды /start
Если все предыдущие шаги выполнены правильно, бот начал работать. Программа регулярно создает запросы, потому что в ней использован метод getUpdates. Перед строкой с элементом none_stop нужна часть кода, обрабатывающая команду /start:
@bot.message_handler(commands=['start'])
def start_command(message):
bot.send_message(
message.chat.id,
'Greetings! I can show you exchange rates.\n' +
'To get the exchange rates press /exchange.\n' +
'To get help press /help.'
)
При commands=[‘start’] равном True вызывается start_command. Содержимое сообщения переходит туда. Далее нужно реализовать функцию send_message по отношению к конкретному сообщению.
Шаг 5: создание обработчика команды /help
Команду /help можно реализовать в виде кнопки. Нажав на нее, пользователь попадет в аккаунт разработчика в Telegram. Присвоим кнопке имя – например «Ask the developer». Установим параметр reply_markup, перенаправляющий пользователя по ссылке, для метода send_message. Пропишем в коде параметр, создающий клавиатуру (InlineKeyboardMarkup). Понадобится только одна кнопка (InlineKeyboardButton).
Финальный код обработчика команды выглядит так:
@bot.message_handler(commands=['help'])
def help_command(message):
keyboard = telebot.types.InlineKeyboardMarkup()
keyboard.add(
telebot.types.InlineKeyboardButton(
'Ask the developer', url='ваша ссылка на профиль'
)
)
bot.send_message(
message.chat.id,
'1) To receive a list of available currencies press /exchange.\n' +
'2) Click on the currency you are interested in.\n' +
'3) You will receive a message containing information regarding the source and the target currencies, ' +
'buying rates and selling rates.\n' +
'4) Click “Update” to receive the current information regarding the request. ' +
'The bot will also show the difference between the previous and the current exchange rates.\n' +
'5) The bot supports inline. Type @<botusername> in any chat and the first letters of a currency.',
reply_markup=keyboard
)
Действие кода в чате Telegram:

Шаг 6: добавление обработчика команды /exchange
Этот шаг нужен, чтобы в чате отображались кнопки с обозначениями доступных валют. Экранная клавиатура с вариантами поможет избежать ошибок. ПриватБанк предоставляет информацию о рубле, долларе и евро. Параметр InlineKeyboardButton работает следующим образом:
- Пользователь кликает по кнопке с нужным обозначением.
- В getUpdates поступает обратный вызов (CallbackQuery).
- Становится известно, как обработать нажатие на клавиатуру – передается информация о нажатой кнопке.
Код обработчика /exchange:
@bot.message_handler(commands=['exchange'])
def exchange_command(message):
keyboard = telebot.types.InlineKeyboardMarkup()
keyboard.row(
telebot.types.InlineKeyboardButton('USD', callback_data='get-USD')
)
keyboard.row(
telebot.types.InlineKeyboardButton('EUR', callback_data='get-EUR'),
telebot.types.InlineKeyboardButton('RUR', callback_data='get-RUR')
)
bot.send_message(
message.chat.id,
'Click on the currency of choice:',
reply_markup=keyboard
)
Результат работы кода в Телеграме:

Шаг 7: написание обработчика для кнопок встроенной клавиатуры
В пакете pyTelegramBot Api размещена функция-декоратор @bot.callback_query_handler. Этот компонент предназначен для перевода обратного вызова в функцию – API разворачивает и снова создает вызов. Это прописывается так:
@bot.callback_query_handler(func=lambda call: True)
def iq_callback(query):
data = query.data
if data.startswith('get-'):
get_ex_callback(query)
Пропишем также метод get_ex_callback:
def get_ex_callback(query): bot.answer_callback_query(query.id) send_exchange_result(query.message, query.data[4:])
Существует и другой полезный метод – answer_callback_query. Он помогает убрать загрузку между нажатием кнопки и выводом результата на экран. В send_exchange_query можно отправить сообщение, передав код какой-либо валюты и Message. Запишем send_exchange_result:
def send_exchange_result(message, ex_code): bot.send_chat_action(message.chat.id, 'typing') ex = pb.get_exchange(ex_code) bot.send_message( message.chat.id, serialize_ex(ex), reply_markup=get_update_keyboard(ex), parse_mode='HTML' )
Пока чат-бот получает результат запроса из банковского API, посетитель видит надпись «набирает сообщение». Это выглядит так, будто отвечает реальный человек. Чтобы вывести такой индикатор на экран, потребуется добавить строки о состоянии ввода. Далее воспользуемся get_exchange – с его помощью программа получит обозначение валюты (рублей, евро или долларов). В send_message используются добавочные методы: serialize_ex переводит валюту в другой формат, а get_update_keyboard устанавливает экранные клавиши, обновляющие информацию и пересылающие данные о валютном рынке в другие чаты.
Напишем код для get_update_keyboard. Нужно упомянуть две кнопки – t и e обозначают тип и обмен. Пункт switch_inline_query для кнопки Share нужен, чтобы пользователю открывался выбор из нескольких чатов. Посетитель сможет выбрать, кому отправить актуальный курс доллара, рубля или евро.
def get_update_keyboard(ex):
keyboard = telebot.types.InlineKeyboardMarkup()
keyboard.row(
telebot.types.InlineKeyboardButton(
'Update',
callback_data=json.dumps({
't': 'u',
'e': {
'b': ex['buy'],
's': ex['sale'],
'c': ex['ccy']
}
}).replace(' ', '')
),
telebot.types.InlineKeyboardButton('Share', switch_inline_query=ex['ccy'])
)
return keyboard
Иногда необходимо увидеть, насколько изменился курс валют за короткое время. Напишем два метода для кнопки Update, чтобы пользователи могли увидеть курсы в сравнении.
Разница между курсами валют передается в сериализатор через параметр diff.
Прописанные методы срабатывают только после обновления данных, они не повлияют на первое отображение курса.
def serialize_ex(ex_json, diff=None):
result = '<b>' + ex_json['base_ccy'] + ' -> ' + ex_json['ccy'] + ':</b>\n\n' + \
'Buy: ' + ex_json['buy']
if diff:
result += ' ' + serialize_exchange_diff(diff['buy_diff']) + '\n' + \
'Sell: ' + ex_json['sale'] + \
' ' + serialize_exchange_diff(diff['sale_diff']) + '\n'
else:
result += '\nSell: ' + ex_json['sale'] + '\n'
return result
def serialize_exchange_diff(diff):
result = ''
if diff > 0:
result = '(' + str(diff) + ' <img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="↗️" src="https://s.w.org/images/core/emoji/2.3/svg/2197.svg">" src="https://s.w.org/images/core/emoji/2.3/svg/2197.svg">" src="https://s.w.org/images/core/emoji/2.3/svg/2197.svg">" src="https://s.w.org/images/core/emoji/72x72/2197.png">" src="https://s.w.org/images/core/emoji/72x72/2197.png">)'
elif diff < 0:
result = '(' + str(diff)[1:] + ' <img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="<img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="↘️" src="https://s.w.org/images/core/emoji/2.3/svg/2198.svg">" src="https://s.w.org/images/core/emoji/2.3/svg/2198.svg">" src="https://s.w.org/images/core/emoji/2.3/svg/2198.svg">" src="https://s.w.org/images/core/emoji/72x72/2198.png">" src="https://s.w.org/images/core/emoji/72x72/2198.png">)'
return result
Представим, что посетитель захотел узнать курс доллара. Вот что произойдет, если выбрать в сообщении USD:

Шаг 8: реализация обработчика кнопки обновления
Напишем код для обработки действий с кнопкой Update и дополним его часть iq_callback_method. Когда пункты программы начинаются с параметра get‒, необходимо прописать get_ex_callback. В других ситуациях разбираем JSON и пытаемся получить ключ t.
@bot.callback_query_handler(func=lambda call: True)
def iq_callback(query):
data = query.data
if data.startswith('get-'):
get_ex_callback(query)
else:
try:
if json.loads(data)['t'] == 'u':
edit_message_callback(query)
except ValueError:
pass
Если t равняется u, потребуется создать программу для метода edit_message_callback. Разберем эту процедуру по шагам:
- Загрузка актуальной информации о состоянии валютного рынка (exchange_now = pb.get_exchange(data[‘c’]).
- Написание нового сообщения через сериализатор с diff.
- Добавление подписи (get_edited_signature).
Если начальное сообщение не меняется, вызовем метод edit_message_text.
def edit_message_callback(query):
data = json.loads(query.data)['e']
exchange_now = pb.get_exchange(data['c'])
text = serialize_ex(
exchange_now,
get_exchange_diff(
get_ex_from_iq_data(data),
exchange_now
)
) + '\n' + get_edited_signature()
if query.message:
bot.edit_message_text(
text,
query.message.chat.id,
query.message.message_id,
reply_markup=get_update_keyboard(exchange_now),
parse_mode='HTML'
)
elif query.inline_message_id:
bot.edit_message_text(
text,
inline_message_id=query.inline_message_id,
reply_markup=get_update_keyboard(exchange_now),
parse_mode='HTML'
)
Пропишем метод get_ex_from_iq_data, чтобы разобрать JSON:
def get_ex_from_iq_data(exc_json):
return {
'buy': exc_json['b'],
'sale': exc_json['s']
}
Понадобится еще несколько методов: например, get_exchange_diff, который считывает старую и новую информацию о стоимости валют и выводит разницу.
def get_exchange_diff(last, now):
return {
'sale_diff': float("%.6f" % (float(now['sale']) - float(last['sale']))),
'buy_diff': float("%.6f" % (float(now['buy']) - float(last['buy'])))
}
Последний – get_edited_signature – показывает время последнего обновления курса.
def get_edited_signature():
return '<i>Updated ' + \
str(datetime.datetime.now(P_TIMEZONE).strftime('%H:%M:%S')) + \
' (' + TIMEZONE_COMMON_NAME + ')</i>'
В результате обновленное сообщение от бота при стабильном курсе выглядит так:

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

Шаг 9: реализация встроенного режима
Встроенный режим нужен для быстрой отправки информации из программы в любой чат – теперь не нужно добавлять бот в беседу как участника. Когда пользователь Telegram водит название бота со знаком @ перед ним, над строкой ввода должны появиться варианты конвертирования. Если кликнуть по одному из пунктов, бот вышлет в беседу сообщение с результатами и кнопками для обновления и пересылки данных. В имени отправителя окажется подпись «via <имя бота>».
InlineQuery передается в query_text через библиотеку. В коде применяется функция answer_line – она извлекает результаты поиска в виде массива данных и элемент inline_query_id. Используем get_exchanges, чтобы бот находил несколько валют по запросу.
@bot.inline_handler(func=lambda query: True)
def query_text(inline_query):
bot.answer_inline_query(
inline_query.id,
get_iq_articles(pb.get_exchanges(inline_query.query))
)
Передаем массив данных в get_iq_articles, чтобы через этот метод вернуть объекты из InlineQueryResultArticle.
def get_iq_articles(exchanges):
result = []
for exc in exchanges:
result.append(
telebot.types.InlineQueryResultArticle(
id=exc['ccy'],
title=exc['ccy'],
input_message_content=telebot.types.InputTextMessageContent(
serialize_ex(exc),
parse_mode='HTML'
),
reply_markup=get_update_keyboard(exc),
description='Convert ' + exc['base_ccy'] + ' -> ' + exc['ccy'],
thumb_height=1
)
)
return result
Теперь, если написать в строке @<имябота> и пробел, на экране появятся результаты поиска – варианты конвертирования в три доступные валюты.

Пользователи могут отфильтровать результаты, если введут обозначение нужной валюты.
После клика по нужной валюте из списка в чат приходит такое же сообщение, какие получают пользователи бота. Кнопкой Update тоже можно пользоваться. На изображении ниже изображено обновленное сообщение, которое отправили через бот:

Заключение
Теперь вам известно, как создать бот для Телеграма. Вы сможете добавить в свою программу полезные инструменты: кнопки обновления и отправки результата другим пользователям мессенджера и встроенный режим, позволяющий пользоваться функциями бота вне чата с ним. На основе этой инструкции можно создать любой простой бот с другими функциями – не только тот, который покажет курсы валют. Не бойтесь экспериментировать с библиотеками, API и кодом, чтобы создать автоматического помощника, который пообщается с клиентами в Телеграме и укрепит связь заинтересованных людей с компанией.















