Telegram bot on centos7

2

Как-то, очередным одиноким вечером, мне стало скучно и захотелось поговорить (Ох уж эти социальные потребности человеков). Что ж, пришлось сделать для этого бота.

Купились? Ха! На самом деле мне конечно же есть с кем поговорить (нет), просто тема с телеграмом и ботами обошла меня стороной, потому что у меня никогда не было аккаунта (не было надобности), а тут по работе приходится там “чатиться”, ну раз произошло такое, что я обзавёлся акком, значит пришла пора изучить “телегу” чуть лучше чем никак. Вообще, очень давно, в далёких 2000-ых я пользовался ICQ (исключительно по работе) и там я писал бота на перле; самый простой эхо-бот, который отвечал заранее вбитыми в него фразами. У этого бота было одно великое предназначение, жаль, что всё провалилось… ну да ладно, в сторону горькое прошлое, приступим к изучению матчасти!

С чего начать?

Конечно же с чтения RTFM, НО так как букоф много, а времени мало – смело кладём хер на доку по API и следуем step-by-step за аффтором пока он жжот.
И так, для приготовления бота нам понадобятся следующие ингредиенты:

  • Centos 7
  • python3. Ну типа, 2k18 на пороге, а через 2 года поддержка python2.7 будет окончена, пора нехотя переползать на третью ветку…
  • python virtual env. К сожалению, centos7 ещё не готов к python3, а особенно скудные репозитории redhat, поэтому нам придётся тащить модули из гита/pip’ом, НО чтоб в хламьё не зафоршмачить всем этим говном систему; чтоб не бороться одним тоскливым вечером с неразрешаемыми зависимостями при обновлении; чтоб не сидеть с грустной миной перед монитором после того, как зависимости разрешили, но скрипты больше не работают; чтоб избежать всех этих и других факапов – мы будем использовать виртуальные окружения змеюки.
  • pytelegrambotapi. Собсно, это либа для общения с telegram api коих херова тонна и, вобщем-то, можно даже без неё обойтись, но-о-о как я уже писал ранее – букаф много, времени мало, и поэтому я делегирую транспорт опытным программистам, авторам модуля, которые знают как лучше наладить общение между ботом и api.

Вобщем-то это всё, ну не исключая конечно же холодной головы, горячего сердца, здравого рассудка и щепотки фантазии. Приступим!

Понеслася!



Перво-наперво, нам понадобится зарегистрировать бота в telegram. В отличии от ICQ, в telegram есть очень чёткая грань между аккаунтами для людей, и аккаунтами для ботов. Заходим под своим аккаунтом а телегу как Вам это удобно: будь то веба, или клиент, – это не имеет значения; и ищем там вот этого товарища: @BotFather – это официальный бот telegram inc. для управления другими, пользовательскими ботами. Начинаем с ним беседу кнопкой “Start!” и следуя его подсказкам регистрируем себе бота, это очень просто и букаф там не оч много, вы справитесь, я в вас верю! Результатом вашей беседы с батей должен стать токен (Пример: 0123456789:AAAAA-hsnheHG3nBSbv2MM23bsallOpwkes) по которому будет авторизоваться ваш бот. Записываем его куда-нить чтоб не забыть и переходим к настройке серверного окружения.
На сервере с Centos7 нам понадобится epel-repo где пакеты чуть посвежей чем в base (Но запашок от них тем не менее тот ещё).

yum install epel-release

Далее нам понадобится пакет python34-devel.x86_64 в составе которого, помимо прочего нам ненужного хлама, есть тот самый pyenv о котором я писал ранее в ингредиентах и pip при помощи которого мы поставим нужный нам модуль для общения с api telegramm.

yum install python34-devel.x86_64

Создаём директорию в которой будут храниться ваши вирутальные окружения в расчёте: один скрипт – одно окружение.

mkdir -p /usr/local/sbin/venvs && cd "$_"

Мы создали общую для вирутальных окружений директорию venvs и командой cd "$_" мы перешли в эту директорию.
Теперь необходимо создать виртуальный домик для нашего бота.

pyvenv-3.4 telebot

В результате команды будет создана директория telebot с кучей дочерних директорий для модулей и библиотек. Заходим в эту директорию (cd telebot) и активируем виртуальное окружение (если надо, то деактивировать его можно командой deactivate).

source bin/activate

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

(telebot) root /usr/local/sbin/venvs/telebot #

Если всё так – поздравляю! Вы ещё не накосячили и всё, как поговаривал товарищ Летов, идёт по-плану. Мы в виртуальном окружении, в котором можно извращаться над питоном и его модулями – как угодно: Ставить через yum, обновлять через pip, удалять/подменять либы – всё, что стыдно делать при приличных людях.
Теперь переходим если не к самомму главному, то ко второму по значимости пункту – установка модуля для общения с api telegram.

pip install --upgrade pip
pip install pytelegrambotapi

Первой командой мы обновим pip, второй – поставим необходимый модуль. Проверяем всё ли мы сделали правильно:

python
Python 3.4.5 (default, May 29 2017, 15:17:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import pytelegrambotapi
>>>

Если нет ошибок – вы настоящий программист! (нет) Так бы вам сказали на каком-нить курсе geekbrains, лишь бы платили бабло…
Выходим из интерпретатора python нажатием сочетания клавиш Ctrl+D и создаём сам скрипт (любым текстовым редактором, у меня это nano (yum install nano))

mkdir body && nano body/bot.py

Записываем туда код простейшего эхо-бота

#!/usr/bin/python3

import os
import telebot
import logging

TOKEN = os.environ['TELETOKEN']

bot = telebot.TeleBot(TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)

@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
    bot.reply_to(message, """\
    Hi there, I am EchoBot.\
    I am here to echo your kind words back to you.\
    Just say anything nice and I'll say the exact same thing to you!\
    """)

@bot.message_handler(content_types=["text"])
def repeat_all_messages(message):
    bot.send_message(message.chat.id, message.text)

bot.polling(none_stop=True)

Внимательный мамкин программист наверное скажет “Ха! Автомеханик лошара, а токен бота-то просрал! Фу таким быть!” и отчасти будет прав… пока что строку TOKEN = os.environ['TELETOKEN'] замените на TOKEN = 'ТУТ_ТОКЕН_БОТА_КОТОРЫЙ_ДАЛ_БАТЯ', а зачем у меня в примере сделано именно так – узнаете позже.
Теперь можно проверить работу скрипта запустив его:

python3 body/bot.py

Ответ должен быть примерно таким

2017-11-04 15:52:47,905 (__init__.py:269 MainThread) INFO - TeleBot: "Started polling."
2017-11-04 15:52:47,906 (util.py:55 PollingThread) DEBUG - TeleBot: "Received task"
2017-11-04 15:52:47,906 (apihelper.py:45 PollingThread) DEBUG - TeleBot: "Request: method=get url=https://api.telegram.org/bot0123456789:AAAAA-hsnheHG3nBSbv2MM23bsallOpwkes/getUpdates params={'offset': 1, 'timeout': 20} files=None"
2017-11-04 15:53:08,321 (apihelper.py:55 PollingThread) DEBUG - TeleBot: "The server returned: 'b'{"ok":true,"result":[]}''"
2017-11-04 15:53:08,322 (__init__.py:195 PollingThread) DEBUG - TeleBot: "Received 0 new updates"

Если всё так – можете в телеграме, от своего аккаунта, написать ему что-нибудь и он будет вам отвечать на команды /start и /help текстом, что записали в скрипте, а всё прочее просто будет копировать вам в ответ.
Собсно, на этом можно было бы и закончить, но тема сисек systemd не раскрыта.

Зачем нам это?

Можно было бы конечно создать виртуальное окружение у себя в хомяке и запускать это вручную, но-о-о-о я не из этих. Давайте попробуем написать unit-файл для systemd и делегировать ему запуск, поддержку “на лету” и завершение бота, в общем, отдадим ему управление.
Для начала поправим скрипт бота заменив TOKEN = 'ТУТ_ТОКЕН_БОТА_КОТОРЫЙ_ДАЛ_БАТЯ' на то что там было изначально TOKEN = os.environ['TELETOKEN'] , затем нам понадобится написать один файл /etc/systemd/system/venv-telebot.service . В директории /etc/systemd/system/ следует размещать самописные юниты; в /usr/lib/systemd/system/ обычно располагаются юниты распакованные из RPM-пакетов при установке, и в /run/systemd/system/ работающие в риалтайме. Называть его можно как угодно, но оканчиваться название должно на .service – так мы дадим системе понять что это юнит, а не насрано. Помещаем туда содержимое:

[Unit]
Description=Telegram bot written on python 3.4 and executed at python virtual env
After=syslog.target network.target

[Service]
Type=simple
User=nobody
Group=nobody
WorkingDirectory=/usr/local/sbin/venvs/telebot
ExecStart=/usr/local/sbin/venvs/telebot/bin/python3 body/bot.py
Restart=on-abort

Environment=VIRTUAL_ENV=/usr/local/sbin/venvs/telebot
Environment=TELETOKEN=AAAAA-hsnheHG3nBSbv2MM23bsallOpwkes
Environment=PATH=$VIRTUAL_ENV/bin:$PATH

[Install]
WantedBy=multi-user.target

Где

  • Description – Просто описание сервиса.
  • After – указание на то, после каких служб надо запускать сервис.
  • Type – Тип, где simple по-умолчанию предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не следует использовать этот тип, если другие службы зависят от очередности при запуске данной службы.
  • User и Group – юзер/группа от имени которых будет запущен сервис. Безопасность и все дела 🙂
  • WorkingDirectory – текущий каталог становится таковым при запуске сервиса.
  • ExecStart – команда запускающая сервис.
  • Restart – Рестартуем при неправильном завершении сервиса.
  • Environment – некие настройки окружения передаваемые при старте. Именно сюда мы помещаем токен нашего бота. Опять же для безопасности. Благодаря такому подходу, писав 100500 часов подряд своего супер-пупер бота, с квадратными, красными глазами, вы можете свободно пушить скрипт в гит, будучи уверенным, что там нет токенов, паролей и т.п.
  • WantedBy – уроверь запуска, в котором multi-user.target соответствует привычному runlevel=3

Финальным штрихом нашего кулинарно-админского безумия будет

systemctl enable venv-telebot.service

для “автозагрузки” нашего бота и запуск последнего командой

systemctl start venv-telebot.service

Ну вот, собсно, и всё. Больше рабочих примеров из коробки есть в репе модуля. С вами был я – автомеханик-социопат и мой робот служивший примером @Alpha_the_bot. До новых встреч! ^_^

2

Leave a Reply

Your email address will not be published. Required fields are marked *