Отправляем сообщения через Telegram Bot API из Powershell

Powershell - это очень крутая штука в руках толкового Windows-сисадмина, которая умеет кучу всего. Сегодня я расскажу, как можно отправлять текстовые сообщения себе в Telegram через бота. Сразу о минусах: во-первых, у меня не получилось передавать какие-либо файлы, т.к. подставить в качестве аргумента "photo" в JSON-массиве содержимое файла в Powershell не представляется возможным, 2 часа гугления рабочего решения не дали. Во-вторых, в силу особенностей Powershell в русифицированных виндах кириллический текст отправляется в виде вопросительных знаков, а попытка в явном виде преобразовать текст в UTF-8 приводит к фейлу. В комментариях к этому уроки подсказали, как добавить поддержку юникода (в который входит и кириллица).

Для чего вообще тогда нужен этот скрипт? Ну, например, если на сервере планировщиком запускаются какие-либо бэкапы, то было бы удобно получать информацию о результатах в Telegram. Или, например, можно сообщать о неполадках на удаленной машине в канал, который читают несколько системных администраторов. В общем, кому надо будет, тот придумает назначение сам. Итак, поехали.

Прежде всего, давайте определимся с аргументами командной строки. Я сделал обязательными chat_id и text (согласно документации) и дополнительно сделал возможной поддержку Markdown и отсутствие генерации превью для ссылок:

param(
[string]$chat_id = $(Throw "'-chat_id' argument is mandatory"),
[string]$text = $(Throw "'-text' argument is mandatory"),
[switch]$markdown,
[switch]$nopreview
)

В случае, если не указан какой-либо из обязательных аргументов, скрипт выпадет с ошибкой, описанной в скобках. Переменная типа switch работает так: если соответствующий аргумент присутствует в вызове, то значение переменной устанавливается в $True, если нет - $False. Нас такой расклад не совсем устраивает, поэтому добавим парочку проверок:

if($nopreview) { $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;
}

И, наконец, осуществим http-запрос к API:

Invoke-WebRequest `
-Uri ("https://api.telegram.org/bot{0}/sendMessage" -f $token) `
-Method Post `
-ContentType "application/json;charset=utf-8" `
-Body (ConvertTo-Json -Compress -InputObject $payload)

Вот и всё! Весь код приведён в следующем листинге:

param(
[string]$chat_id = $(Throw "'-chat_id' argument is mandatory"),
[string]$text = $(Throw "'-text' argument is mandatory"),
[switch]$markdown,
[switch]$nopreview
)
$token = "ВАШ ТОКЕН"
if($nopreview) { $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;
}
Invoke-WebRequest `
-Uri ("https://api.telegram.org/bot{0}/sendMessage" -f $token) `
-Method Post `
-ContentType "application/json;charset=utf-8" `
-Body (ConvertTo-Json -Compress -InputObject $payload)