Как создать чат-бот в Telegram
Чат-бот — это автоматизированный многофункциональный помощник, который может показывать информацию подписчикам и собирать информацию по запросу согласно заранее подготовленным сценариям.
Следуйте пошаговой инструкции, чтобы создать своего первого чат-бота для Telegram мессенджера или подключить существующий к сервису SendPulse для дальнейшей настройки.
Содержание
Если у вас уже создан бот, переходите сразу к третьему пункту.
Зачем нужен чат-бот Telegram
Чаще всего чат-боты применяются для автоматизации обслуживания клиентов. Боты могут быстро и эффективно отвечать на вопросы и запросы клиентов 24/7, автоматически собирать обратную связь от клиентов после покупки или обслуживания. Для этого вам необходимо создать сценарий бота с необходимыми командами, которые будет выбирать подписчик для решения своих вопросов.
Боты могут отправлять мгновенные уведомления через рассылки о новых акциях, событиях или важных обновлениях бизнеса, что помогает удерживать клиентов в курсе и повышать узнаваемость бренда.
Как создать свой бот в Telegram
Откройте мессенджер Telegram, войдите в вашу учетную запись или создайте новую.
Введите в поле поиска @BotFather и выберите бот.
У официального бота Telegram будет стоять синий подтверждающий знак возле имени в виде галочки.

Нажмите «Запустить» для активации бота BotFather.
В ответ вы получите список команд по управлению ботом.

Выберите или напечатайте и отправьте команду /newbot .

Дайте имя боту — клиенты увидят это имя при общении с ботом. И никнейм бота — по нему можно будет найти бота в Telegram. Никнейм должен быть уникальным, не повторять существующие в базе и заканчиваться на слово «bot».

После того как вы выберите подходящее имя бот будет создан. Вы получите сообщение со ссылкой на бота t.me/ , рекомендации по настройке аватарки, описание бота и список команд для его настройки.
Для подключения бота в SendPulse вам понадобится токен. Скопируйте значение токена и перейдите к последнему пункту.

Где найти ключ для уже существующего бота
Перейдите к боту @BotFather и введите команду /token .
Вы увидите кнопки с созданными ботами.

Выберите бот, который нужно подключить.

Скопируйте значение токена.

Как подключить бот в Sendpulse
Перейдите в раздел «Чат-боты» в вашем аккаунте SendPulse. Если у вас нет подключенных каналов, нажмите на кнопку «Подключить каналы».
Если вы уже подключали ботов, перейдите в раздел «Управление ботами» и нажмите «Добавить бот». Также вы можете выбрать «Подключить» напротив нужного канала.

В секции «Telegram» введите ключ доступа — токен полученный в созданном боте. Нажмите «Подключить».

Нажмите на кнопку «Подписаться на бота». Таким образом вы сможете тестировать каждое сообщение и цепочку и отправлять их себе перед реализацией.

Вы будете перенаправлены в приложение Telegram, нажмите на кнопку «Запустить» и вы подпишетесь на свой бот.

После успешного подключения чат-бота вы получите приветственную цепочку, бот появится у вас в списке ботов и вы можете начинать создавать приветственные и триггерные цепочки, массовые рассылки.
Как создать сценарий чат-бота
По умолчанию доступны цепочки «Приветственная серия», «Стандартный ответ» и «После отписки». Также вы можете создавать свои триггеры и сценарии.

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

По шаблону
Также вы можете использовать готовые решения или вдохновиться ими. В разделе «Шаблоны» есть шаблоны цепочек по разным темам. Вы можете взять один из них за основу, а потом работать с ним в конструкторе, добавляя необходимый контент в блоки.

С помощью AI
Также вы можете задействовать искусственный интеллект для создания сценариев цепочек под ваши запросы. Это позволит существенно сократить время на генерацию творческих идей и продумывание логики.
Откройте конструктор и нажмите кнопку «Создать цепочку с помощью ИИ» (Create a flow with AI). Продумайте все детали, которые вы хотели бы включить в бот, и впишите требования в подсказку для генерации цепочки.

Искусственный интеллект можно подключить и для того, чтобы нейронная сеть генерировала ответы пользователям в режиме реального времени, не по сценариям. Подключите ChatGPT и предоставьте основные данные о вашей компании, на которые вы хотите, чтобы бот отвечал.
После того как вы создали бот в Telegram и настроили сценарии ответов, вы можете добавить ссылку на бот на ваш сайт или подключить его к умным попапам. Если у вас есть список ID подписчиков из 8-10 чисел, можете его импортировать.
Вы также можете отслеживать поведение бота в статистике и в чатах с подписчиками, чтобы анализировать путь пользователя и улучшать их опыт взаимодействия.
Как написать Telegram бота на C#? [Часть 1]
Приветствую всех в своем уроке по написанию Telegram бота на языке программирования C#. В этом уроке я постараюсь максимально просто и понятно объяснить как написать своего бота с нуля. Конечно, здесь не будет какого-то трудного проекта, я дам вам необходимую базу, с помощью которой вы сможете писать своих ботов.
Начало
Для начала нам требуется зарегистрировать нашего бота. Делается это через «Ботобатю» (кликабельно) в самом Telegram.

