Как упростить коммуникацию, «подружив» Telegram и Microsoft Teams
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.
Привет, меня зовут Денис Рыжих, я отвечаю за направление Future Workplace (современное рабочее место) в украинском представительстве компании SoftwareONE, где мы помогаем бизнесу повышать эффективность работы сотрудников (занимаемся внедрением, продажей и адаптацией технологий от ведущих производителей).
Статья о том, как организовать пересылку сообщений между Telegram и Microsoft Teams с помощью Power Automate. Уверен, она будет полезна для технических специалистов.
В своей работе я довольно часто сталкиваюсь с использованием разнообразных инструментов в бизнесе. Украинскому бизнесу свойственно выжимать из бесплатных технологий максимум и пытаться экономить. Иногда это оборачивается кошмаром для реализации задач безопасности или администрирования. Но оставим эти отчасти философское рассуждения для следующих материалов, а сегодня я хочу познакомить с решением, которое позволит подружить две очень популярные платформы из разных миров — мира домашних пользователей с мессенджером Telegram, у которого на момент написания статьи насчитывалось более 500 миллионов ежемесячно активных пользователей, и мира бизнеса и образования — Office 365 с платформой Microsoft Teams, которая насчитывает более чем 145 миллионов ежедневно активных пользователей. (Telegram FAQ, Microsoft Teams usage jumps to 145 million daily active users — The Verge.)
Чтобы продемонстрировать возможности программных интерфейсов двух платформ, в данном примере мы реализуем отправку и получение текста между ними. Сделаем это с помощью коннектора, который реализуем на Power Automate — часть платформы Office 365.
Power Automate — это Low-code/no-code решение, которое позволяет автоматизировать действия пользователя. Может работать в разных режимах и взаимодействовать с интерфейсом или с программными интерфейсами — API.
Для начала давайте определимся с задачей.
Дано:
- Команда и канал в Teams, где могут присутствовать различные сотрудники и приглашать своих коллег (чат 1).
- В Telegram создан групповой чат, где присутствуют подрядчики и задают вопросы либо могут ответить на вопросы (чат 2).
Цель — настроить двухсторонний обмен текстовыми сообщениями между сервисами. Чтобы сообщение, отправленное в чат Telegram, попадало в чат Teams, а сообщение из чата Teams попадало в Telegram.
Архитектура решения
Архитектура решения состоит в том, чтобы создать чат-бота Telegram и его обработку на Power Automate. Бот будет получать сообщения в чате, а возможно и в разных чатах Telegram, и пересылать их в каналы Teams. Соответственно, сообщения в Teams будут также пересылать в чаты Telegram.
Создание чат-бота для Telegram
Telegram предоставляет простую возможность регистрации бота. Для этого прямо в мессенджере мы должны обратиться к @BotFather — специальному боту для управления ботами.
Ищем его и начинаем диалог:
/start — для того, чтобы увидеть доступные команды:
Нам нужен новый бот:
/newbot
Давайте назовём его MessageExchangeBot. Для этого дадим ему такие имя и username:
А в ответ получим HTTP API токен для возможности отправки команд нашему боту. Сохраните его и подставляйте в дальнейших примерах вместо <token>.
Все команды мы будем отправлять боту через запросы вида:
https://api.telegram.org/bot/METHOD_NAME
И получать ответы в виде структурированной информации в формате JSON. Проверьте, проходит ли команда получения последних обновлений:
https://api.telegram.org/bot/getUpdates
Ответ должен получиться:
{"ok":true,"result«:[]}
Так как мы ещё никуда не подключали бота, то никаких новостей для нас нет — он просто сообщает о том, что работает.
Проверка и настройка Telegram-бота
Боты Telegram могут работать с групповым чатом или реагируя на сообщения, адресованные им (enable privacy mode), либо на все сообщения в чате (disable privacy mode). Так как нам нужно, чтобы боты реагировали на все сообщения, обратимся к @BotFather для отключения privacy-режима командой /setprivacy:
Нам необходимо указать имя бота, параметрами которого мы управляем: @MessageExchangeBot, и отметить, что мы хотим изменить настройку на Disable (отключить).
Теперь давайте познакомимся с механизмом получения новостей (обновлений, updates) от бота. Есть два варианта работы:
- Мы можем вручную запрашивать наличие новостей, постоянно выполняя веб-запрос с методом getUpdates. Такие запросы называют PULL (тянуть) подходом, когда мы в удобное для нас время запрашиваем информацию обо всём, что произошло между предыдущим запросом и текущим.
- Бот может при наступлении нового события сразу отправлять его нам через механизм Webhook. Для этого у нас должен быть развёрнут сервис, который ожидает получения такого сообщения и обрабатывает его. Такой подход называется PUSH (толкать), так как всю информацию бот сразу выталкивает в сторонний сервис.
В некоторых случаях, например, когда мы хотим проверять состояние бота раз в день или раз в час, нам может быть удобен подход PULL, но так как мы хотим построить максимально интерактивную систему, то нам больше подойдёт PUSH с работой через Webhook.
Перед тем как мы переключим бота в такой режим, необходимо настроить сервис, который будет принимать PUSH-сообщения. К счастью, Power Automate позволит организовать такую систему очень просто, без необходимости аренды и настройки отдельного веб-сервера.
Настройка Webhook на Power Automate
Итак, мы определились, что будем использовать интерактивный механизм обмена сообщениями с ботом.
Power Automate работает по принципу потоков (flow), когда серия действий выполняется друг за другом. А начинает свою работу по одному из следующих принципов:
- Автоматически (Automated flow). Обычно для такого способа используется преднастроенное действие — триггер. Таким триггером может быть, например, получение почты в Exchange online, сообщения в Teams или сохранения файла в OneDrive.
- Мгновенно (Instant flow). Обычно такие потоки запускаются вручную, по какому-то внешнему событию или вручную по необходимости.
- По расписанию (Scheduled flow). Такой подход удобно использовать, если нужно, чтобы поток отрабатывал каждый день или раз в какой-либо промежуток времени, например раз в час.
Наиболее подходящим в нашем случае будет Instant flow, так как мы будем реагировать на присланное сообщение от бота.
Среди предложенных триггеров выбираем When HTTP request is received:
И создаём поток — Create:
Теперь давайте раскроем триггер, нажав на нём:
Для того чтобы узнать URL, по которому мы будем принимать сообщения от бота, нам необходимо сначала сохранить поток. Для этого вместо Untitled слева вверху дайте имя потоку. Например, MessageExhcangeBotHook и добавьте один шаг (+ New Step) с обработчиком Parse JSON:
В поле Content можно выбрать динамический параметр с предыдущего триггера — Body (поступивший запрос состоит из трех элементов: заголовок (Header), тело (Body) и путь (Path)).
Схему запроса можно сгенерировать на основе примера, либо просто можете использовать уже описанную мной структуру:
{ "type": "object", "properties": { "update_id": { "type": "integer" }, "message": { "type": "object", "properties": { "message_id": { "type": "integer" }, "from": { "type": "object", "properties": { "id": { "type": "integer" }, "is_bot": { "type": "boolean" }, "first_name": { "type": "string" }, "last_name": { "type": "string" }, "language_code": { "type": "string" } } }, "chat": { "type": "object", "properties": { "id": { "type": "integer" }, "first_name": { "type": "string" }, "last_name": { "type": "string" }, "type": { "type": "string" } } }, "date": { "type": "integer" }, "text": { "type": "string" } } } } }
После чего нажмите Save (сохранить):
Если сохранение произошло успешно, то, открыв карточку триггера, мы увидим ссылку, по которой веб-сервис будет ожидать сообщений:
Скопируйте и сохраните его, далее в статье я буду называть эту ссылку <WebhookURL>.
Настройка режима работы бота
Теперь, когда у нас есть сервис, ожидающий сообщений от бота, мы сделаем соответствующие настройки бота.
Эта настройка выполняется через строку веб-браузера, но, прежде чем мы сможем выполнить такой запрос, нам необходимо преобразовать <WebhookURL> в безопасный для адресной строки формат. В этом нам поможет urlencoder.org.
Переходим на страницу сервиса, вставляем нашу ссылку <WebhookURL> в верхнее окно и нажимаем Encode:
Сохраните преобразованную ссылку. Далее в статье мы будем её называть <EncodedWebhookURL>.
Теперь составьте следующий запрос:
https://api.telegram.org/bot/setWebhook?url=
И выполните его в строке веб-браузера:
Теперь, когда у нас получилось установить Webhook, мы создадим групповой чат в Telegram и пригласим в него бота.
Тестирование отправки сообщения из чата Telegram в Power Automate
Начнём с того, что создадим новый групповой чат — Test message exchange:
Пригласим туда нашего бота:
И напишем тестовое сообщение в чат Test message:
Теперь перейдём в интерфейс Power Automate и посмотрим историю выполнения нашего потока MessageExchangeWebHook. Там нас будут ждать два сообщения:
Первым на Webhook пришло сообщение о создании группового чата и добавлении бота. Вторым пришло сообщение о получении сообщения в групповом чате. Мы можем открыть каждое из этих событий и посмотреть, что передавалось в каждом из них:
Листинг Body первого сообщения:
{ "update_id": 444291210, "message": { "message_id": 1, "from": { "id": 1436813460, "is_bot": false, "first_name": "W", "last_name": "W" }, "chat": { "id": -406916955, "title": "Test message exchange", "type": "group", "all_members_are_administrators": true }, "date": 1605914785, "group_chat_created": true } }
Листинг второго сообщения:
{ "update_id": 444291211, "message": { "message_id": 2, "from": { "id": 1436813460, "is_bot": false, "first_name": "W", "last_name": "W" }, "chat": { "id": -406916955, "title": "Test message exchange", "type": "group", "all_members_are_administrators": true }, "date": 1605914840, "text": "Test message" } }
Для решения задачи в частном виде (одного конкретного чата), нам достаточно будет использовать полученное chat id: −406916955. Установив фильтр по данному id, мы будем обрабатывать только сообщения в одном чате. Конечно, в реальной системе нам необходимо предусмотреть механизм добавления бота в различные чаты и соответствующую обработку события.
Создание Teams канала и отправка сообщений из него в Telegram
Теперь создадим команду, в которой сделаем канал обмена сообщениями с Telegram-чатом:
Существует три вида команд в Teams:
Private — участие должен подтвердить владелец канала.
Public — команда, открытая для всех желающих. Надо быть осторожным с использованием этой команды, так как вся переписка и файлы будут доступны всем сотрудникам организации.
Org-wide — команда, в которую по умолчанию добавляются все сотрудники организации.
Наш выбор — Private-команда, назовём её Telegram exchange.
Мы создали команду, и по умолчанию в ней создан общий канал:
Для обмена сообщениями с чатом Telegram создадим канал Telegram chat. Для этого нажмите на три точки возле команды и выберите Add channel:
У каналов есть два режима приватности:
- Стандартный (Standard) — в этом случае все участники команды могут просмотреть все сообщения канала и чата.
- Приватный (Private) — в этом случае только выбранные участники имеют доступ к сообщениям и файлам этого канала.
В нашем случае будет удобно, чтобы все участники канала смогли просмотреть всю историю переписки, поэтому оставляем стандартную настройку и создаём канал.
Теперь, когда у нас готов канал, из которого необходимо пересылать сообщения в чат Telegram, давайте автоматизируем этот процесс при помощи Power Automate. Для этого нам понадобиться создать новый автоматический поток (Automated flow):
С триггером на новое сообщение в канале When a new channel message is added, назовём его Teams to telegram flow:
В карточке триггера выберем нашу команду и наш канал обмена сообщениями с Telegram:
Добавим новый шаг для обработки поступившего сообщения. Так как сообщения в Teams имеют HTML-разметку, необходимо преобразовать их в обычный текст. В этом поможет существующий компонент HTML to text:
Работает он просто, достаточно на вход подать текст в разметке HTML, который будет преобразован в текст:
Теперь, казалось бы, всё готово для того, чтобы отправить сообщение в Telegram, но мы должны предусмотреть, что все сообщения, поступившие в чат Telegram, будут пересылаться обратно в Teams. И чтобы не попасть в бесконечный цикл пересылки сообщений между мессенджерами, необходимо настроить фильтрацию и исключить повторную отправку тех сообщений, которые пересылает бот. Сделать это можно разными способами, один из которых — фильтровать по части сообщения. Для этого мы ко всем сообщениям из Teams будем дописывать «From Teams>>», а к сообщениям из Telegram — «From Telegram>>».
Добавим в поток шаг, проверки текста, который мы планируем отправить в Teams:
Добавляем условие (Condition):
Добавляем в значение очищенный от тегов текст сообщения (необходимо выбрать The plan text content):
И в доступных условиях нужно выбрать «начинается с» (starts with):
И так как это ветка отправки в Telegram, то отфильтруем сообщения, которые пришли из Telegram. Для этого в значение условия введём: From Telegram>>.
В ветку «If yes» будут попадать сообщения, которые пришли из Telegram. Их мы будем игнорировать, чтобы не попасть в бесконечный цикл пересылок. А в ветку «If no» — все остальные сообщения, отправленные пользователями, в этом случае их нужно переслать в Telegram.
В ветке «If no» добавим действие (Add an action) — отправка HTTP-запроса. У этого компонента есть пометка Premium, что означает дополнительные требования к лицензиям Power Automate — у пользователя должна быть лицензия Power Automate per user plan:
Отправка текстового сообщения в Telegram может быть как через GET, так и через POST-метод. Для нашего обмена короткими сообщениями подойдёт GET:
В поле URI мы добавим следующую ссылку:
https://api.telegram.org/bot/sendmessage?chat_id=-406916955&text=From Teams>>
И добавим к ней динамический контент — имя отправителя (Message from user displayName):
и текст сообщения. Только, чтобы передача текста произошла без ошибок, нам необходимо будет закодировать ссылку в допустимый для URI формат. С этим нам поможет функция encodeUriComponent(), которой на вход мы отправим очищенное от HTML тегов текстовое сообщение: encodeUriComponent(outputs(’Html_to_text’)?[’body’]):
Теперь можно сохранить поток и отправить тестовое сообщение в чат Telegram из Teams.
И с небольшой задержкой получим его в Telegram:
Отправка сообщения из Telegram в Teams
Аналогично тому, как мы организовали отправку сообщений из Teams в Telegram, теперь дополним поток получения сообщений через Webhook от бота Telegram и отправим его в Teams.
Для этого откроем наш поток MessageExhcangeBotHook:
И внесём в него правки (Edit):
Добавляем новый шаг (Add new step) и уже знакомый компонент HTML to text:
Чтобы предусмотреть фильтр по сообщениям, добавляем в поле контента начало пересылаемого сообщения: «From Telegram>>», а также информацию об отправителе — её мы сможем взять из динамического контента: first_name — имя, last_name — фамилия пользователя Telegram и сообщение — text.
Теперь наша задача — отфильтровать сообщения из множества чатов, в которые может быть добавлен Telegram-бот, и пересылать сообщения только определённого группового чата. Для этого воспользуемся условием Switch и создадим ветку действий для нашего чата:
Переключение веток потока происходит на основании параметра в поле «On» — туда мы подставим chat id из динамического контента, и поток направляется в ветку (case), где значение параметра будет совпадать со значением в поле Equals.
Так как значений «id» в динамическом контенте несколько, убедимся, что вы выбрали правильный. Это можно сделать благодаря всплывающей подсказке, которая появляется, если навести курсор на динамическую переменную:
Теперь в ветке с нашим чатом создадим новый шаг с отправкой сообщения в канал Teams:
Важный момент — переключить режим редактора в Code View (иконка: </>) и так как сообщения отправляются в HTML, то необходимо убрать теги <p>, которые оформляют сообщения:
Теперь сохраним поток и отправим сообщение в группу Telegram:
И тут же получим его в Teams:
Заключение
Несмотря на отсутствие механизмов Interoperability между Teams и Telegram, их можно «подружить» через программные интерфейсы. А для решения такой задачи уже достаточно low-code/no-code платформ автоматизации и нескольких часов, а не отдельной команды разработчиков и недель на постановку задачи и её реализацию. Кроме простого обмена сообщениями, доступные методы позволяют обмениваться файлами и настроить более полное взаимодействие по различным событиям, если возникнет такая необходимость.
16 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів