Бот Telegram: различия между версиями

Материал из ALT Linux Wiki
 
(не показано 46 промежуточных версий этого же участника)
Строка 3: Строка 3:
А меж тем всё довольно просто.
А меж тем всё довольно просто.
=Получение бота=
=Получение бота=
Cгенерим нового телегобота в... генераторе телегоботов, для чего следует:
Cгенерим нового телегобота в генераторе (внезапно!) телегоботов, для чего следует:
#Отправить боту-праотцу [https://t.me/BotFather @BotFather] молитву '''<code>/newbot</code>'''.
#Отправить боту-праотцу [https://t.me/BotFather @BotFather] молитву '''<code>/newbot</code>'''.
#Ввести название бота — в этой категории особых ограничений нет.
#Ввести название бота — в этой категории особых ограничений нет.
Строка 9: Строка 9:
#*быть уникальным,
#*быть уникальным,
#*написано латиницей,
#*написано латиницей,
#*оканчиваться на '''bot''' ''(так Телега защищается от злыдней, выдающих ботов за людей)''.
#*оканчиваться на '''bot''' ''(так Телега защищается от злыдней, выдающих ботов за людей... замуж)''.
По завершению сего действа праотец пришлет токен-жетон нового бота в виде: <pre><10-числовой ИД бота>:ХХХ-<31-цифробуквенный жетон></pre>Каковой в дальнейшем и задействуем.
По завершению сего действа праотец пришлет токен-жетон нового бота в виде: <pre><10-циферный ИД бота>:ХХХ-<31-цифробуквенный жетон></pre>Каковой в дальнейшем и задействуем.
{{Внимание|Токен бота (тот, что после двоеточия) храним пуще зеницы ока, поскольку всяк, кому оный вéдом, может невозбранно слать непотребства от имени того!}}
{{Внимание|Токен бота (тот, что после двоеточия) храним пуще зеницы ока, поскольку всяк, кому оный вéдом, может невозбранно слать непотребства от добавленного в чат имени того!}}


=Группы-чаты-каналы=
=Группы-чаты-каналы=
Добавив свежеиспечённого бота в скопления людей, куда нужно слать мессаги, нужно получить ИДы этих групп, имеющие вид 13-значного числа с предваряющим его дефисом. Существует [https://it-stories.ru/get-chat-id-telegram/ сервис] по определению ИДа — однако:
Добавив свежеиспечённого бота в скопления людей, куда хочется слать мессаги, следует получить ИДы этих групп ( {{path|https://t.me/<ВОТ ЭТА ЧАСТЬ>/}}). Что легко достижимо копированием ссылки на любое сообщение в нужной группе.
*не проверял, умеет ли он в приватные чатики,
*и неизвестно, как долго он будет доступен.


Так что лучше оставлю здесь на будущее уже проверенные методы.
Например:
==Публичные==
==Сообщение из темы про Альт в публичном чате==
Тут всё просто — с помощью нашего жетона-токена запросим их либо через браузер, либо командой вида:
<pre>https://t.me/linuxforum_ru/685/ZZZZ</pre>
<pre>curl https://api.telegram.org/bot<бот:жетон>/getChat?chat_id=@ИмяГруппы</pre>
Здесь:
На что будет выводиться ответ, одним из первых полей в котором и станет искомый ИД.
*linuxforum_ru — ИД группы/чата
==Частные==
*685 — (не обязательный) ИД темы,
Здесь посложнее — понадобится:
*ZZZZ — (ненужный) ИД сообщения.
*добавить в чатик бота [https://t.me/olegonbot @olegonbot] по имени Акакий Акваланг и
==Или в какой-нибудь частной группе==
*задать в этом чатике безадресный вопрос «'''<code>Акваланг?</code>'''»
<pre>https://t.me/XXXXXXXXXX/YYYY/ZZZZ</pre>
На что он через несколько секунд выдаст ответ, первым же полем которого и будет потребный ИД.
*-100+XXXXXXXXXX — ИД группы/чата ('''-100XXXXXXXXXX'''),
*YYYY — ИД темы.


После чего бота лучше удалить во обеспечение дальнейшей приватности.
=Отправка сообщений=
Внесём в баш-скрипт команду ''(удобнее оформить как функцию — см. в примере ниже)'', которая при наступлении отслеживаемого события будет слать соответствующий текст по жетону бота и ИДу канала (и темы, если надо) ''(на куски разбито для удобочитаемости, можно одной строкой)'':
<pre>
$ curl -s https://api.telegram.org/bot<Токен>/send<Функция> \
      -F "text=Нужное сообщение." \
      -F "document=@/путь/к/файлу" \
      -F "chat_id=-100ХХХХХХХХХХ" \
      -F "reply_to_message_id=YYYY"
</pre>
Где '''Функция''':
*либо <code>Message</code> — тогда поле <code>"text=..."</code>,
*либо <code>Document</code> — тогда поле <code>"document=@..."</code>.
Адрес, опции (<code>-s</code>, например) и поля <code>-F "..."</code> можно размещать в любом порядке и в одну строку.


Наверняка есть способ получать ИД таких чатиков посредством тележного API (Акакий ведь это как-то делает), однако разбираться с этим сейчас некогда, а вышеприведённый вариант работает надёжно.
{|class="mw-collapsible mw-collapsed wikitable"
!Пример распаковки дампа базы для проверки &nbsp;
|-
|<source lang=bash>
#!/bin/bash


=Отправка сообщений=
Token="10_цифр:???-31_цифробуква"                  # Токен/жетон созданного для этого бота.
Внесём в баш-скрипт команду ''(удобнее оформить как функцию — см. в [[Бот_Telegram#Пример_скрипта|примере ниже]])'', которая при наступлении отслеживаемого события будет слать соответствующий текст по жетону бота и ИДу канала ''(на куски разбито для удобочитаемости, можно одной строкой)'':
URL="https://api.telegram.org/bot$Token"          # API телеги с ИДом бота.
<pre>curl -s -X POST -H 'Content-Type: application/json' \
ChatID="-13_цифр"                                  # ИД чатика, куда слать оповещения.
    -d '{"chat_id": "ИД_чатика", "text": "текст сообщения", "disable_notification": true}' \
Topic="<ИД темы>"                                  # Например, в тему "Дампы БД".
    https://api.telegram.org/bot<токен бота>/sendMessage</pre>
=Пример скрипта=
У меня таким макаром распаковывается дамп базы для проверки его на целостность:
<source lang=bash>
#!/bin/bash


WD=/mnt/dumps.psql/daily                          # Ежедневные дампы на СХД.
WD=/mnt/dumps.psql/daily                          # Ежедневные дампы на СХД.
DUMP=`ls -1 $WD/$1*|tail -2|head -1|sed 's|.*/||'` # Проверять предпоследнюю ежедневку.
DUMP=`ls -1 $WD/$1*|tail -2|head -1|sed 's|.*/||'` # Проверять предпоследнюю ежедневку.
DATE=`echo $DUMP | cut -d, -f2`
DATE=${DUMP%,*}                                    # Дампы имеют вид 'база,гггг-мм-дд,чч-мм-сс.тип'
ChatID="-13_цифр"                                  # ИД чатика, куда слать оповещения.
TEST=check_${DUMP%%,*}                             # Имя базы для проверки бэкапа.
BoTokn="10_цифр:???-31_цифробуква"                # Токен/жетон созданного для этого бота.
 
Notify(){ # Функция отправки оповещений, предварительно формирующая текст.
    curl -s -X POST -H 'Content-Type: application/json' \
        -d "{\"chat_id\": \"$ChatID\", \"text\": \"$1\", \"disable_notification\": true}" \
        https://api.telegram.org/bot$BoTokn/sendMessage 2>&1 >/dev/null
}


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


TESTDB=check_${DUMP%%,*}
Notify(){ # Функция отправки оповещений из предварительно сформированного текста.
    curl -F "chat_id=$ChatID" -F "reply_to_message_id=$Topic" \
        -F "text=$1" -s $URL/sendMessage 2>&1 >/dev/null
}


Notify "Распаковывается база $TESTDB от $DATE."
Notify "(Пере)создаётся база $TEST."


# [пере]создадим проверочную базу:
[ `psql -U postgres -c "\l+ $TEST" | grep -c $TEST` -eq 0 ] || {
[ `psql -U postgres -c "\l+" | grep -c $TESTDB` -lt 1 ] ||
     for pid in `psql -U postgres -c 'SELECT datname, pid FROM pg_stat_activity' |
     for DO in drop create; do
                awk '/'$TEST'/{print $3}'`; do
         ${DO}db -U postgres $TESTDB
         psql -U postgres -c "SELECT pg_terminate_backend($pid);"
     done
     done
# и распакуем в неё дамп:
    dropdb -U postgres $TEST
$UNPAK $WD/$DUMP | psql -U postgres -d $TESTDB >/dev/null 2>&1
}
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])          # Сколько длился весь процесс.
TIME=$(date +%T -ud @$[`date +%s`-START])          # Сколько длился весь процесс.


Notify "$TESTDB распакована за $TIME, можно проверять целостность."
Notify "$TEST распакована за $TIME, можно проверять целостность."
</source>
</source>
|}
=Обратная связь=
=Обратная связь=
*[https://t.me/gbIMoBou @gbIMoBou]
*[https://t.me/gbIMoBou @gbIMoBou]

Текущая версия от 15:25, 17 января 2024

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

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

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

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

Token="10_цифр:???-31_цифробуква"                  # Токен/жетон созданного для этого бота.
URL="https://api.telegram.org/bot$Token"           # API телеги с ИДом бота.
ChatID="-13_цифр"                                  # ИД чатика, куда слать оповещения.
Topic="<ИД темы>"                                  # Например, в тему "Дампы БД".

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(){ # Функция отправки оповещений из предварительно сформированного текста.
    curl -F "chat_id=$ChatID" -F "reply_to_message_id=$Topic" \
         -F "text=$1" -s $URL/sendMessage 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, можно проверять целостность."

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