Бот для Telegram на Python: от первой строчки кода до запуска на Heroku

24 июня разработчики Telegram открыли платформу для создания ботов. Новость кого-то обошла стороной Хабр, однако многие уже начали разрабатывать викторины. При этом мало где указаны хоть какие-то примеры работающих ботов. Прежде всего, бот для Telegram — это по-прежнему приложение, запущенное на вашей стороне и осуществляющее запросы к Telegram Bot API. Причем API довольное простое — бот обращается на определенный URL с параметрами, а Telegram отвечает JSON объектом. Рассмотрим API на примере создания тривиального бота:

1. Регистрация

Прежде чем начинать разработку, бота необходимо зарегистрировать и получить его уникальный id, являющийся одновременно и токеном. Для этого в Telegram существует специальный бот — @BotFather. Пишем ему /start и получаем список всех его команд. Первая и главная — /newbot — отправляем ему и бот просит придумать имя нашему новому боту. Единственное ограничение на имя — оно должно оканчиваться на «bot». В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты, иначе придется поломать голову над именем. Для начала работы этого уже достаточно. Особо педантичные могут уже здесь присвоить боту аватар, описание и приветственное сообщение. Не забудьте проверить полученный токен с помощью ссылки /getMe»>api.telegram.org/bot/getMe, говорят, не всегда работает с первого раза.

2. Программирование

Создавать бота буду на Python3, однако благодаря адекватности этого языка алгоритмы легко переносятся на любой другой. Telegram позволяет не делать выгрузку сообщений вручную, а поставить webHook, и тогда они сами будут присылать каждое сообщение. Для Python, чтобы не заморачиваться с cgi и потоками, удобно использовать какой-нибудь реактор, поэтому я для реализации выбрал tornado.web. (для GAE удобно использовать связку Python2+Flask) Каркас бота:

URL = "https://api.telegram.org/bot%s/" % BOT_TOKEN MyURL = "https://example.com/hook"  api = requests.Session() application = tornado.web.Application([     (r"/", Handler), ])  if __name__ == '__main__':     signal.signal(signal.SIGTERM, signal_term_handler)     try:         set_hook = api.get(URL + "setWebhook?url=%s" % MyURL)         if set_hook.status_code != 200:             logging.error("Can't set hook: %s. Quit." % set_hook.text)             exit(1)         application.listen(8888)         tornado.ioloop.IOLoop.current().start()     except KeyboardInterrupt:         signal_term_handler(signal.SIGTERM, None) 

Здесь мы при запуске бота устанавливаем вебхук на наш адрес и отлавливаем сигнал выхода, чтобы вернуть поведение с ручной выгрузкой событий. Приложение торнадо для обработки запросов принимает класс tornado.web.RequestHandler, в котором и будет логика бота.

class Handler(tornado.web.RequestHandler):         def post(self):             try:                 logging.debug("Got request: %s" % self.request.body)                 update = tornado.escape.json_decode(self.request.body)                 message = update['message']                 text = message.get('text')                 if text:                     logging.info("MESSAGEt%st%s" % (message['chat']['id'], text))                      if text[0] == '/':                         command, *arguments = text.split(" ", 1)                         response = CMD.get(command, not_found)(arguments, message)                         logging.info("REPLYt%st%s" % (message['chat']['id'], response))                         send_reply(response)             except Exception as e:                 logging.warning(str(e)) 

Здесь CMD — словарь доступных команд, а send_reply — функция отправки ответа, которая на вход принимает уже сформированный объект Message. Собственно, её код довольно прост:

def send_reply(response):     if 'text' in response:         api.post(URL + "sendMessage", data=response) 

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

3. Команды

Перво-наперво, необходимо соблюсти соглашение Telegram и научить бота двум командам: /start и /help:

def help_message(arguments, message):     response = {'chat_id': message['chat']['id']}     result = ["Hey, %s!" % message["from"].get("first_name"),               "rI can accept only these commands:"]     for command in CMD:         result.append(command)     response['text'] = "nt".join(result)     return response 

