Телеграмм-бот для системных администраторов. Это ни в коем случае не готовый проект, в нем есть над чем поработать. Это полуфабрикат и набор приемов который каждый админ может подпиливать под свои разные задачи.
В статье содержатся примеры нескольких ботов и примеры работы с апи телеграмм из powershell.
Для быстрого добавления бота и чтобы было возможно быстро добавить его к себе лучше всего использовать специальную ссылку начинающуюся с символа @, взять его можно в инфо:
если такую ссылку комуто переслать то он может просто кликнуть по ней чтобы открыть чат с вашим ботом
Готовые шаблоны админботов
- небольшой — всего около 300 строк
- может исполнять команды описанные в функции logic
- может получать и отправлять сообщения
- может принимать файлы
- есть проверка по паролю
- ведет лог присланых команд
- может открывать несколько сессий для одновременной работы (реализовано не полностью. Но взаимодействовать несколько человек одновременно могут
Минусы:
- слишком простая авторизация. Пароль останется в чате на устройстве. Не может отличить устройства
скачать простого бота можно вот отсюда, в архиве содержится: 1. хелп с примерами разметки текста; 2. исходник
Для запуска нужно получить токен бота у BotFather как описывается в начале статьи и прописать в переменную $token скрипта. Работать должно сразу.
Функционал добавлять в функцию logic
- Небольшой — всего около 450 строк
- Может исполнять команды описанные в функции logic
- Может получать и отправлять сообщения
- Может принимать файлы
- Есть проверка по паролю, может дополнительно проверять chat_id
- Ведет лог присланых команд
- Может открывать несколько сессий для одновременной работы (реализовано не полностью. На последнем этапе прикручивалась консоль, если работать в ней то у других пользователей будет зависание и может быть кик по таймауту.
Функционал который был реализован для примера:
- Может принимать файлы, складывает их в папочку
- Может показывать файлы из папочки
- Может удалять файлы из папки загрузки
- Может запускать файл на исполнение (посредством start-process)
- Показывает список серверов с которым производится работа (просто список имен в текстовом файле)
- Пингует серверы из списка и показывает какие из них онлайн
- Отключает компы из списка
- Показывает пользователей залогинившихся на терминал, делает вызов внешнего скрипта (нужно установить на терминал PSTerminalServices)
- Делает logoff пользователя на терминале. Входишь в режим консоли и потом пишешь имена пользователей (нужно установить на терминал PSTerminalServices)
- Делает скриншот того компа на котором запущен (но не передает обратно)
- Открывает ssh-сессию с устройством в сети и переходит в режим ввода команд (для примера кредиталы и адрес жестко зашиты в скрипт. Для работы требует установки на машину с которой будет вестись управление модуля работы с ssh poshSSH)
Из того, что не было реализовано, но хотелось бы:
- Обратная передача файлов (напишите кто знает как это сделать через powershell)
- Неполноценная поддержка многопользовательской работы
- Неполноценный режим консоли
Скачать бота можно вот отсюда, в архиве содержится:
1. хелп с примерами разметки текста;
2. конфигурационный файл config.csv;
3. сам бот — abormot.ps1;
4. набор вспомогательный файлов;
5. список компов для работы в текстовом файле ping-list.txt
Для запуска нужно получить токен бота у BotFather как описывается в начале статьи и прописать в конфигурационном файле config.csv. Работать должно сразу.
Функционал добавлять в функцию logic
Скачать бота можно вот отсюда.
Для запуска нужно получить токен бота у BotFather прописать токен в переменную $token. Выставить номер чата админа в $adminChatID. Прописать адрес доменной машины и кредиталы к ней:
Я встроил в примере функцию unlock прямо в скрипт, для постоянного использования лучше создать реакцию на событие в журнале и самому генерировать это событие. По событию будет запускаться скрипт unlock из места которое доступно только админам, так вы не забудете пароль от домена в скрипте. Это важно.
Скачать бота можно вот отсюда.
Для запуска нужно получить токен бота у BotFather прописать токен в переменную $token. Работать должно сразу. Не забудьте добавить нужный вам чат в switch
Как работать с bot api
1. Принять сообщение
Нужно выполнить Invoke-WebRequest на адрес
https://api.telegram.org/bot{Токен}/getUpdates?offset={порядковый ID сообщения}&timeout={время ожидания перед возвратом в секундах}
{Токен} — токен бота полученный от BotFather
{порядковый ID сообщения} — для первого сообщения 0, для последующих номер последнего + 1. Если указывать последний номер то будете получать при каждом обращении последнее сообщение.
{время ожидания перед возвратом в секундах} — время которое телеграмм подождет ответа если его нет прежде чем вернуть обратно пустую структуру. Годится для создания задержки в боте. Я использовал в ботиках задержку в 1 секунду чтобы не ждать на отладке.
на выходе получим структуру JSON которую парсим при помощи ConvertFrom-Json
Листинг кода №1
$ChatTimeout = 1
$UpdateId = 0
$token = "bot token"
$URL = "https://api.telegram.org/bot$token/getUpdates?offset=$UpdateId&timeout=$ChatTimeout"
$Request = Invoke-WebRequest -Uri $URL -Method Get
$content = ConvertFrom-Json $Request.content
# если на выходе 2 и более результатов возьмем только последний
$str = $content.result | select -First 1
$str = ($str).message
$props = [ordered]@{
ok = $content.ok
UpdateId = ($str).update_id
Message_ID = $str.message_id
first_name = ($str.from).first_name
last_name = ($str.from).last_name
chat_id = ($str.chat).id
text = $str.text
}
$obj = New-Object -TypeName PSObject -Property $props
$obj
На выходе в объекте $obj будет сообщение и от кого оно пришло
2. Скачать файл
Если передается файл то в структуре JSON будут переданы дополнительные параметры. Чтобы получить файл нужно вытащить file_id из сообщения, затем обратится по адресу:
https://api.telegram.org/bot{token}/getFile?file_id={file_id из сообщения}
Запрос вернет структуру JSON содержащую путь для скачивания. Далее скачиваем файл по ссылке
https://api.telegram.org/file/bot{token}/{file_path}
Предположим что нам передали файл, тогда код для его скачивания будет выглядеть так:
$ChatTimeout = 1
$UpdateId = 0
$token = "bot token"
$Path = "c:"
##### Получаем сообщение как обычно
$URL = "https://api.telegram.org/bot$token/getUpdates?offset=$UpdateId&timeout=$ChatTimeout"
$Request = Invoke-WebRequest -Uri $URL -Method Get
$content = ConvertFrom-Json $Request.content
# если на выходе 2 и более результатов возьмем только последний
$str = $content.result | select -First 1
$str = ($str).message
##### Если в сообщение передается файл то будут дополнительные поля
# так например мы можем узнать что нам передали картинку
if ( $($str.document).mime_type -eq "image/jpeg" ) { $isJPG = $true }
##### Если есть file_name то значит там чтото лежит
# документ на скачивание есть?
if ( $($str.document).file_name -ne $null ) {
### разные данные например для логирования
$DocFileName = ($str.document).file_name
$DocFileID = ($str.document).file_id
$DocFileSize = ($str.document).file_size
# получаем сылку на файл исполняя команду бота /getFile
$URL = "https://api.telegram.org/bot$token/getFile?file_id=$DocFileID"
$RequestFile = Invoke-WebRequest -Uri $URL
### в $RequestFile если все верно содержится ссылка на скачивание
foreach ( $JSON in $((ConvertFrom-Json $RequestFile.Content).result) ) {
$FilePath = $json.file_path
$URL = "https://api.telegram.org/file/bot$token/$FilePath"
$FilePath = Split-Path -Leaf $FilePath
$OutputFile = "$Path$FilePath"
# качаем без проверки
Invoke-WebRequest -Uri $URL -OutFile $OutputFile
}
}
3. Написать что-нибудь
Телеграмм-бот поддерживает 2 режима разметки текста markdown и html.
Внимание: в html-режиме тэг br не поддерживается
_italic text_ — наклонный текст
[text](http://www.example.com/) — ссылка
`inline fixed-width code` — фиксированный
текстовый блок
```text
pre-formatted fixed-width code block
```
Для переноса строк используйте последовательность %0A
Пример отправки сообщения
$token = "ваш токен"
$сhatid = "ID чата в который нужно послать сообщение"
$text = "привет habr"
$payload = @{ "parse_mode" = "Markdown"; "disable_web_page_preview" = "True" }
$URL = "https://api.telegram.org/bot$token/sendMessage?chat_id=$сhatid&text=$text"
$request = Invoke-WebRequest -Uri $URL -Method Post `
-ContentType "application/json; charset=utf-8" `
-Body (ConvertTo-Json -Compress -InputObject $payload)
Если данный код даст ошибку например при отправке строки вот такого типа:
"$FDownload : file name is ""$($JSON.file_path)""; size $($json.file_size) kb"
Можно использовать метод отправки посложнее:
$token = "ваш токен"
$chat_id = "ID chata"
$text = "сообщение"
$markdown = $true
$preview_mode = "True"
if ($markdown) { $markdown_mode = "Markdown" } else {$markdown_mode = ""}
$payload = @{ "chat_id" = $chat_id;
"text" = $text
"parse_mode" = $markdown_mode;
"disable_web_page_preview" = $preview_mode;
}
$URL = "https://api.telegram.org/bot$token/sendMessaget"
$request = Invoke-WebRequest -Uri $URL `
-Method Post -ContentType "application/json; charset=utf-8" `
-Body (ConvertTo-Json -Compress -InputObject $payload)
Если кто знает, как закачать файл обратно — скиньте, я дополню.
Автор: pak-nikolai