- Переходим по ссылке и попадаем в диалог с BotFather и жмем «Запустить». BotFather — это официальный бот Telegram`а, через которого проходит регистрация и настройка ваших ботов.
- От вашего лица должна отправиться команда /start , на которую бот ответит большим списком команд с описаниями. Подробно изучить каждую Вы можете сами, а мы двигаемся к шагу 3.
- Используем команду /newbot. На этом шаге нужно отправить боту имя Вашего будущего бота. Например, пусть это будет Александр Николаевич.
- Далее нас попросят ввести username бота, учтите, что он должен быть написан строго на латинице, а также содержать bot или _bot в конце.Username — это уникальный идентификатор аккаунта (вашего или бота), по которому люди могут найти аккаунт в поиске. В случае, если username уже занят, вас попросят использовать другой.
- После всех выполнений действий, Ботобатя присылает нам небольшое сообщение, в котором говорится об успешном создании бота. Из этого сообщения нам нужен token (уникальный ключ), с помощью которого мы будем авторизировать нашего бота в дальнейшем, он имеет примерно такой вид:13523457:AFAgd_SDFG6sd7f6asdf67asdf78. Учтите, что абсолютно никому нельзя присылать этот token! Это ваш секретный ключ для доступа к боту.
Создание проекта в IDE
После того, как мы создали бота, перейдем к созданию проекта в вашей IDE. У меня это Rider от компании JetBrains. Вы можете использовать эту же IDE, либо Visual Studio от компании Microsoft, либо все от той же компании Visual Studio Code.
По сути, вы можете создать любой тип проекта, будь то консольное приложение или же какой-нибудь WinForms. Я всегда создаю консольное приложение, так как в будущем делаю деплой на Linux, да и как-то не вижу смысла в создании бота с программным интерфейсом.
Если же вы до сих пор не знаете, что такое IDE, как создавать проекты, то вам явно рано писать ботов, займитесь для начала изучением языка!
После того, как мы создали проект, нам нужно установить библиотеку Telegram.Bot (GitHub библиотеки, Nuget пакет). Сделать это можно либо через терминал в IDE, написав команду
dotnet add Telegram.Bot
либо же использовать графический интерфейс. На момент написания статьи была установлена самая последняя и самая актуальная версия пакета (19.0.0).
У библиотеки есть своя документация, можете посмотреть ее здесь.
Написание бота
Теперь приступим к написанию бота, для начала напишем стандартный класс Program. Добавим туда объект интерфейса ITelegramBotClient и в методе Main создадим стандартные переменные и присвоим им соответствующие значения.
class Program < // Это клиент для работы с Telegram Bot API, который позволяет отправлять сообщения, управлять ботом, подписываться на обновления и многое другое. private static ITelegramBotClient _botClient; // Это объект с настройками работы бота. Здесь мы будем указывать, какие типы Update мы будем получать, Timeout бота и так далее. private static ReceiverOptions _receiverOptions; static async Task Main() < _botClient = new TelegramBotClient(""); // Присваиваем нашей переменной значение, в параметре передаем Token, полученный от BotFather _receiverOptions = new ReceiverOptions // Также присваем значение настройкам бота < AllowedUpdates = new[] // Тут указываем типы получаемых Update`ов, о них подробнее расказано тут https://core.telegram.org/bots/api#update < UpdateType.Message, // Сообщения (текст, фото/видео, голосовые/видео сообщения и т.д.) >, // Параметр, отвечающий за обработку сообщений, пришедших за то время, когда ваш бот был оффлайн // True - не обрабатывать, False (стоит по умолчанию) - обрабаывать ThrowPendingUpdates = true, >; using var cts = new CancellationTokenSource(); // UpdateHander - обработчик приходящих Update`ов // ErrorHandler - обработчик ошибок, связанных с Bot API _botClient.StartReceiving(UpdateHandler, ErrorHandler, _receiverOptions, cts.Token); // Запускаем бота var me = await _botClient.GetMeAsync(); // Создаем переменную, в которую помещаем информацию о нашем боте. Console.WriteLine($" запущен!"); await Task.Delay(-1); // Устанавливаем бесконечную задержку, чтобы наш бот работал постоянно > >
Теперь давайте в этом же классе (можно и в другом) напишем методы UpdateHandler и ErrorHandler.
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) < // Обязательно ставим блок try-catch, чтобы наш бот не "падал" в случае каких-либо ошибок try < // Сразу же ставим конструкцию switch, чтобы обрабатывать приходящие Update switch (update.Type) < case UpdateType.Message: < Console.WriteLine("Пришло сообщение!"); return; >> > catch (Exception ex) < Console.WriteLine(ex.ToString()); >> private static Task ErrorHandler(ITelegramBotClient botClient, Exception error, CancellationToken cancellationToken) < // Тут создадим переменную, в которую поместим код ошибки и её сообщение var ErrorMessage = error switch < ApiRequestException apiRequestException =>$"Telegram API Error:\n[]\n", _ => error.ToString() >; Console.WriteLine(ErrorMessage); return Task.CompletedTask; >
Теперь давайте посмотрим, работает ли наш код ? Жмем на кнопку Debug и проверяем 🙂

Как мы видим, бот успешно запустился, теперь давайте напишем пару сообщений, чтобы понять, получает ли он сообщения

