PowerBot или не Микротиком единым…

Здравствуйте Друзья!

По роду деятельности приходится немного писать на PowerShell. В результате родился Телеграм бот и на этом языке.

Это шаблон или «рыба». Начинка уже зависит от вашей фантазии. Проектировался для больших нагрузок, реализована многопоточная обработка сообщений.

Но через -AsJob мы не пошли. Всё сделано на Runspaces.

Вот здесь сравниваются два этих подхода, Runspaces реально быстрее.

Ближе к делу. Давайте посмотрим как это работает, постараюсь коротко.

Скрипт Create-Runspace.ps1 создаёт четыре пространства исполнения. По одному для каждого обработчика:

psGetUpdate — получает сообщения
psMssageHandler — обрабатывает текстовые сообщения
psCallbackHandler — обрабатывает нажатия на кнопки
psInlineHandler — обрабатывает инлайн-запросы

Папка pbScriptBlocks содержит код с логикой каждого.

psGetUpdate получает обновления и кладёт их в потокобезопасные hashtable. Для каждого типа сообщений своя таблица. Через них потоки взаимодействуют друг с другом. Так же есть общие таблицы для отладки и логов.

#очередь сообщений типа Message 
$queueMessageHash = [hashtable]::Synchronized(@{})

#очередь сообщений типа Inline 
$queueInlineHash = [hashtable]::Synchronized(@{}) 

Поток psInlineHandler для каждого сообщения создает дочернее пространство исполнения. Максимальное количество определено в настройках в виде параметра inlineRunspacesMax.

Остальные обработчики дочерних потоков не создают, но можно сделать по аналогии.

Все настройки хранятся в BotSettings.json, для его создания есть скрипт BotSettings.ps1, там нужно прописать ваши данные и запустить.

Обработчики это бесконечные циклы, которые считывают из таблицы queueCommandsHash флаг остановки.

Такие флаги устанавливаются в конце скрипта Create-Runspace.ps1.

$queueCommandsHash['inlineNonStop']=$false

Поэтому поставьте точку останова на строке 143. Иначе бот запустит потоки и тут же их остановит.

Функция Get-Runspaces удаляет потоки из памяти. Её скомуниздил в интернете и немного адаптировал.

Логи обработчиков сохраняются в таблицу queueDebugHash, в конце выгружаются в одноименный файл json.

При старте, прилет такое сообщение

Главное окно

Главное окно

При нажатии на кнопки формы, в консоли увидите пример такую картину.

2a60d22f5fe6d04a722869ae7b412a97.png

Если нажать на Users, то в меню получим список пользователей. Работает поиск, набирайте имя на английском и он будет фильтровать результат.

В InlineHandler.ps1 это прописано в качестве примера и имеет комментарий.

# Пример использования — удалить

54141930ffa56bfdb9ebe4dfb1d126d4.png

Задумывался, как бот управления инфраструктурой. По структуре замысел должен быть примерно понятен.

Есть форма для DNS, можно вызвать руками.

7f4df6f468426111fd07365bbfdcf6cc.png

Шаблон получился вполне универсальным.

Можно еще сделать отдельный поток для отправки сообщений, но это уже сами, кому надо…

Код опубликован здесь. Всем добра!

© Habrahabr.ru