С ноября 2022 года Heroku отключает бесплатные тарифы, поэтому данная инструкция, начиная со второго шага, устарела. Размещайте бота где-нибудь ещё.
Каждый шаг этой инструкции соответствует одному из коммитов в данном репозитории.
-
Бот, работающий локально (первый коммит)
- Создадим пустого бота с помощью @BotFather - зададим ему имя и получим токен (ключ доступа)
- Установим питоновскую библиотеку
pytelegrambotapi
, с удобной обёрткой для телеграма. Это можно сделать, например, с помощью пакетного менеджераpip
. Все установленные библиотеки будем записывать вrequirements.txt
, чтобы потом они автоматически устанавливались на сервере. - Создадим файл
main.py
с примитивным ботом-повторюшкой. При запуске файла пароль от бота читается из переменных среды (чтобы не палить его в репозитории), создаются функции для ответа на сообщения, и бот запускается в режиме "polling" (когда ваша программа постоянно спрашивает Телеграм, нет ли обновлений) - Чтобы протестировать его, надо вписать пароль в переменные среды (вбить в командной строке
set TOKEN=...
на винде илиexport TOKEN=...
на маке и линуксе), а дальше запустить в командной строкеpython main.py
(предварительно перейдя в с помощьюcd
в папку с кодом) - и бот заработает! P.S. Я тестировал это на python 3.6, но по идее всё должно работать и с другими версиями.
-
Запуск бота на сервере heroku (второй коммит)
- Зарегистрируемся на heroku.com и создадим пустое приложение (я назвал его
example-telebot
). - Привяжем приложение к вашему репозиторию с ботом на гитхабе скриншот. Если ещё потом и поставить галочку "Enable automatic deploys", то бот будет перезапускаться на heroku после каждого коммита автоматически.
- Чтобы heroku знал, что именно надо запускать, создадим для него файл Procfile с единственной строчкой
web: python main.py
- Для продакшна режим polling не годится (неэффективен и частенько ломается), но на сервере бота можно запускать в
другом режиме, "webhook", когда Telegram сам обращается к вашему серверу. Для этого сервер должен уметь
обрабатывать запросы; мы добьемся этого, используя фреймворк Flask. Установим его также с помощью
pip
. - Допишем файл
main.py
: теперь кроме бота появляется объект server, который передаёт сообщения боту в функцииget_message
. - Сам сервер имеет смысл запускать только на heroku, поэтому мы будем выбирать между режимами webhook и polling
в зависимости от аргумента командной строки
poll
. То есть теперь, чтобы запустить бота не на heroku, а на своем компьютере, нужно будет писатьpython main.py --poll
- Чтобы на heroku бот мог получить токен, его надо добавить в переменные среды heroku, примерно так.
- Теперь можно коммитить и пушить изменения, и за пару минут они приедут на heroku, и бот заработает оттуда.
- Зарегистрируемся на heroku.com и создадим пустое приложение (я назвал его
-
Исправление ошибок (3 и 4 коммиты)
- Я забыл добавить flask в
requirements.txt
, и на heroku бот сначала не запустился. - После установки flask бот всё равно не запускался, и я добавил функцию webhook, чтобы его будить, открывая страничку приложения в браузере.
- Я забыл добавить flask в
-
Связывание приложения с базой данных mongodb (5 коммит).
- mongo может показаться необычным выбором, потому что это nosql база. Но мне и не хочется морочиться с sql; к тому же, в heroku mongo довольно объемная и дешёвая. Бесплатный аккаунт можно добавить так
- Открыв добавленную иконку mongo, перейдём в её админку, и создадим новую "коллекцию" (аналог таблицы)
по имени
logs
. - Обратите внимание, что теперь в переменных среды heroku появилась ещё одна,
MONGODB_URI
. Мы будем ей пользоваться, поэтому, если вы хотите запускать бота локально, её надо копировать себе в командную строку. - Установим библиотеку
pymongo
и добавим её вrequirements.txt
. - Модифицируем
main.py
: настроим доступ к таблице и создадим функцию-обёрткуreply_with_log
, которая бы и отвечала ботом, и записывала бы реплику пользователя и ответ на неё в таблицуlogs
. - Чтобы убедиться, что логи действительно пишутся, создадим простенькую веб-страничку, которая бы визуализировала
последние 10 сообщений и их общее число. У нас уже есть flask, и туда надо просто добавить новую функцию.
Назовём её
show_logs
. Тут я генерирую html просто "вручную", но на самом деле во flask есть куда более удобные методы для этого (например, шаблоны jinja). - В принципе, это всё. Вот ссылка на бота, на страничку с логами, на репозиторий. Клонируйте его, учитесь и веселитесь!