И тут тоже все прекрасно, теперь давайте дополним наш метод UpdateHandler и напишем эхо бота. Также чуть-чуть попозже расскажу немного о типах Update.
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) < // Обязательно ставим блок try-catch, чтобы наш бот не "падал" в случае каких-либо ошибок try < // Сразу же ставим конструкцию switch, чтобы обрабатывать приходящие Update switch (update.Type) < case UpdateType.Message: < // эта переменная будет содержать в себе все связанное с сообщениями var message = update.Message; // From - это от кого пришло сообщение (или любой другой Update) var user = message.From; // Выводим на экран то, что пишут нашему боту, а также небольшую информацию об отправителе Console.WriteLine($"() написал сообщение: "); // Chat - содержит всю информацию о чате var chat = message.Chat; await botClient.SendTextMessageAsync( chat.Id, message.Text, // отправляем то, что написал пользователь replyToMessageId: message.MessageId // по желанию можем поставить этот параметр, отвечающий за "ответ" на сообщение ); return; > > > catch (Exception ex) < Console.WriteLine(ex.ToString()); >>

Как мы видим, все работает идеально. Теперь расскажу о типах Update, так как дальше мы напишем кое-что посложнее. Итак, типы Update:
- Message — принимает в себя все сообщения. Обычные текстовые, фото или видео, аудио или видео сообщения (кружочки), стикеры, контакты, геопозицию, голосование и так далее. Всё, что мы отправляем в чат — это все Message.
- EditedMessage — тут все просто: этот тип принимает в себя любое обновление сообщения. Схож с Message.
- ChannelPost — как и Message, но направлен на каналы.
- EditedChannelPost — аналогичен EditedMessage, но также направлен на каналы.
- CallbackQuery — отвечает за Inline кнопки, они висят под сообщением, возможно, вы их уже видели в других ботах.
- Poll — получает все связанное с голосованием.
- PollAnswner — а этот тип работает только тогда, когда пользователь изменил свой ответ в голосовании.
- ChatMember — всё, что касается людей в чате/канале: зашел, вышел, повысили, понизили, замьютили и т.д.
- MyChatMember — всё, что касается бота в диалоге между пользователем и ботом, т.е. изменения в личных сообщениях.
- ChatJoinRequest — получение информации о поданной заявки на вступление в чат/канал.
- InlineQuery — получение входящих inline запросов. Inline запрос — это, когда вы в чате используете @ и username бота и вводите какой-то запрос, а результат выполнения отправляется в чат от вашего лица с надписью «сделано с помощью. «.
- ChosenInlineResult — а это уже то, что как раз таки выбрал пользователь. Т.е. InlineQuery это просто как разрешение использовать эту функцию, а ChosenInlineResult получает выбор пользователя и обрабатывает его. Знаю, что вы думаете «Они что, совсем идиоты ? Не могли сделать нормально ?», но привыкайте, такого будет полно)
- PreCheckoutQuery — сюда приходит информация о платеже, который начал оплачивать пользователь.
- ShippingQuery — а это срабатывает тогда, когда успешно сработал PreCheckoutQuery , т.е. этот update уже подтверждает успешную оплату пользователем.
Фух, ну вроде все, если желаете посмотреть оригинал, то он находится здесь.
Теперь давайте напишем что-нибудь посложнее. Добавим в AllowedUpdates тип CallbackQuery:
AllowedUpdates = new[] // Тут указываем типы получаемых Update`ов, о них подробнее расказано тут https://core.telegram.org/bots/api#update < UpdateType.Message, // Сообщения (текст, фото/видео, голосовые/видео сообщения и т.д.) UpdateType.CallbackQuery // Inline кнопки >,
Теперь в нашем UpdateHandler добавим обработку команды /start и сделаем там несколько клавиатур, чтобы вы поняли, как работать с разными типами update, а также увидели еще одну клавиатуру, которая называется Reply клавиатура.
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) < // Обязательно ставим блок try-catch, чтобы наш бот не "падал" в случае каких-либо ошибок try < // Сразу же ставим конструкцию switch, чтобы обрабатывать приходящие Update switch (update.Type) < case UpdateType.Message: < // эта переменная будет содержать в себе все связанное с сообщениями var message = update.Message; // From - это от кого пришло сообщение var user = message.From; // Выводим на экран то, что пишут нашему боту, а также небольшую информацию об отправителе Console.WriteLine($"() написал сообщение: "); // Chat - содержит всю информацию о чате var chat = message.Chat; // Добавляем проверку на тип Message switch (message.Type) < // Тут понятно, текстовый тип case MessageType.Text: < // тут обрабатываем команду /start, остальные аналогично if (message.Text == "/start") < await botClient.SendTextMessageAsync( chat.Id, "Выбери клавиатуру:\n" + "/inline\n" + "/reply\n"); return; >if (message.Text == "/inline") < // Тут создаем нашу клавиатуру var inlineKeyboard = new InlineKeyboardMarkup( new List() // здесь создаем лист (массив), который содрежит в себе массив из класса кнопок < // Каждый новый массив - это дополнительные строки, // а каждая дополнительная строка (кнопка) в массиве - это добавление ряда new InlineKeyboardButton[] // тут создаем массив кнопок < InlineKeyboardButton.WithUrl("Это кнопка с сайтом", "https://habr.com/"), InlineKeyboardButton.WithCallbackData("А это просто кнопка", "button1"), >, new InlineKeyboardButton[] < InlineKeyboardButton.WithCallbackData("Тут еще одна", "button2"), InlineKeyboardButton.WithCallbackData("И здесь", "button3"), >, >); await botClient.SendTextMessageAsync( chat.Id, "Это inline клавиатура!", replyMarkup: inlineKeyboard); // Все клавиатуры передаются в параметр replyMarkup return; > if (message.Text == "/reply") < // Тут все аналогично Inline клавиатуре, только меняются классы // НО! Тут потребуется дополнительно указать один параметр, чтобы // клавиатура выглядела нормально, а не как абы что var replyKeyboard = new ReplyKeyboardMarkup( new List() < new KeyboardButton[] < new KeyboardButton("Привет!"), new KeyboardButton("Пока!"), >, new KeyboardButton[] < new KeyboardButton("Позвони мне!") >, new KeyboardButton[] < new KeyboardButton("Напиши моему соседу!") >>) < // автоматическое изменение размера клавиатуры, если не стоит true, // тогда клавиатура растягивается чуть ли не до луны, // проверить можете сами ResizeKeyboard = true, >; await botClient.SendTextMessageAsync( chat.Id, "Это reply клавиатура!", replyMarkup: replyKeyboard); // опять передаем клавиатуру в параметр replyMarkup return; > return; > // Добавил default , чтобы показать вам разницу типов Message default: < await botClient.SendTextMessageAsync( chat.Id, "Используй только текст!"); return; >> return; > > > catch (Exception ex) < Console.WriteLine(ex.ToString()); >>
Как мы видим, бот теперь реагирует на /start:

Вот так выглядит inline клавиатура:

А вот так reply клавиатура:

Причем, если вы понажимаете на кнопки, то как вы уже поняли, ничего не произойдет:)

Конечно, это логично, ведь мы не добавили обработчики этих кнопок. Как вы могли заметить, reply клавиатура — это просто как заготовленный текст для пользователя, поэтому с обработкой этих кнопок у вас не должно возникнуть проблем. Так как это просто дополнительные if в блоке case MessageType.Text. Но я все же покажу, как это сделать, после перейдем к кейсу с Inline клавиатурой.
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) < // Обязательно ставим блок try-catch, чтобы наш бот не "падал" в случае каких-либо ошибок try < // Сразу же ставим конструкцию switch, чтобы обрабатывать приходящие Update switch (update.Type) < case UpdateType.Message: < // тут все переменные // Добавляем проверку на тип Message switch (message.Type) < // Тут понятно, текстовый тип case MessageType.Text: < // а тут обработчики команд if (message.Text == "Позвони мне!") < await botClient.SendTextMessageAsync( chat.Id, "Хорошо, присылай номер!", replyToMessageId: message.MessageId); return; >if (message.Text == "Напиши моему соседу!") < await botClient.SendTextMessageAsync( chat.Id, "А самому что, трудно что-ли ?", replyToMessageId: message.MessageId); return; >return; > // тут остальной код > return; > > > catch (Exception ex) < Console.WriteLine(ex.ToString()); >>
Ну, вот так как-то вышло:

Теперь перейдем к блоку с Inline клавиатурами. Для обработки этой клавиатуры нам потребуется добавить в
switch(update.Type) < case UpdateType.Message: < // тут весь код из примеров выше >>
case UpdateType.CallbackQuery: < // Переменная, которая будет содержать в себе всю информацию о кнопке, которую нажали var callbackQuery = update.CallbackQuery; // Аналогично и с Message мы можем получить информацию о чате, о пользователе и т.д. var user = callbackQuery.From; // Выводим на экран нажатие кнопки Console.WriteLine($"() нажал на кнопку: "); // Вот тут нужно уже быть немножко внимательным и не путаться! // Мы пишем не callbackQuery.Chat , а callbackQuery.Message.Chat , так как // кнопка привязана к сообщению, то мы берем информацию от сообщения. var chat = callbackQuery.Message.Chat; // Добавляем блок switch для проверки кнопок switch (callbackQuery.Data) < // Data - это придуманный нами id кнопки, мы его указывали в параметре // callbackData при создании кнопок. У меня это button1, button2 и button3 case "button1": < // В этом типе клавиатуры обязательно нужно использовать следующий метод await botClient.AnswerCallbackQueryAsync(callbackQuery.Id); // Для того, чтобы отправить телеграмму запрос, что мы нажали на кнопку await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > case "button2": < // А здесь мы добавляем наш сообственный текст, который заменит слово "загрузка", когда мы нажмем на кнопку await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "Тут может быть ваш текст!"); await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > case "button3": < // А тут мы добавили еще showAlert, чтобы отобразить пользователю полноценное окно await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "А это полноэкранный текст!", showAlert: true); await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > > return; >
В конечном счете UpdateHandler должен выглядеть вот так:
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) < // Обязательно ставим блок try-catch, чтобы наш бот не "падал" в случае каких-либо ошибок try < // Сразу же ставим конструкцию switch, чтобы обрабатывать приходящие Update switch (update.Type) < case UpdateType.Message: < // Эта переменная будет содержать в себе все связанное с сообщениями var message = update.Message; // From - это от кого пришло сообщение (или любой другой Update) var user = message.From; // Выводим на экран то, что пишут нашему боту, а также небольшую информацию об отправителе Console.WriteLine($"() написал сообщение: "); // Chat - содержит всю информацию о чате var chat = message.Chat; // Добавляем проверку на тип Message switch (message.Type) < // Тут понятно, текстовый тип case MessageType.Text: < // тут обрабатываем команду /start, остальные аналогично if (message.Text == "/start") < await botClient.SendTextMessageAsync( chat.Id, "Выбери клавиатуру:\n" + "/inline\n" + "/reply\n"); return; >if (message.Text == "/inline") < // Тут создаем нашу клавиатуру var inlineKeyboard = new InlineKeyboardMarkup( new List() // здесь создаем лист (массив), который содрежит в себе массив из класса кнопок < // Каждый новый массив - это дополнительные строки, // а каждая дополнительная кнопка в массиве - это добавление ряда new InlineKeyboardButton[] // тут создаем массив кнопок < InlineKeyboardButton.WithUrl("Это кнопка с сайтом", "https://habr.com/"), InlineKeyboardButton.WithCallbackData("А это просто кнопка", "button1"), >, new InlineKeyboardButton[] < InlineKeyboardButton.WithCallbackData("Тут еще одна", "button2"), InlineKeyboardButton.WithCallbackData("И здесь", "button3"), >, >); await botClient.SendTextMessageAsync( chat.Id, "Это inline клавиатура!", replyMarkup: inlineKeyboard); // Все клавиатуры передаются в параметр replyMarkup return; > if (message.Text == "/reply") < // Тут все аналогично Inline клавиатуре, только меняются классы // НО! Тут потребуется дополнительно указать один параметр, чтобы // клавиатура выглядела нормально, а не как абы что var replyKeyboard = new ReplyKeyboardMarkup( new List() < new KeyboardButton[] < new KeyboardButton("Привет!"), new KeyboardButton("Пока!"), >, new KeyboardButton[] < new KeyboardButton("Позвони мне!") >, new KeyboardButton[] < new KeyboardButton("Напиши моему соседу!") >>) < // автоматическое изменение размера клавиатуры, если не стоит true, // тогда клавиатура растягивается чуть ли не до луны, // проверить можете сами ResizeKeyboard = true, >; await botClient.SendTextMessageAsync( chat.Id, "Это reply клавиатура!", replyMarkup: replyKeyboard); // опять передаем клавиатуру в параметр replyMarkup return; > if (message.Text == "Позвони мне!") < await botClient.SendTextMessageAsync( chat.Id, "Хорошо, присылай номер!", replyToMessageId: message.MessageId); return; >if (message.Text == "Напиши моему соседу!") < await botClient.SendTextMessageAsync( chat.Id, "А самому что, трудно что-ли ?", replyToMessageId: message.MessageId); return; >return; > // Добавил default , чтобы показать вам разницу типов Message default: < await botClient.SendTextMessageAsync( chat.Id, "Используй только текст!"); return; >> return; > case UpdateType.CallbackQuery: < // Переменная, которая будет содержать в себе всю информацию о кнопке, которую нажали var callbackQuery = update.CallbackQuery; // Аналогично и с Message мы можем получить информацию о чате, о пользователе и т.д. var user = callbackQuery.From; // Выводим на экран нажатие кнопки Console.WriteLine($"() нажал на кнопку: "); // Вот тут нужно уже быть немножко внимательным и не путаться! // Мы пишем не callbackQuery.Chat , а callbackQuery.Message.Chat , так как // кнопка привязана к сообщению, то мы берем информацию от сообщения. var chat = callbackQuery.Message.Chat; // Добавляем блок switch для проверки кнопок switch (callbackQuery.Data) < // Data - это придуманный нами id кнопки, мы его указывали в параметре // callbackData при создании кнопок. У меня это button1, button2 и button3 case "button1": < // В этом типе клавиатуры обязательно нужно использовать следующий метод await botClient.AnswerCallbackQueryAsync(callbackQuery.Id); // Для того, чтобы отправить телеграмму запрос, что мы нажали на кнопку await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > case "button2": < // А здесь мы добавляем наш сообственный текст, который заменит слово "загрузка", когда мы нажмем на кнопку await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "Тут может быть ваш текст!"); await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > case "button3": < // А тут мы добавили еще showAlert, чтобы отобразить пользователю полноценное окно await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "А это полноэкранный текст!", showAlert: true); await botClient.SendTextMessageAsync( chat.Id, $"Вы нажали на "); return; > > return; > > > catch (Exception ex) < Console.WriteLine(ex.ToString()); >>
Теперь запускаем проект и проверяем кнопки!
Заключение
К сожалению, на этом пока всё. Скорее всего будет вторая часть этой статьи или полноценный видеоурок на Youtube, но пока вот так.
Прошу оценить мою статью и оставить комментарий, так как это первая моя подобная работа, до этого мне не доводилось писать статьи или что-нибудь подобное.
Как написать Telegram-бота на Python: делаем ремайндер
Создаём простого бота-ремайндера в Telegram на языке Python, единственная задача которого — напоминать пользователю о важных делах.
В этой иструкции разберем процесс создания простого бота-ремайндера, единственная задача которого — напоминать пользователю о важных делах. Это базовая конструкция, которую можно усложнять и менять под свои потребности.
Инструкция подойдет для новичков, которые знают Python на базовом уровне, пробовали писать код и установили на компьютер редактор кода.
Первый этап: подготовка проекта и развертывание окружения
Найдем в поиске Telegram BotFather — официального бота мессенджера, который создает другие боты и управляет ими. В интерфейсе выбираем /start, затем — /newbot, и следом задаем имя и адрес. В этой иструкции это будут Elbrus Reminder и elbrus_reminder_bot соответственно.
После этого BotFather пришлет сообщение с токеном и ссылкой на бот:
Токен нужно хранить в безопасном месте — он дает контроль над ботом. и, как следствие, позволяет получить доступ к данным пользователей.
На время закроем Telegram и создадим на компьютере папку с именем проекта: например, reminder_bot. Откроем папку в среде разработки и создадим рабочий файл с понятным названием — bot.py.
Откроем терминал редактора кода и создадим для проекта новое окружение. В среде разработки с помощью команды python -m venv .venv создадим папку с окружением .venv .
Если окружение не активировалось автоматически, можно сделать это вручную, прописав путь к файлу активации в формате source .venv/bin/activate , где source — команда языка программирования Bash. Другой вариант — перезапустить среду разработки. Он работает для Visual Studio Code, но нужно предварительно принять предложение редактора привязать среду к папке проекта сразу после создания окружения.
Практика создания нового окружения под каждый проект позволяет повыстить безопасности и стабильность проекта — в окружении вы можете использовать только те библиотеки и их версии, которые требуются в проекте. Если в проекте появятся дополнительные функции, все изменения будут храниться в этом окружении. При этом оно будет изолировано от других окружений и проектов — это повысит безопасность проекта.
Второй этап: подключаем библиотеки
Проект создан и окружение готово: пора переходить к написанию кода. По правилам хорошего тона в первую очередь через import добавляем несколько предустановленных библиотек Python. При создании бота нам пригодятся logging и time , которые отвечают за определение времени и логирование сообщений.
import time import logging
Затем добавим асинхронную библиотеку aiogram, на основе которой будет работать бот. Она, например, определяет, какое сообщение пришло, как его нужно обработать и какие порты нужны. Сначала устанавливаем ее через терминал командой pip install aiogram , а в редакторе кода пишем следующее:
from aiogram import Bot, Dispatcher, executor, types
Из этой библиотеки нам нужны только отдельные модули и классы — все ее возможности для создания базовой версии бота не пригодятся. Поэтому вместо одиночного import использована команда from <> import <> .
Когда библиотеки импортированы, создадим переменные с токеном бота и сообщением, которое он будет отправлять пользователю. Вы можете заменить это сообщение на любое другое, которое вам необходимо. Это статические переменные, поэтому их имена написаны капслоком:
TOKEN = "здесьбудетваштокенот от BotFather" MSG = "Программировал ли ты сегодня, <>?"
Токены, ключи и прочие данные для настройки проекта лучше загружать более безопасным способом (например, создавать переменные окружения или файлы конфигурации). Но в данном случае сделаем все в одном файле для наглядности, а примеры более безопасной работы с такими переменными разберем в следующих постах.
Теперь создадим экземпляр класса Bot , передав ему в качестве аргумента наш токен, и экземпляр класса Dispatcher (dp), который в качестве аргумента получит bot . В результате получаем связку объекта класса bot с ключем, который привязан к боту, и диспетчера, который привязан к этому боту:
bot = Bot(token=TOKEN) dp = Dispatcher(bot=bot)
Следующим шагом добавим конструкцию под названием декоратор ( massage_handler ) — она помогает получить из диспетчера нужный функционал. В качестве аргумента прописываем команды, которые обрабатывает декоратор — в данном случае это команда /start , которая запускает бот.
@dp.message_handler(commands=['start'])
Под декоратором прописываем функцию, которая будет обрабатывать команду /start и определяет логику, в соответствии с которой будет работать бот. Поскольку мы работаем с асинхронной библиотекой, функция тоже должна быть асинхронной. Для этого перед указанием def добавим ключевое слово async :
async def start_handler(message: types.Message):
Функция приветствует пользователя и обрабатывает сообщение, которое он отправляет в ответ. Из сообщения можно получить информацию о пользователе, который его прислал, время отправки и его ID.
Создаем переменную и сохраняем в ней user id :
user_id = message.from_user.id
Затем получаем из сообщения короткое и полное имя пользователя:
user_name = message.from_user.first_name user_full_name = message.from_user.full_name
Для того, чтобы в логах отображалась информация о пользователе, передаем в виде текста ID и полное имя, а также используем возможности библиотеки time , чтобы определить время, когда писал пользователь:
logging.info(f' ')
Здесь отойдем в сторону и проверим корректность работы модуля time . Сделать это можно в терминале: для этого напишем import time , а затем — time.asctime
Вернемся к коду. Поскольку функция, которую мы используем, асинхронна, вместо обычного для функций return используем await :
await message.reply(f"Привет, !")
Ответить пользователю в боте можно несколькими способами — в данном случае используем reply. Выше в переменной MSG мы задали стандартное сообщение: «Программировал ли ты сегодня, <>?». Зададим частоту напоминаний: семь раз каждые семь суток (60х60х24 — количество секунд в одних сутках) с момента отправки команды /start боту от пользователя:
for i in range(7): await asyncio.sleep(60*60*24)
Затем настроим отправку сообщения с указанием имени пользователя в этом же цикле:
await bot.send_message(user_id, MSG.format(user_name))
Третий этап: финал
Переходим к финальной части: в конце скрипта напишем несколько строк. Они могут показаться странными для новичка, но это общепринятая практика, к которой многие программисты прибегают при разработке. В этой строке мы проверяем, равна ли переменная __name__ строке «__main__» . Это условие всегда будет True, если мы запускаем этот файл как python-скрипт через терминал:
if __name__ == '__main__':
Теперь делаем нашего бота доступным в сети:
executor.start_polling(dp)
Сохраняем файл. Запускаем бота в терминале, открытом в папке проекта, с помощью команды python bot.py .
Вернемся в BotFather и перейдем по ссылке, которую получили вместе с токеном. Нажимаем «Начать» — готово, бот, написанный меньше, чем в 30 строк, работает.
Так выглядит его код целиком:
import time import logging import asyncio from aiogram import Bot, Dispatcher, executor, types TOKEN = "здесьбудетваштокенот@BotFather" MSG = "Программировал ли ты сегодня, <>?" logging.basicConfig(level=logging.INFO) bot = Bot(token=TOKEN) dp = Dispatcher(bot=bot) @dp.message_handler(commands=["start"]) async def start_handler(message: types.Message): user_id = message.from_user.id user_name = message.from_user.first_name user_full_name = message.from_user.full_name logging.info(f' ') await message.reply(f"Привет, !") for i in range(7): await asyncio.sleep(60*60*24) await bot.send_message(user_id, MSG.format(user_name)) if __name__ == "__main__": executor.start_polling(dp)
В следующий раз подробно расскажем, как написать подобный бот на языке программирования JavaScript. Подписывайтесь, чтобы не пропустить инструкцию.

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