Структура message[‘from’] — это объект типа User, она предоставляет боту информацию как id пользователя, так и его имя. Для ответов же полезнее использовать message[‘chat’][‘id’] — в случае личного общения там будет User, а в случае чата — id чата. В противном случае можно получить ситуацию, когда пользователь пишет в чат, а бот отвечает в личку. Команда /start без параметров предназначена для вывода информации о боте, а с параметрами — для идентификации. Полезно её использовать для действий, требующих авторизации. После этого можно добавить какую-нибудь свою команду, например, /base64:

def base64_decode(arguments, message):     response = {'chat_id': message['chat']['id']}     try:         response['text'] = b64decode(" ".join(arguments).encode("utf8"))     except:         response['text'] = "Can't decode it"     finally:         return response 

Для пользователей мобильного Telegram, будет полезно сказать @BotFather, какие команды принимает наш бот: I: /setcommands
BotFather : Choose a bot to change the list of commands.
I: @******_bot
BotFather: OK. Send me a list of commands for your bot. Please use this format:

command1 - Description
command2 - Another description
I:
whoisyourdaddy - Information about author
base64 - Base64 decode
BotFather: Success! Command list updated. /help

C таким описанием, если пользователь наберет /, Telegram услужливо покажет список всех доступных команд.

4. Свобода

Как можно было заметить, Telegram присылает сообщение целиком, а не разбитое, и ограничение на то, что команды начинаются со слеша — только для удобства мобильных пользователей. Благодаря этому можно научить бота немного говорить по-человечески.UPD:
Как верно подсказали, такое пройдет только при личном общении. В чатах боту доставляются только сообщения, начинающиеся с команды (/<commans://core.telegram.org/bots#privacy-mode)

  • All messages that start with a slash ‘/’ (see Commands above)
  • Messages that the bot by username
  • Replies to the bot’s own messages
  • Service messages (people added or removed from the group, etc.)

Чтобы бот получал все сообщения в группах пишем @BotFather команду /setprivacy
и выключаем приватность. Для начала в Handler добавляем обработчик:

if text[0] == '/':     ... else:     response = CMD[""](messalogging.info("REPLYt%st%s" % (message['chat']['id'], response))     send_reply(response) 

А потом в список команд добавляем псевдо-речь:

RESPONSES = {     "Hello": ["Hi there!", "Hi!", "Welcome!", "Hello, {name}!"],     "Hi there": ["Hello!", "Hello, {name}!", "Hi!", "Welcome!"],     "Hi!": ["Hi there!", "Hello, {name}!", "Welcome!", "Hello!"],     "Welcome": ["Hi there!", "Hi!", "Hello!", "Hello, {name}!",], } def human_response(message):     leven = fuzzywuzzy.process.extract(message.get("text", ""), RESPONSES.keys(), limit=1)[0]     response = {'chat_id': message['chat']['id']}     if leven[1] < 75:         response['text'] = "I can not understand you"     else:         response['text'] = random.choice(RESPONSES.get(leven[0])).format_map(             {'name': message["from"].get("first_name", "")}         )     return response 

Здесь эмпирическая константа 75 относительно неплохо отражает вероятность того, что пользователь всё-таки хотел сказать. А format_map — удобна для одинакового описания строк как требующих подстановки, так и без нее. Теперь бот будет отвечать на приветствия и иногда даже обращаться по имени.

5. Не текст.

Боты, как и любой нормальный пользователь Telegram, могут не только писать сообщения, но и делиться картинками, музыкой, стикерами. Для примера расширим словарь RESPONSES:

RESPONSES["What time is it?"] = ["", "{date} UTC"] </c

И будем отлавливать текст :

if respo'text'] == "":         response[cker'] = "BQADAgADeAcAAlOx9wOjY2jpAAHq9DUC"         del response['text'] 

Видно, что теперь структура Message уже не содержит текст, поэтому необходимо модифицировать send_reply:

def send_reply(response):     if 'sticker' in response:         api.post(URL + "sendSticker", data=response)     elif 'text' in response:         api.post(URL + "sendMessage", data=response) 

И все, теперь бот будет время от времени присылать стикер вместо времени:

6. Возможности

Благодаря удобству API и быстрому старту боты Telegram могут стать хорошей платформой для автоматизации своих действий, настройки уведомлений, создания викторин и task-based соревнований (CTF, DozoR и прочие). Вспоминая статью про умный дом, могу сказать, что теперь извращений меньше, а работа прозрачнее.

7. Ограничения

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

while True:             r = requests.get(URL + "?offset=%s" % (last + 1))             if r.status_code == 200:                 for message in r.json()["result"]:                     last = int(message["update_id"])                     requests.post("http://localhost:8888/",                                   data=json.dumps(message),                                   headers={'Content-type': 'application/json',                                            'Accept': 'text/plain'}                      )             else:                 logging.warning("FAIL " + r.text)             time.sleep(3) 

P.S. По пункту 7 нашел удобное решение — размещение бота не у себя, а на heroku, благо все имена вида *.herokuapp.com защищены их собственным сертификатом. UPD: Telegram улучшили Бот Апи, из-за чего, теперь не обязательно иметь отдельную функцию для отправки сообщений при установленном вебхуке, а в ответ на POST запрос можно отвечать тем же сформированным JSON с ответным сообщением, где одно из полей устанавливается как ч 'method': 'sendMessage' (или любой другой метод, используемый ботом).

730

902.1k


730

Делаем простого бота для публикации новостей в канал и автоматические ответы на вопросы за 6 шагов.

В закладки

Материал подготовлен при поддержке Selectel

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

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

Начнем с разработки бота, который сможет автоматически отправлять в Telegram-канал новости компании, опубликованные на сайте или в Facebook.

Шаг 1. Создаём бота в Telegram

Бот в Telegram создается при помощи другого бота под названием BotFather. Отправляем ему команду /newbot, выбираем имя, которое будет отображаться в списке контактов, и адрес. Например, «Бот для DTF» с адресом «dtf_news_bot».

Если адрес не занят, а имя введено правильно, BotFather пришлет в ответ сообщение с токеном — «ключом» для доступа к созданному боту. Его нужно сохранить и никому не показывать.

Через BotFather также можно добавить аватарку для бота, описание и прочее.

Шаг 2. Создаём канал в Telegram

Теперь создаём канал с любым названием и адресом, и переходим в его настройки. Всё, что требуется — добавить в список администраторов созданного нами бота — именно он будет публиковать заметки в канал.

Для поиска бота можно использовать его адрес. Например, «dtf_news_bot».

Шаг 3. Создание условия

Следующий этап — научить бота отправлять новости с сайта в созданный канал. Для этого воспользуемся популярным сервисом для автоматизации IFTTT.

С его помощью можно создавать инструкции для работы бота. В нашем случае она выглядит так: каждый раз, когда в RSS-ленте сайта появляется новая запись, он должен отправлять сообщение в канал Telegram.

IFTTT расшифровывается как If This Then That

Переходим в раздел IFTTT "My Applets", нажимаем на кнопку "New Applet" и далее на ссылку "This". Находим в списке функций триггер Feed, New feed item и указываем URL-адрес нашей RSS-ленты. Например, у WordPress-сайтов она обычно расположена по адресу example.com/feed/.

Вместо RSS-ленты можно отслеживать появление новых записей в Twitter или Facebook-аккаунте — для каждой функции в IFTTT предусмотрены отдельные модули.

Теперь переходим ко второму шагу — выбираем действие, которое будет выполняться при обнаружении новой записи в RSS. Нажимаем на "That" и ищем Maker Webhook, "Make a web request" — с помощью этого модуля можно отправлять запросы к любым сервисам. В нашем случае — к боту в Telegram.

В открывшейся форме в поле URL нужно указать ссылку https://api.telegram.org/botТОКЕН
/sendMessage, подставив в неё токен, сгенерированный на первом шаге. Метод: POST, тип контента: application/json.

Body — поле для шаблона запроcа, который будет отправляться в Telegram. В нём указываем, в какой канал нужно отправить сообщение и что в нём должно быть написано:

{"chat_id":"@адрес_канала", "text":"{{EntryTitle}} {{FeedUrl}}"}
  • chat_id
    — адрес канала, в который необходимо отправить сообщение. Таким образом одного бота можно подключить сразу к нескольким каналам. В качестве адресата можно указать и конкретного пользователя. В таком случае вместо адреса канала необходимо указать его ID (можно получить при помощи бота).
  • text
    — содержание сообщения. Например, заголовок материала из RSS (EntryTitle), его содержание (EntryContent) и ссылка (FeedUrl). Список доступных опций можно посмотреть по кнопке Ingredient.

Если всё настроено верно, бот отправит сообщение из RSS-ленты в канал. У триггера в IFTTT есть задержка, поэтому сообщение, появившееся в RSS-ленте, отправится в Telegram не сразу, а спустя 30-60 минут.

В качестве условия для отправки сообщения можно выбрать любой другой сценарий, доступный на IFTTT. Например, Weather Underground умеет каждый день отправлять сообщение с прогнозом погоды на завтра. Триггер Stocks можно настроить на отправку стоимости акций при закрытии торгов.

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

Шаг 4. Подключаем сервер

На этом этапе понадобится веб-хостинг и сертификат SSL, который можно получить бесплатно с помощью сервиса Let's Encrypt.

Удобнее всего создать отдельный поддомен для бота — например, bot.example.com — и разместить на нём один файл index.php. Внутри файла размещаем код простейшего бота c сайта Telegram.

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

В код бота нужно внести всего два изменения:

  • в строке define('BOT_TOKEN', '12345678:replace-me-with-real-token');
    вместо 12345678:replace-me-with-real-token написать токен, полученный на первом шаге;
  • в строке define('WEBHOOK_URL', 'https://my-site.example.com/secret-path-for-webhooks/');
    вместо https://my-site.example.com/secret-path-for-webhooks/ указать URL-адрес файла с кодом для бота: https://bot.example.com/index.php.

Шаг 5. Связываем Telegram-бота и сервер

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

Для этого понадобится консоль. У разных хостинг-провайдеров она может находиться в разных разделах интерфейса управления сайтом. Кроме того, можно воспользоваться программой Terminal на macOS, введя через неё команду ssh имя_пользователя@адрес_домена
.

После ввода пароля, печатаем для нашего поддомена простую команду:

php -f /var/www/bot.example.com/index.php

Если всё сделано правильно, бот сразу отправит в Telegram сообщение "Hello".

Шаг 6. Настраиваем текст автоответов бота

Добавим различные сценарии для ответов бота. Открываем созданный ранее файл index.php и находим в нём строчку:

} else if ($text === "Hello" || $text === "Hi") { apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Nice to meet you'));
  • Hello и Hi — текст пользователя, на который бот должен отреагировать.
  • Nice to meet you — ответ бота на отправленное пользователем сообщением.

Ниже в коде добавляем дополнительные ответы. Например, чтобы в зависимости от отправленного слова, бот присылал необходимую информацию пользователю (как в боте vc.ru для «ВКонтакте»):

} else if ($text === "Цены") { apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Прайс-лист можно скачать по ссылке example.com/price')); } else if ($text === "Контакты") { apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Контактный адрес для связи — secret@vc.ru'));

