Бот Telegram

Материал из ALT Linux Wiki

Многие ищут способы отправлять оповещения о событиях на инфраструктуре в свои телеграм-группы/чаты — изучают перл с питоном (дело хорошее, но необязательное) да роются по гит-барахолкам в поисках телегоботов, написанных другими.

А меж тем всё довольно просто.

Получение бота

Cгенерим нового телегобота в генераторе (внезапно!) телегоботов, для чего следует:

  1. Отправить боту-праотцу @BotFather молитву /newbot.
  2. Ввести название бота — в этой категории особых ограничений нет.
  3. Задать техническое имя бота, которое будет отображаться в адресной строке. К нему есть требования — оно должно:
    • быть уникальным,
    • написано латиницей,
    • оканчиваться на bot (так Телега защищается от злыдней, выдающих ботов за людей... замуж).

По завершению сего действа праотец пришлет токен-жетон нового бота в виде:

<10-циферный ИД бота>:ХХХ-<31-цифробуквенный жетон>

Каковой в дальнейшем и задействуем.

Внимание! Токен бота (тот, что после двоеточия) храним пуще зеницы ока, поскольку всяк, кому оный вéдом, может невозбранно слать непотребства от добавленного в чат имени того!

Группы-чаты-каналы

Добавив свежеиспечённого бота в скопления людей, куда хочется слать всякое, следует получить ИДы этих групп ( https://t.me/<ВОТ ЭТА ЧАСТЬ>/). Что легко достижимо копированием ссылки на любое сообщение в нужной группе. Например:

Сообщение из темы про Альт в публичном чате

https://t.me/linuxforum_ru/685/ZZZZ

Здесь:

  • linuxforum_ru — ИД группы/чата
  • 685 — (необязательный) ИД темы,
  • ZZZZ — (ненужный) ИД сообщения.

Или в какой-нибудь частной группе

https://t.me/XXXXXXXXXX/YYYY/ZZZZ
  • -100+XXXXXXXXXX — ИД группы/чата (-100XXXXXXXXXX),
  • YYYY — ИД темы.

Отправка

Внесём в баш-скрипт команду (удобнее оформить как функцию — см. в примере ниже), которая при наступлении отслеживаемого события будет слать соответствующий текст по жетону бота и ИДу канала (и темы, если надо) (на куски разбито для удобочитаемости, можно одной строкой):

$ curl -s https://api.telegram.org/bot<Токен>/send<Функция> \
       -F "text=Нужное сообщение." \
       -F "document=@/путь/к/файлу" \
       -F "chat_id=-100ХХХХХХХХХХ" \
       -F "reply_to_message_id=YYYY"

Где <Функция>:

  • либо Message — и пользуем поле "text=...",
  • либо Document — пользуем поле "document=@...".

Адрес, опции (-s, например) и поля -F "..." можно размещать в любом порядке и в одну строку.

Примеры

Сообщение

Распаковка дампа БД для проверки  
#!/bin/bash

WD=/mnt/dumps.psql/daily                           # Ежедневные дампы на СХД.
DUMP=`ls -1 $WD/$1*|tail -2|head -1|sed 's|.*/||'` # Проверять предпоследнюю ежедневку.
DATE=${DUMP%,*}                                    # Дампы имеют вид 'база,гггг-мм-дд,чч-мм-сс.тип'
TEST=check_${DUMP%%,*}                             # Имя базы для проверки бэкапа.

case ${DUMP##*.} in
    lzo) UNPAK="lzop -dcf";;
    zst) UNPAK="zstdcat"  ;;
    sql) UNPAK="cat"      ;;
esac

Notify(){ # Функция отправки оповещений с предварительно сформированным текстом.
    Token="10_цифр:???-31_цифробуква"             # Токен/жетон созданного для этого бота.
    URL="https://api.telegram.org/bot$Token/send" # API телеги с ИДом бота.
    ChatID="-13_цифр"                             # ИД чатика, куда слать оповещения.
    Topic="<ИД темы>"                             # Например, в тему "Дампы БД".
    curl -s ${URL}Message -F "text=$1" \
         -F "chat_id=$ChatID" -F "reply_to_message_id=$Topic" 2>&1 >/dev/null
}

Notify "(Пере)создаётся база $TEST."

[ `psql -U postgres -c "\l+ $TEST" | grep -c $TEST` -eq 0 ] || {
    for pid in `psql -U postgres -c 'SELECT datname, pid FROM pg_stat_activity' |
                awk '/'$TEST'/{print $3}'`; do
        psql -U postgres -c "SELECT pg_terminate_backend($pid);"
    done
    dropdb -U postgres $TEST
}
createdb -U postgres $TEST || {
    Notify "Пересоздать не удалось: база занята."
    exit
}

Notify "Распаковывается база $TEST от ${DATE#*,}."

$UNPAK $WD/$DUMP | psql -U postgres -d $TEST >/dev/null 2>&1
TIME=$(date +%T -ud @$[`date +%s`-START])          # Сколько длился весь процесс.

Notify "$TEST распакована за $TIME, можно проверять целостность."

Файл

Из скрипта по генерации конфигов ваергарда для сотрудников:
Только функция отправки  
Notify(){
    Token="см. примером выше"
    URL="см. там же"
    ChatID="-100"                               # Заголовок приватных чатов
    ChatID+="10_цифр"                           # Сам чат (группа ИТ-отдела)
    Topic=5                                     # Тема чата (VPN)
    PROXY="http://user:password@proxy.url:3128" # Необязательный пограничник
    curl -x "$PROXY" -s ${URL}Document -F document=@$CFG \
         -F chat_id=$ChatID -F reply_to_message_id=$Topic 2>&1 >/dev/null
}

SMART-оповещения

  1. В файле /etc/…/smartmontools (где «…» — default для деб-форков или sysconfig для рпм-дистров) раскомментировать либо добавить в опции ежеполучасовую проверку:
    smartd_opts="--interval=1800"
  2. Создать исполняемый файл /etc/smartmontools/run.d/10telegram:
    #!/bin/bash -e
    
    BOT="<ИД бота>:<жетон бота>"
    URL=https://api.telegram.org/bot$BOT/send
    ChatID="-100XXXXXXXXXX" # ИД или имя чатика
    Topic=<число>           # Тема для ловли уведомлений
    MSG=`cat $1`            # Сообщение от смарт-демона
    
    curl -s ${URL}Message -F text="$MSG" -F parse_mode=markdownv2 \
         -F chat_id=$ChatID -F reply_to_message_id=$Topic 2>&1 >/dev/null
    
  3. В файле /etc/smartd.conf добавить для проверки опцию -M test в директиву, подобную этой:
    DEVICESCAN -d removable -n standby -m root -M test -M exec /usr/share/smartmontools/smartd-runner
  4. Перезапустить службу (# systemctl restart smartd) и ловить в настроенном чатике проверочные сообщения.
  5. Если всё ОК, перезапустить службу без проверочной опции из пункта выше.

Готово.

Источники

S.M.A.R.T.

Обратная связь