6 Апрель 2016 , Python, 454909 просмотров, How To Create a Telegram Bot Using Python
В последнее время Telegram у всех на слуху. Нужно отдать должное отделу маркетинга этого приложения, шумиху подняли на славу. Одной из основных «фишек» Telegram является его якобы защищённость — по словам Павла Дурова вся переписка между пользователями шифруется. Более того, ни одна спец.служба мира не будет иметь доступ к вашим сообщениям. Но в данной статье речь не об этом. Сегодня хотелось бы поговорить о не менее крутой фишке в Telegram, а именно о ботах. Помимо того, что в сети уже полно информации о различного рода Telegram ботах (github бот, например), мессенджер открыл своё API для разработчиков, и теперь каждый может создать своего собственного бота с блэкджеком и плюшками.
В статье я приведу пример написания онлайн бота с использованием Python и Django фреймворка. То есть мы «запилим» полноценное веб-приложение, которое будет крутиться на удалённом хосте и принимать команды от пользователей. Весь исходный текст доступен в моём github репозитории.
Документация, описывающая процесс взаимодействия с ботами Telegram находится тут. Чтобы не изобретать велосипед, я нашел неплохую Python библиотеку, реализующую все основные функции ботов — telepot. Как я уже упоминал ранее, для того, чтобы обслуживать пользователей нашего бота мы будет разрабатывать веб-приложение, используя Django фреймворк.
Как создать Telegram бота?
Для начала нам необходимо зарегистрировать в Telegram нашего будущего бота. Это делается следующим образом:
- Необходимо установить приложение Telegram на телефон или компьютер. Скачать приложение можно тут
- Добавляем к себе в контакт-лист бота с именем BotFather
- Запускаем процедуру «общения» с ботом нажатием кнопки Start. Далее перед нами предстанет список команд точно как на скриншоте.
- Для того, чтобы создать нового бота необходимо выполнить команду /newbot и следовать инструкциям. Обратите внимание, что username для бота должен всегда содержать в конце слово bot. Например, DjangoBot или Django_bot.