Можем указать любое количество фраз и ответов на них. Также можно изменить кнопки, доступные пользователю во время работы с ботом. Находим строчку кода 'keyboard' => array(array('Hello', 'Hi'))
и вместо Hello
и Hi
указываем «Цены» и «Контакты».

После сохранения файла изменения сразу вступят в силу.

Промокод

Специально для читателей vc.ru доступен промокод на 250 рублей при заказе хостинга Vscale. Укажите "VC250” в виджете с балансом. Промокод действует до 1 июня 2017 года.

#партнерский#selectel#инструкции#разработка

Адаптированный перевод статьи «How to Create and Deploy a Telegram Bot?»

Вступление

На первый взгляд, Telegram — это просто очередной мессенджер. Реклама гласит, что он быстр, защищён, в нём нет рекламы и всё такое. Но у него есть важная фича — боты!

Бот — это не просто «автоответчик». Его правильнее считать автоматизированным помощником. Представим, что вы хотите поделиться в групповом чате видео с YouTube, но ссылки у вас нет.

Вот стандартный алгоритм действий без бота:

  • открываем YouTube в браузере;
  • находим видео;
  • нажимаем на «Поделиться» (и надеемся, что в списке будет наш мессенджер);
  • если нашего мессенджера в списке не оказалось, копируем ссылку на видео;
  • возвращаемся в мессенджер и делимся ссылкой.

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

  • переписываемся в мессенджере;
  • вводим @vid
    и название видео, которое вы хотите найти и скинуть в беседу;
  • отправляем его.

