![](https://habrastorage.org/webt/ex/rg/qc/exrgqcvsrvilgaxihlqtzyqsov4.jpeg)
Всем привет! Меня зовут Макарий, я DevOps-инженер в команде кросс-платформенной инфраструктуры корпоративного супераппа VK Teams. Сегодня я продолжу рассказ о том, как мы применяем практики ChatOps в наших рабочих процессах. Первую часть о самих практиках и мини-аппах для их реализации можно прочитать здесь.
Напомню, ChatOps — модель организации работы и коммуникации внутри команды через общение, то есть через мессенджер. Такой подход объединяет разработчиков, DevOps-инженеров, QA-специалистов, инженеров поддержки, продуктовых менеджеров, аналитиков и других участников процесса в единую коммуникационную платформу. Мы рассмотрим открытый кросс-платформенный фреймворк OpsDroid, его возможности, напишем коннектор между OpsDroid и VK Teams, а также реализуем бота. Уверен, этот опыт откроет для ваc новые возможности, которые предоставляет ChatOps.
ChatOps и корпоративные мессенджеры
В предыдущей части мы рассмотрели основные принципы построения ChatOps:
Также мы поговорили о том, как работает автоматизация процессов с использованием корпоративного мессенджера:
Здесь нам на помощь приходит VK Teams — корпоративный суперапп от VK, который объединяет в себе мессенджер для общения с коллегами, ботов для автоматизации, свой таск-трекер, видеоконференции на 100 пользователей и платформу мини-приложений.
Успешная реализация ChatOps требует не только выбора подходящих инструментов, но и создания культуры, при которой команды готовы активно использовать и вкладываться в принципы ChatOps.
Open-Source-фреймворк OpsDroid
OpsDroid — это кросс-платформенный фреймворк для разработки ChatOps-решений. Его основная идея заключается в создании единого центра управления ботом, который может работать одновременно на нескольких платформах, таких как Slack, MS Teams, Webex Teams, Facebook Messenger, Telegram, Matrix, Discord и других. Это позволяет командам использовать существующую инфраструктуру мессенджеров для управления операциями и взаимодействия с OpsDroid.
Взаимодействие между OpsDroid и платформой мессенджера осуществляется через коннекторы. Они представляют собой абстракцию над API и протоколами, используемыми различными мессенджерами и сервисами уведомлений. Коннекторы обеспечивают унифицированный интерфейс для взаимодействия с платформами и позволяют:
- принимать и отправлять сообщения,
- управлять каналами и пользователями,
- получать уведомления о событиях и реагировать.
Например, для связи OpsDroid и VK Teams потребуется соответствующий коннектор, который свяжет Bot API VK Teams с функциональностью OpsDroid.
OpsDroid также предоставляет удобный интерфейс для создания ботов: в виде навыков (skills) — то есть модулей, которые обрабатывают входящие события (events), анализируют их, взаимодействуют с внешними сервисами, возвращают результат для обработки.
Установить OpsDroid можно удобным для вас способом на личный компьютер или сервер. Для запуска бота необходимо настроить OpsDroid в соответствии с инструкциями:
Linux, MacOS — используйте Docker (руководство). Вы также можете установить OpsDroid без использования Docker, просто с помощью:
pip3 install opsdroid[common]
Коннектор OpsDroid-VK Teams
Для связи VK Teams и OpsDroid можно написать простой коннектор.
import aiohttp import asyncio from opsdroid.connector import Connector from opsdroid.events import Message class ConnectorVKTeams(Connector): """A connector for VK Teams""" def __init__(self, config, opsdroid=None): # Инициализация коннектора super().__init__(config, opsdroid=opsdroid) self.name = "vkteams" self.opsdroid = opsdroid self.latest_update = None self.listening = True self.default_target = self.default_user self.session = None self._closing = asyncio.Event() self.loop = asyncio.get_event_loop() self.base_url = config.get("base-url", None) self.default_user = config.get("default-user", None) self.whitelisted_users = config.get("whitelisted-users", None) self.update_interval = config.get("update-interval", 1) # без токена бот работать не сможет self.token = config["token"] async def _get_messages(self): # Получение сообщений из ивентов. Ивенты получаем: events/get из Bot API data = { 'token': self.token, 'pollTime': 30, 'lastEventId': 1 } if self.latest_update is not None: data["lastEventId"] = self.latest_update await asyncio.sleep(self.update_interval) resp = await self.session.get(self.build_url("events/get"), params=data) if 200 == resp.status: json = await resp.json() await self._parse_message(json) async def _parse_message(self, response): # Отдаем сообщения, которые нашли в json-е ивента for event in response["events"]: user = self.get_user(event) target = self.get_target(event) parsed_event = await self.handle_messages( user=user, target=target, event_id=event.get("eventId"), raw_event=event ) if parsed_event: if self.handle_user_permission(event, user): await self.opsdroid.parse(parsed_event) else: block_message = Message( text="У вас нет доступа к взаимодействию с ботом", user=user, user_id=user, target=target, connector=self ) await self.send(block_message) self.latest_update = event["eventId"] elif "eventId" in event: # игнорируем self.latest_update = event["eventId"]
Также в коннекторе необходимо реализовать методы для отправки сообщений, согласуя с Bot API.
import aiohttp from opsdroid.connector import register_event from opsdroid.events import Message, File ... @register_event(Message) async def send_message(self, message): data = dict() data["token"] = self.token data["chatId"] = message.target data["text"] = message.text resp = await self.session.post(self.build_url("messages/sendText"), data=data) @register_event(File) async def send_file(self, file_event): data = aiohttp.FormData() data.add_field( "token", str(self.token)) data.add_field( "chatId", str(file_event.target), content_type="multipart/form-data") data.add_field( "file", await file_event.get_file_bytes(), content_type="multipart/form-data") async with aiohttp.ClientSession() as session: resp = await session.post(self.build_url("messages/sendFile"), data=data)
Подробнее пример коннектора смотрите в репозитории. Коннектор позволяет OpsDroid понимать, когда приходит новое сообщение в VK Teams, и получать его содержимое, а также самому отправлять сообщения. Коннектор можно дополнительно расширить. Например, добавить поддержку всех возможных ивентов от OpsDroid:
from opsdroid.events import JoinGroup ... if raw_event.get("type") == "newChatMembers": return JoinGroup( user=f"@[{user}]", user_id=user, event_id=event_id, target=target, connector=self, raw_event=raw_event, )
Или реализовать поддержку всех типов событий, которые доступны на платформе (для VK Teams см. /events/get).
from opsdroid.events import Message from . import vkt_events ... if raw_event['payload']['parts'][0].get("type") == "forward": return vkt_events.Forward( user=f"@[{user}]", user_id=user, event_id=event_id, target=target, message=Message( text=raw_event['payload']['text'], user=f"@[{first_part['payload']['message']['from']['userId']}]", user_id=first_part['payload']['message']['from']['userId'], connector=self, raw_event=first_part, ), connector=self, raw_event=raw_event )
Расширение коннектора увеличивает возможности навыков, которыми будут обладать ваши боты. В нашем случае добавим поддержку следующих ивентов: Reply, Forward, File, Voice, Sticker, Mention для нового сообщения, а также Edited Message, Deleted Message, Pinned/Unpinned Message, Join/Left chat для других событий в чате.
Еще OpsDroid предоставляет широкие возможности для тестирования. Принято полностью покрывать новый коннектор тестами.
Пример бота с OpsDroid
Давайте реализуем такого же бота, который отправляет на указанный имейл сообщение, если на него был дан ответ с ключевым словом «send_email». Мы будем использовать OpsDroid для создания кросс-платформенного бота, который будет работать как в VK Teams, так и в Slack и, например, в Matrix. Код не претерпит значительных изменений, мы обернем его в OpsDroid. Действия, которые мы ранее выполняли с распаковкой payload вложенного сообщения, перенесены в код коннектора, разобранный выше, в парсинг ивента типа Reply. В данном случае нам останется лишь получить содержимое ивента, которое привязано к основному:
message.linked_event.text
Навык, который будет использоваться в нашем кросс-платформенном боте в файле configuration.yaml, выглядит следующим образом:
from opsdroid.skill import Skill from opsdroid.matchers import match_regex from opsdroid.constraints import constrain_connectors class SendEmailSkill(Skill): @match_regex(r'send_email', matching_condition="fullmatch") async def send_email(self, message): if not isinstance(message, Reply): await message.respond("Сделайте реплай на сообщение, " "которое хотите переслать на имейл") return message_for_email = f"{message.linked_event.user_id}:\n\n" \ f"{message.linked_event.text}\n\n" send_email(to=["your.real.email@mail.ru"], subject=f"Сообщение из {message.connector.name}(opsdroid)", text=message_for_email) await message.respond(f"Сообщение переслано на имейл") @match_regex(r'send_email', matching_condition="fullmatch") @constrain_connectors(['slack']) async def send_email_slack(self, message): slack = self.opsdroid.get_connector('slack') thread_timestamp = message.raw_event.get('thread_ts', None) replies = await slack.slack_web_client.conversations_replies( channel=message.target, ts=thread_timestamp ) messages = replies['messages'] thread_head = messages[0] users_info = await slack.slack_web_client.users_info(user=thread_head['user']) message_for_email += f"{users_info.get('user').get('real_name')}:" \ f"\n\n{thread_start['text']}\n\n" send_email(to=["your.real.email@mail.ru"], subject=f"Сообщение из Slack (opsdroid)", text=remove_emoji(message_for_email)) await message.respond(f"Сообщение переслано на имейл")
Код этого навыка для Slack отличается, так как коннектор Slack не поддерживает тип ивента Reply. Здесь мы используем разбиение с помощью constrain_connectors, чтобы в случае, если бот принял ивент в Slack, он распарсил его одним способом, а если принял в VK Teams или в Matrix — то другим, более подходящим. Коды навыка для VK Teams и Matrix идентичны.
Подробнее пример навыка смотрите в репозитории. Для более глубокого погружения используйте полную документацию OpsDroid.
Затем нам необходимо организовать структуру проекта следующим образом:
.
├── Dockerfile*
├── configuration.yaml
└── skills
└── email_sender (имя кастомного скилла)
└── __init__.py
* Dockerfile — если вы запускаете OpsDroid с помощью docker.
Для этого выполним следующие команды:
cd /home/username/Projects mkdir -p my_opsdroid_project/skills/email_sender cd my_opsdroid_project vim __init__.py <- сюда положим код навыка
Соберем нашего кросс-платформенного бота:
logging: level: debug timestamp: true welcome-message: false # Web server web: host: '0.0.0.0' port: 8080 ## Parsers parsers: [] ## Connectors modules connectors: vkteams: token: "VKT_BOT_TOKEN" # <- токен, который получили у Метабота bot-name: "email_sender_bot" # <- имя бота, которое задали Метаботу при создании base-url: "api.my-company.myteam.mail.ru/bot/v1/" # <- base-url бот-апи repo: https://github.com/mboriskin/connector-vkteams # <- код коннектора # как настроить slack - https://docs.opsdroid.dev/en/stable/connectors/slack.html slack: bot-token: "SLACK_BOT_TOKEN" bot-name: "email_sender_bot" socket-mode: true app-token: "SLACK_APP_TOKEN" # как настроить matrix - https://docs.opsdroid.dev/en/stable/connectors/matrix.html matrix: mxid: "@bot_account_username:matrix.org" password: "bot_account_password" rooms: 'main': '#my-corporate-bots:matrix.org' nick: "Botty EmailSender" ## Skill modules skills: ## Hello (https://github.com/opsdroid/skill-hello) hello: {} # <- как пример, навык по умолчанию ## Отправить сообщение на имейл email_sender: path: /opt/opsdroid/skills/email_sender # <- там лежит навык (если через docker) no-cache: true app-name: my_opsdroid_vkt
Соберем бота:
opsdroid config -f configuration.yaml build
Запустим в работу:
opsdroid start
Для запуска через Docker стяните скрипт startup.sh и Dockerfile из репозитория с примерами. Затем запустите скрипт для сборки бота:
IMAGE_NAME="my_opsdroid_vkt" ./startup.sh --build
Запустить скрипт можем как напрямую (для отладки и наблюдения за логами):
./startup.sh --run
Так и в фоне:
./startup.sh --runbg
И когда придет время, остановить бота:
./startup.sh --stop
Также можем удалить отработавший образ:
./startup.sh --remove
После запуска бота вы сможете написать ему личное сообщение или сообщение в групповом чате, куда он добавлен, и он выполнит нужную операцию, отправив сообщение на указанный имейл.
Например, в Slack:
В VK Teams:
И в Matrix:
OpsDroid представляет собой мощный кросс-платформенный фреймворк для разработки ChatOps-решений. Благодаря способности работать одновременно на нескольких платформах, таких как Slack, MS Teams, VK Teams и других, OpsDroid обеспечивает командам гибкость и удобство при управлении операциями и взаимодействии с ботами. Концепция коннекторов упрощает интеграцию с различными сервисами, обеспечивая единый интерфейс для взаимодействия. Навыки в OpsDroid позволяют разработчикам создавать функциональность ботов, обрабатывать события и взаимодействовать с внешними сервисами. Благодаря простой установке и настройке OpsDroid является эффективным инструментом для разработки кросс-платформенных ботов, способных оперативно выполнять задачи и обеспечивать эффективное взаимодействие с пользователями.
Готовые решения OpsDroid можно шарить между мессенджерами.
Можно найти множество уже готовых решений для OpsDroid и затем интегрировать их для использования в VK Teams или другом сервисе.
- skill-ssh — навык для взаимодействия с Linux-серверами с помощью SSH-команд;
- skill-devops — навык для взаимодействия с Docker и Gitlab;
- skill-sysanalytics — мониторинг системы при запущенном экземпляре OpsDroid;
- skill-nginx-rtmp — мониторинг запуска, остановки nginx-rtmp и состояния в целом;
- skill-github-linker — предоставление ссылок на GitHub Issues и PR при упоминании;
- skill-jenkins — навык для взаимодействия с Jenkins;
- skill-repohook — предоставление ссылок на события в Git{Hub|Lab};
- skill-docker-daemon — навык для управления Docker;
- skill-k8s — навык для работы с Kubernetes;
- skill-shell — навык для запуска shell-скриптов;
- skill-yourextip — получение своего внешнего IP-адреса в чате;
- skill taginfo — навык для получения данных из OpenStreetMap;
- skill-awx — навык для взаимодействия с AWX;
- skill-grafana-annotation — навык для создания и просмотра аннотаций Grafana;
- skill-prometheus-scrape — навык для сбора метрик через Prometheus прямо из чата;
- skill-github — навык для взаимодействия с GitHub;
- skill-cloudhealth — навык для взаимодействия с CloudHealth;
- skill-reminders — для установки напоминаний;
- skill-minecraft — навык для отслеживания и публикации логов сервера Minecraft;
- skill-google-it — для ответа ссылкой на поиск в Google;
- skill-iss — навык для определения местоположения МКС;
- skill-formula1-schedule — обработка календаря «Формулы-1» и отправка напоминаний;
- skill-random — навык для примера: отображение случайных событий;
- skill-words — навык, использующий модуль NLTK для игры в слова;
- skill-word-of-the-day — прислать слово дня из Оксфордского словаря английского языка.
Заключение
ChatOps представляет собой модель организации работы и коммуникации внутри команды через мессенджеры, объединяя различные роли и функции в единую коммуникационную платформу.
VK Teams как корпоративный суперапп предоставляет широкий набор инструментов для общения, автоматизации, управления задачами и видеоконференций. Успешная реализация ChatOps требует создания соответствующей культуры в команде, готовности использовать инструменты и принципы ChatOps.
OpsDroid является кросс-платформенным фреймворком для разработки ChatOps-решений. Он позволяет создать единую централизованную систему управления ботом, который может работать на различных платформах, таких как Slack, MS Teams, VK Teams, Matrix и других. Взаимодействие с мессенджерами осуществляется через коннекторы, которые предоставляют унифицированный интерфейс для обмена сообщениями, управления пользователями и получения уведомлений о событиях.
В качестве примера использования OpsDroid был рассмотрен простой бот, способный отправлять сообщения на указанный имейл при получении определенного ключевого слова. Благодаря гибкости OpsDroid и его возможности работать на различных платформах такой бот может быть использован как в VK Teams, так и в других мессенджерах, например Slack или Matrix.
Мы отметили возможность использования готовых решений OpsDroid, которые могут быть адаптированы и интегрированы для использования в VK Teams или других мессенджерах. Это позволяет разработчикам использовать уже существующие возможности и навыки для управления операциями и взаимодействия с ботами.
В целом благодаря OpsDroid и интеграции с VK Teams команды могут создавать эффективные и гибкие ChatOps-решения, улучшая коммуникацию, автоматизируя рутинные задачи.
ссылка на оригинал статьи https://habr.com/ru/articles/750208/
Добавить комментарий