- Для нашего бота я выбрал имя PythonPlanetBot, так как его основная функция заключается в парсинге RSS feed сайта Python Planet и выдача информации о последних постах пользователю 🙂

После создания бота, обратите внимание на строку с текстом:
Use this token to access the HTTP API:
За которой следует т.н. token по которому мы будем манипулировать нашим ботом. Помимо функции создания telegram бота, BotFather также имеет ряд других возможностей:
- Присвоить боту описание
- Установить аватар
- Поменять token
и так далее. Полное описание доступных команд можно увидеть на первом скриншоте.
Приступаем к кодированию
Как я ранее уже упоминал, мы будем писать веб-приложение на Django. Но стоит отметить, что это делать необязательно. Можно обойтись и обычным Python скриптом, правда в этом случае необходимо будет периодически опрашивать Telegram на предмет новых запросов от пользователей бота (используя метод getUpdates) и увеличивая offset для получения самых последних данных без повторений. В Telegram существует два взаимоисключающих метода получения команд/сообщений для вашего бота.
- Использование вызова API метода getUpdates
- Установка Webhook
Установка Webhook заключается в передаче боту специального URL адреса на который будет поступать POST запрос каждый раз, когда кто-то начнёт посылать сообщения боту. Именно этот вариант мы и будем использовать для взаимодействия между ботом и его пользователем. Для того, чтобы задать URL, необходимо использовать API метод setWebhook. Отмечу, что URL должен начинаться с https, то есть иметь защищённое SSL соединение с валидным сертификатом. Telegram разрешает использовать самоподписанный сертификат, правда для этого необходимо в методе setWebhook передавать также публичный ключ в PEM формате (ASCII base64). Либо же можно получить валидный бесплатный SSL сертификат от Let’s Encrypt.
Подробнее о getUpdates и setWebhook можно почитать соответственно здесь и тут.
Итак, вернёмся к python библиотеке для работы с Telegram — telepot. На текущий момент самой последней её версий является 6.7. Устанавливаем её в виртуальное окружение python virtualenv:
pip install telepot
Самый простой вариант взаимодействия с Telegram ботом на Python выглядит следующим образом:
import telepot token = '123456' TelegramBot = telepot.Bot(token) print TelegramBot.getMe()
Переменной token присваиваем значение токена, полученного при создании бота через BotFather. В итоге после выполнения этих команд мы получим:
Поздравляю! Мы вызывали самый простой API запрос getMe, который возвращает информацию о боте: username, id, first_name.
Добавим нашего бота к себе в контакт-лист и пошлём ему первую стандартную команду /start