Удобно, не правда ли? И это лишь одна из возможностей.

Системный аналитик

Sportmaster Lab, Москва, до 150 000 ₽ (до налогов)

tproger.ru
Вакансии на tproger.ru

Telegram позволяет пользователям создавать своих ботов. Ответим на вопрос «Почему мне стоит написать своего?» — это, пожалуй, самый простой способ понять, что такое API.

Круто, начинаем писать бота?

Обо всём по порядку. Сперва нужно зарегистрироваться в Telegram. Наиболее удобно использовать веб-клиент для знакомства с основными принципами работы ботов и API.

Откройте приложение, найдите @BotFather и начните беседу. Отправьте команду /newbot
и следуйте инструкциям. После выполнения первых шагов вы получите:

  • свой токен;
  • адрес Telegram API (https://api.telegram.org/bot);
  • ссылку на документацию.

Собственно, вот и всё. На данном этапе ваш бот полностью пассивен.

Вам нужно начать беседу с ботом. Введите в поисковой строке его имя и нажмите на кнопку /start
. Отправьте сообщение, например, «Привет». Это первое сообщение очень важно, поскольку оно станет первым обновлением, которое получит ваш бот.

Если вы в первый раз работаете с API, то разобраться вам поможет браузер. Откройте новую вкладку и воспользуйтесь Telegram API, перейдя по ссылке:

https://api.telegram.org/bot/getUpdates

Открыв этот адрес в браузере, вы отправите запрос на сервер Telegram, и он ответит вам в формате JSON. Ответ чем-то похож на словарь в Python. Вы увидите что-то вроде такого:

{   "ok":true,   "result":[{     "update_id":523349956,     "message":{       "message_id":51,       "from":{         "id":303262877,         "first_name":"YourName"       },       "chat":{         "id":303262877,         "first_name":"YourName",         "type":"private"       },       "date":1486829360,       "text":"Hello"     }   }] }

Если вы изучите раздел метода/sendMessage
в документации, то увидите, что он принимает два параметра: chat_id
и text
. Вы можете создавать цепочки параметров в адресной строке браузера, используя ?
для первого и &
для всех последующих. Команда для отправки сообщения будет выглядеть так:

/sendMessage?chat_id=303262877&text=test

Попробуйте получить ответ от вашего бота, подставив в качестве chat_id
значение, полученное после вызова /getUpdates
(в нашем примере — 303262877
). Текст сообщения может быть любым. Запрос должен выглядеть примерно так:

https://api.telegram.org/bot/sendMessage?chat_id=303262877&text=Hello

И когда же будет код?

Если вы пользуетесь Windows и у вас не установлен Python, скачать его можно с официального сайта. Вообще версия не важна, но в этой статье будет использоваться Python 3.x. Если же у вас Linux или macOS, то обе версии (или, как минимум, Python 2.x) уже установлены.

Затем нужно установить pip. В версиях выше Python 2.7.9 и Python 3.4, а также на macOS/Linux он уже есть. Проверить это можно командой pip --version
в терминале. Если же по каким-то причинам он отсутствует, установить его можно при помощи команды:

$ sudo apt-get install python-pip

Загвоздка в том, что разные версии Python используют разные pip. Если у вас macOS, вы можете попробовать следовать советам со Stack Overflow. В случае с Windows вам нужно скачать get-pip.py, открыть командную строку, перейти в директорию со скачанным файлом и выполнить команду:

$ python get-pip.py

Самое сложное позади. Установим пакет requests при помощи pip:

$ pip install requests

А теперь — код

Теперь, когда вы поняли, что такое API, и установили все необходимые инструменты, напишем скрипт, который будет проверять обновления и отвечать на новые сообщения.

Сперва бот должен проверить обновления. Первое сообщение можно расценивать как самое свежее, но getUpdates
возвращает все обновления за последние 24 часа. Напишем небольшой скрипт, чтобы получить самое последнее обновление:

import requests  url = "https://api.telegram.org/bot/"   def get_updates_json(request):       response = requests.get(request + 'getUpdates')     return response.json()   def last_update(data):       results = data['result']     total_updates = len(results) - 1     return results[total_updates]

Словарь обновлений состоит из двух элементов: ok
и results
. Нас интересует вторая часть — список всех обновлений, полученных ботом за последние 24 часа.

Узнать больше о библиотеке requests можно, прочитав документацию. По сути, каждый раз, когда вам нужно получить, обновить или удалить информацию, хранящуюся на сервере, вы отправляете запрос и получаете ответ.

Теперь нужно добавить ещё 2 функции. Первая будет доставать chat_id
из обновления, а вторая — отправлять сообщение.

def get_chat_id(update):       chat_id = update['message']['chat']['id']     return chat_id  def send_mess(chat, text):       params = {'chat_id': chat, 'text': text}     response = requests.post(url + 'sendMessage', data=params)     return response  chat_id = get_chat_id(last_update(get_updates_json(url))) send_mess(chat_id, 'Your message goes here')

Помните, как мы объединяли параметры при помощи ?
и &
? Вы можете сделать то же самое, добавив словарь в качестве второго дополнительного параметра в функциях get
/post
из пакета requests.

Скрипт готов, но он не идеален. Главным минусом является необходимость запускать его каждый раз, когда мы хотим, чтобы бот отправил сообщение. Исправим это. Чтобы бот слушал сервер и получал обновления, нам нужно запустить основной цикл. На новой строке, после import requests
, добавьте from time import sleep
. После этого замените две последние строки на следующий код:

def main():       update_id = last_update(get_updates_json(url))['update_id']     while True:         if update_id == last_update(get_updates_json(url))['update_id']:            send_mess(get_chat_id(last_update(get_updates_json(url))), 'test')            update_id += 1         sleep(1)         if __name__ == '__main__':       main()

Хотя мы и добавили таймаут в 1 секунду, пример выше можно использовать только в обучающих целях, поскольку он использует частые опросы (short polling). Это плохо влияет на сервера Telegram, поэтому их нужно избегать. Есть ещё два способа получения обновлений через API — длинные опросы (long polling) и вебхуки (webhooks). Если мы будем использовать способ получения обновлений через getUpdates
 без параметров, то запросы будут происходить слишком часто.

Поскольку мы начали использовать в скрипте основной цикл, мы должны переключиться на длинные опросы. Сперва изменим первую функцию, добавив в неё параметр timeout
. Сам по себе он не уменьшит частоту проверки обновлений и будет работать только в том случае, когда обновлений нет. Чтобы помечать уже просмотренные обновления, нужно добавить параметр сдвига offset
:

def get_updates_json(request):       params = {'timeout': 100, 'offset': None}     response = requests.get(request + 'getUpdates', data=params)     return response.json()

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

import requests   import datetime  class BotHandler:      def __init__(self, token):         self.token = token         self.api_url = "https://api.telegram.org/bot{}/".format(token)      def get_updates(self, offset=None, timeout=30):         method = 'getUpdates'         params = {'timeout': timeout, 'offset': offset}         resp = requests.get(self.api_url + method, params)         result_json = resp.json()['result']         return result_json      def send_message(self, chat_id, text):         params = {'chat_id': chat_id, 'text': text}         method = 'sendMessage'         resp = requests.post(self.api_url + method, params)         return resp      def get_last_update(self):         get_result = self.get_updates()          if len(get_result) > 0:             last_update = get_result[-1]         else:             last_update = get_result[len(get_result)]          return last_update

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

greet_bot = BotHandler(token)   greetings = ('здравствуй', 'привет', 'ку', 'здорово')   now = datetime.datetime.now()   def main():       new_offset = None     today = now.day     hour = now.hour      while True:         greet_bot.get_updates(new_offset)          last_update = greet_bot.get_last_update()          last_update_id = last_update['update_id']         last_chat_text = last_update['message']['text']         last_chat_id = last_update['message']['chat']['id']         last_chat_name = last_update['message']['chat']['first_name']          if last_chat_text.lower() in greetings and today == now.day and 6 <= hour < 12:             greet_bot.send_message(last_chat_id, 'Доброе утро, {}'.format(last_chat_name))             today += 1          elif last_chat_text.lower() in greetings and today == now.day and 12 <= hour < 17:             greet_bot.send_message(last_chat_id, 'Добрый день, {}'.format(last_chat_name))             today += 1          elif last_chat_text.lower() in greetings and today == now.day and 17 <= hour < 23:             greet_bot.send_message(last_chat_id, 'Добрый вечер, {}'.format(last_chat_name))             today += 1          new_offset = last_update_id + 1  if __name__ == '__main__':       try:         main()     except KeyboardInterrupt:         exit()

Теперь вы можете улучшать бота так, как захотите. Можно, например, настроить отправку медиафайлов или добавить собственные кнопки.

Устрой деплой

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

Сперва зарегистрируйтесь на GitHub. Создайте аккаунт (рано или поздно он вам точно пригодится) и установите Git. На Linux выполните следующую команду:

$ sudo apt-get install git-all

На macOS и Windows его нужно скачать и установить вручную. И не забудьте зарегистрироваться на Heroku.

Установите virtualenv:

$ pip install virtualenv

Теперь вам нужно навести порядок в файлах. Создайте новую папку и перейдите в неё в терминале или командной строке. Инициализируйте в ней virtualenv
:

$ virtualenv my_env

Имя не имеет значения, но лучше сделать его интуитивно понятным. Перейдите в папку my_env
.

Теперь вам нужно склонировать git-репозиторий. Введите следующую команду:

$ git clone https://github.com/имя_вашего_профиля/имя_вашего_репозитория

Поместите скрипт в папку, полученную в результате выполнения команды git clone
.

Вернитесь в папку my_env
и запустите virtualenv
:

  • На Windows:
    $ scriptsactivate.bat
    
  • На Linux/macOS:
    $ source bin/activate
    

Если вы успешно запустили virtualenv
, приглашение командной строки должно начинаться с (my_env).

Перейдите в папку репозитория и ещё раз установите модуль requests:

$ pip install requests

Теперь нужно создать список зависимостей Heroku. Это несложно. Введите:

$ pip freeze > requirements.txt

Создайте Procfile
. В этом файле вам нужно разместить инструкции по работе с вашим скриптом. Имя файла обязательно должно быть Procfile
(Procfile.windows
в случае с Windows). У него не должно быть других расширений. Содержимое файла должно быть таким (замените my_bot
на имя вашего скрипта):

web: python my_bot.py

Добавьте файл __init__.py
в вашу папку. Он может быть пустым, но он должен там быть.

Отправьте коммит с изменениями в репозиторий:

$ git init $ git add . $ git commit -m ‘короткое сообщение, описывающее изменения в коммите’ $ git push -u https://github.com/имя_вашего_профиля/имя_вашего_репозитория

Теперь развернём бота на Heroku. Можно использовать и панель управления на сайте, но мы потренируемся делать всё через консоль. Если вы столкнётесь с какими-то проблемами, обратитесь к этому руководству.

Рассмотрим лишь те действия, которые нужны для развёртывания приложения. Если вы пользуетесь macOS или Windows, установите интерфейс командной строки, следуя гайду.

Если вы пользуетесь Ubuntu, используйте следующие команды:

$ sudo add-apt-repository "deb https://cliassets.heroku.com/branches/stable/apt ./" $ curl -L https://cli-assets.heroku.com/apt/release.key | $ sudo apt-key add - $ sudo apt-get update $ sudo apt-get install heroku

Если возникнут ошибки, проверьте, присутствуют ли все зависимости.

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

$ heroku login $ heroku create $ git push heroku master $ heroku ps:scale web=1 $ heroku open

С этого момента ваше приложение должно работать на сервере Heroku. Если что-то пойдёт не так, проверить логи можно следующим образом:

$ heroku logs --tail

Коды ошибок можно найти на сайте Heroku.

Бесплатный аккаунт накладывает некоторые ограничения. Тем не менее теперь у вас есть полностью рабочий бот — поздравляем! Продолжить изучение возможностей ботов для Telegram вам поможет видеокурс — в нём используют PHP, но суть остаётся той же.

Не смешно? А здесь смешно: @ithumor

Рейтинг автора
5
Подборку подготовил
Андрей Ульянов
Наш эксперт
Написано статей
168
Ссылка на основную публикацию
Похожие публикации