Телеграмм-бот для системного администратора
В статье содержатся примеры нескольких ботов и примеры работы с апи телеграмм из 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)
Если кто знает, как закачать файл обратно — скиньте, я дополню.
Комментарии (16)
21 декабря 2016 в 23:26
0↑
↓
«Написать удаленное управление и мониторинг за сервером» — по-моему это первая мысль приходит сисадмину на вопрос: «Какого первого бота написать для Telegram?»21 декабря 2016 в 23:29
+3↑
↓
Почему код в архиве и вконтактике, если есть гитхаб (или даже gist)?22 декабря 2016 в 01:02
+2↑
↓
По той же причине, что бот для телеграма, когда есть терминал.22 декабря 2016 в 01:31
0↑
↓
Не скажите, терминал есть не везде, а телеграм везде.22 декабря 2016 в 02:28
+1↑
↓
А интернет из воздуха можно вырабатывать22 декабря 2016 в 08:32
0↑
↓
вырубать компы при проверке можно, прикрутить функцию из за которой тебя дергают на объект по ночам или с гостей. Репорты о состояниях и какихто авариях можно прикрутить
22 декабря 2016 в 08:28
0↑
↓
Ну терминал это же сложно, нужно руками команды вбивать. Используя бота, это все можно отмести, и одним пальцем пытаться угадать, как поведет себя система в той или иной ситуации. И именно по этому в этом вопросе я выбиру консоль, а вот иметь справочник по нужной тебе теме в телеграме я был бы рад. Посмотреть состояние «умного дома», это очень удобно! Но компенсировать консоль сервера, нет я не выберу телеграмме! Хотя заиметь полноценное ssh, в окне чата бота тоже был рад.
22 декабря 2016 в 08:31
0↑
↓
, а он может это делать, нужно только в скрипте кредиталы указать, он отправляет присланую команды по ssh, ждет 1 секунду, забирает ответ и отправляет обратно. Если ssh сессию установит не удается то и в режим не войдет
22 декабря 2016 в 08:31
0↑
↓
потому что я еще не освоил гитхаб)22 декабря 2016 в 11:51
+1↑
↓
Это не страшно. Если вам нужно просто сделать так, чтоб остальным было удобно, то просто создаёте репозитарий из веб интерфейса и создаёте/загружаете файлы ручками.
Следующий этап, это официальный клиент (есть под windows) с GUI. Там все очень просто. Достаточно один раз где то прочитать что вообще такое система контроля версий, и знать базовые вещи (комит, бранч и пр.).
Потом и глазом не успеете моргнуть, как начнёте использовать систему контроля версий даже для своих локальный поделок.
22 декабря 2016 в 02:53
0↑
↓
Расскажите, пожалуйста, как через этот [вырезано] Powershell загрузить в Telegram изображение? (Bot API). С текстом проблем нет, но изображение — никак не получается, в гугле ответ не находится тоже.22 декабря 2016 в 09:51
0↑
↓
это можно сделать из пхп вот таким образом:$url = $apiURL. "sendPhoto?chat_id=" . $chatID"; $post_fields = array('chat_id' => $chatID, 'caption' => 'Подпись под картинкой', 'photo' => new CURLFile(realpath('/img/1.png')) ); $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type:multipart/form-data" )); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); $output = curl_exec($ch);
на c# есть примеры, но как это выглядит именно на пошике запихать файл в структуру которая передается через post?
вообще удобная тема, есть пользователи которые на выезде и им нужно забрасывать быстро фотографии на терминал, раньше это вообще никак не реализовывалось, а тут красота — записал сотку в бота, поставил телеграмм, объяснил пользователю что у него будет отжираться интернет и он убежал в поля.
Или аварийное отключение, или репорт о состоянии служб на терминалах которые никогда не отключаются.Но это лишь промежуточная идея, это только транспорт для более сложной системы которая остлеживание состояние серверов и делает автоматически мелкие ремонты, нужен интерфейс взаимодействия через который бот анализирующий состояние разных систем мог оповещать админа и спрашивать подтверждение действий которые он собирается произвести
Для полноценной работы нужно чтобы он умел скриншоты обратно загружать, надеюсь что ктонибудь из конструктивных подключится и скажет как делать хотя бы
22 декабря 2016 в 12:16 (комментарий был изменён)
0↑
↓
Большое спасибо, но вопрос был именно про Powershell (который у Вас в статье), и ответ про PHP, увы, не отвечает на него.
У Вас статья про работу с Bot API в Powershell, Вы можете ответить на вопрос: «Как через Powershell отправить локальное изображение с помощью Bot API»? (речь конкретно про метод sendPhoto)
22 декабря 2016 в 09:51
0↑
↓
, а у меня одного ssh так сказать весит бота? То есть сессию он отрыл все хорошо, но не принимает команды и в консольке просто цикл обработки., а то я что то не силен в ps22 декабря 2016 в 09:56
0↑
↓
вы установили модуль posh-ssh?
если нет то скачать можно так:iex (New-Object Net.WebClient).DownloadString("https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev")
проверьте работает ли на той машине с которой запускаете бота
как проверить работает ли описывается тут: https://habrahabr.ru/post/314990/
22 декабря 2016 в 12:10 (комментарий был изменён)
0↑
↓
да модуль я установил, параметры верны и соединение устанавливается. проблема в том что после этого все что пишешь боту до него не доходит. Выключить его получается только вырубив самого бота руками и при следующем включении он получает все те сообщения что были отправлены после удачного соединения. И именно в эту магию я что то не могу разуметь. В логе кстати последняя запись так о успешном соединении и дальше тишина