TelegramBot.getUpdates() [, u'message_id': 1, u'chat': >, u'update_id': 649179764>]
Процесс общения с telegram ботом происходит по HTTPS; для передачи данных используется JSON. Метод getUpdates возвращает список/массив из объектов типа Update. Внутри Update находится объект Message. Для стандартного взаимодействия с ботом нас фактически интересует именно объект Message, у которого мы считываем атрибут text, хранящий в себе текст, переданный боту и объект chat, в котором лежит информация о пользователе, инициировавшем общение с нашим Telegram ботом. Также имеется параметр update_id, который служит в качестве offset параметра при вызове метода getUpdates. То есть update_id+1 вернёт все сообщения, поступившие после последнего update_id, при этом все предыдущие сообщения будут удалены.
TelegramBot.getUpdates(649179764+1) [, u'message_id': 13, u'chat': >, u'update_id': 649179765>]
На этапе написания простейшего Telegram бота нам этих вызовов достаточно. Приступим к написанию Django приложения для обслуживания наших пользователей.
Простая функция парсинга RSS фида Planet Python выглядит вот так:
# -*- coding: utf8 -*- from xml.etree import cElementTree import requests def parse_planetpy_rss(): """Parses first 10 items from http://planetpython.org/rss20.xml """ response = requests.get('http://planetpython.org/rss20.xml') parsed_xml = cElementTree.fromstring(response.content) items = [] for node in parsed_xml.iter(): if node.tag == 'item': item = <> for item_node in list(node): if item_node.tag == 'title': item['title'] = item_node.text if item_node.tag == 'link': item['link'] = item_node.text items.append(item) return items[:10]
Здесь я использую python библиотеку requests для работы с HTTP в самом простейшем варианте без обработки ошибок. Django «вьюшка» выглядит следующим образом:
TOKEN = '' TelegramBot = telepot.Bot(TOKEN) def _display_help(): return render_to_string('help.md') def _display_planetpy_feed(): return render_to_string('feed.md', ) class CommandReceiveView(View): def post(self, request, bot_token): if bot_token != TOKEN: return HttpResponseForbidden('Invalid token') commands = < '/start': _display_help, 'help': _display_help, 'feed': _display_planetpy_feed, >try: payload = json.loads(request.body.decode('utf-8')) except ValueError: return HttpResponseBadRequest('Invalid request body') else: chat_id = payload['message']['chat']['id'] cmd = payload['message'].get('text') # command func = commands.get(cmd.split()[0].lower()) if func: TelegramBot.sendMessage(chat_id, func(), parse_mode='Markdown') else: TelegramBot.sendMessage(chat_id, 'I do not understand you, Sir!') return JsonResponse(<>, status=200) @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(CommandReceiveView, self).dispatch(request, *args, **kwargs)
CommandReceiveView ждёт POST запрос на себя, парсит его и отвечает исходя из заданной команды. Полноценное Django приложение можно найти по этой ссылке. Стоит отметить в коде использование ещё одного API вызова — sendMessage. Этот метод отправляет сообщение заданному пользователю, используя при этом chat_id и сам текст сообщения. Chat_id — это уникальный идентификатор чата между пользователем и ботом (его идентификатор есть в ответе на запрос getUpdates). У Telegram ботов есть одно ограничение, они не могут посылать сообщения пользователям, которые предварительно не инициировали общение с ним. По-видимому это сделано дабы избежать массового создания спам-ботов.
Я предполагаю, что вы уже клонировали мой репозиторий, настроили окружение и установили все необходимые зависимости: Django, requests, telepot. Если же вы не знаете как это сделать, то совсем скоро я напишу цикл статей о разработке веб-приложений на Python, включая разбор экосистемы: разработка, настройка, деплой. Если вам это интересно, то отпишитесь, пожалуйста, в комментариях к этой статье. Хочется получить обратную связь 🙂
Итак, веб-приложение на Django запущено. Как же начать тестировать бота? А всё очень просто — необходимо симулировать действия Telegram сервиса. Для этого нам понадобится HTTP клиент и тело запроса. В качестве HTTP клиента я часто использую Chrome плагин под названием Postman, а тело запроса мы возьмём напрямую из данных, полученных с помощью API вызова getUpdates.
После запуска runserver, URL на который необходимо посылать запрос выглядит следующим образом:
http://127.0.0.1:8000/planet/b. BOT_TOKEN/
где BOT_TOKEN — это токен нашего бота. Смотрим скриншот:


А давайте-ка отправим команду feed для получения списка новостей из Planet Python:


На скриншотах видно, что бот адекватно отреагировал на нашу команду вывести список последних 10 постов.
Следующим шагом является деплой нашего Django приложения на удалённый хост и последующий вызов метода setWebhook для передачи URL на который будет посылаться POST запрос от сервиса Telegram каждый раз при поступлении команд боту от пользователей. Об этом мы поговорим в следующей заметке.
Интересные записи:
- Обзор Python 3.9
- Pyenv: удобный менеджер версий python
- FastAPI, asyncio и multiprocessing
- Руководство по работе с HTTP в Python. Библиотека requests
- Введение в logging на Python
- Работа с MySQL в Python
- Django Channels: работа с WebSocket и не только
- Celery: начинаем правильно
- Почему Python?
- Что нового появилось в Django Channels?
- Авторизация через Telegram в Django и Python
- Python-RQ: очередь задач на базе Redis
- Введение в pandas: анализ данных на Python
- Работа с PostgreSQL в Python
- Разворачиваем Django приложение в production на примере Telegram бота
- Django, RQ и FakeRedis
- Интеграция Trix editor в Django
- Итоги первой встречи Python программистов в Алматы
- Обзор Python 3.8
- Участие в подкасте TalkPython
- Строим Data Pipeline на Python и Luigi
- Авторизация через Telegram в Django приложении
- Видео презентации ETL на Python