Как упростить коммуникацию, «подружив» 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.

Для начала давайте определимся с задачей.

Дано:

  1. Команда и канал в Teams, где могут присутствовать различные сотрудники и приглашать своих коллег (чат 1).
  2. В 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) от бота. Есть два варианта работы:

  1. Мы можем вручную запрашивать наличие новостей, постоянно выполняя веб-запрос с методом getUpdates. Такие запросы называют PULL (тянуть) подходом, когда мы в удобное для нас время запрашиваем информацию обо всём, что произошло между предыдущим запросом и текущим.
  2. Бот может при наступлении нового события сразу отправлять его нам через механизм Webhook. Для этого у нас должен быть развёрнут сервис, который ожидает получения такого сообщения и обрабатывает его. Такой подход называется PUSH (толкать), так как всю информацию бот сразу выталкивает в сторонний сервис.

В некоторых случаях, например, когда мы хотим проверять состояние бота раз в день или раз в час, нам может быть удобен подход PULL, но так как мы хотим построить максимально интерактивную систему, то нам больше подойдёт PUSH с работой через Webhook.

Перед тем как мы переключим бота в такой режим, необходимо настроить сервис, который будет принимать PUSH-сообщения. К счастью, Power Automate позволит организовать такую систему очень просто, без необходимости аренды и настройки отдельного веб-сервера.

Настройка Webhook на Power Automate

Итак, мы определились, что будем использовать интерактивный механизм обмена сообщениями с ботом.

Power Automate работает по принципу потоков (flow), когда серия действий выполняется друг за другом. А начинает свою работу по одному из следующих принципов:

  1. Автоматически (Automated flow). Обычно для такого способа используется преднастроенное действие — триггер. Таким триггером может быть, например, получение почты в Exchange online, сообщения в Teams или сохранения файла в OneDrive.
  2. Мгновенно (Instant flow). Обычно такие потоки запускаются вручную, по какому-то внешнему событию или вручную по необходимости.
  3. По расписанию (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:

У каналов есть два режима приватности:

  1. Стандартный (Standard) — в этом случае все участники команды могут просмотреть все сообщения канала и чата.
  2. Приватный (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 платформ автоматизации и нескольких часов, а не отдельной команды разработчиков и недель на постановку задачи и её реализацию. Кроме простого обмена сообщениями, доступные методы позволяют обмениваться файлами и настроить более полное взаимодействие по различным событиям, если возникнет такая необходимость.

👍ПодобаєтьсяСподобалось8
До обраногоВ обраному6
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

В matrix можна спокійно мати загальний спейс для кількох серверів через конектори, і нативну підтримку для всіх сторін. Дуже просто розгортається бридж і на тг, і на тімз. З гіттером та irc взагалі з коробки. Це я звичайно до контексту рішень кросс-сайт комунікації, яким матрікс задумувався, крім того що це доволі крутий месенжер сам по собі, більш безпечно для бізнес комунікації (бо в телеграм люди часто зберігають конфіденційні дані в папку збереженого і не тільки)
Але це вибір зручності і приватності, то вже вирішувати бізнесу.

А можете навести аргументи чому Ви обрали саме Power Automate ? Є безліч конкурентів той же UiPath. І чи економічно вигідно це, враховуючи що у вас відсутні системи контролю версій, як не як код простіше б масштабувався та підтримувався.

Power Automate це платформа, яка інтегрована з Office 365 і враховує усі налаштування безпеки. Використовувати сторонні сервіси, звісно, можна, але навіщо, якщо підняти сервер для webhook запитів можна за лічені хвилини.
Контроль версій залишається за коннекторами, які є стандартними — цим займається Майкрософт. Якщо будуть оновлюватись API Teams — потрібно буде просто в декілька кліків замінити старий коннектор на новий. Якщо буде мінятись API Telegram — скоріш за все, потрібно буде підвантажити нову структуру JSON. Однак це буде потрібно робити в будь-якій системі.
Економіка цього рішення прораховується окремо, тому що в багатьох компаніях вже є Office 365. Дуже часто це вигідно, ніж купляти ще окрему систему.
Залежно від задачі, звичайно, можна використовувати інструменти, які більше для неї підходять.

може якби тімз був юзабельний, не треба було б писати цю інтеграцію)

може якби тімз був юзабельний, не треба було б писати цю інтеграцію)

Чому він не юзабельний?

Спочатку це був корпоративний інструмент, а зараз ще є версія для кінцевих користувачів, яка, доречі, вже інтегрована в Windows 11.
Тімзом щоденно користуються вже 145 мільонів юзерів.

Які вимоги зазвичай закриває використання МС Тімс?
Те що я зустрічав — це в основному безпека, компанія не хоче, щоб:
— повідомлення (а ще скріншоти, шматки коду, записи відео та аудіо) зберігались або проходили через сервери компаній з якими у них немає контрактів про збереження даних;
— МС тімс на мобільних пристроях часто йде з вимогами зафорсити вимоги по безпеці (введення піна, доступ до ресурсів телефону, які мали б бути приватними, і тд)

Оцими іграми ви «похерили» вирішення вказаних проблем. Ви впевнені, що така стаття не змусить напрягтись клієнтів SoftwareONE?

Безпека тут не порушена. Зі свого досвіду можу сказати, що в більшості компаній і так є окремі чати між співробітниками в не корпоративних мессенджерах. Платформа Power Automate і API, які ми використовуємо, залишаються під контролем безпеки.

Безпека тут не порушена.

Як саме ви гарантуєте, що повідомлення виду:
«Народ, ми підписали контору з надкушеним яблуком! Го стафити 5 команд про, які говорили раніше»
не вийдуть за межі корпоративної інфраструктури?

Зі свого досвіду можу сказати, що в більшості компаній і так є окремі чати між співробітниками в не корпоративних мессенджерах.

Таке буває. От тільки одна з задач менеджерів (проджект, ендженірінг менеджерів або тімлідів) нагадувати, що
«по роботі ми використовуємо корпоративний, про побухать будь-який».
І часто це закінчується створенням в корпоративному месенджері чатів про дозвілля, типу «Ланч» або «Київ Футбол Клаб»

Compliance політики будуть відпрацьовуватися до коннекторів. Якщо хтось спробує поширити інформацію і при цьому буде налаштовано DLP, то таке повідомлення не буде відправлено. Крім того, в компаніях де мають справи з sensitive data, скоріш за все, заблокують коннектори в Power Automate і дане рішення для них буде не актуальним.

Чати типу «Ланч», «Футбол» в сторонніх мессенджерах часто з’явлюяться, тому що в них можуть знаходитись не тільки користувачі компанії. Я часто використовую функцію вимкнути повідомлення в таких чатах Тімс, щоб не відволікатись на кожне повідомлення.
Скоріш за все, тут справа звички. :)

Якщо хтось спробує поширити інформацію і при цьому буде налаштовано DLP, то таке повідомлення не буде відправлено
Як саме ви гарантуєте, що повідомлення виду:
«Народ, ми підписали контору з надкушеним яблуком! Го стафити 5 команд про, які говорили раніше»
не вийдуть за межі корпоративної інфраструктури?

Ви просто сказали, що інструменти існують. Але як вирішити проблему, яка __була створена такої інтеграцією__, все ще не ясно. Додавати МЛ, який буде відрізняти бізнес інсайти і рецепт яблучного пирога?

Чати типу «Ланч», «Футбол» в сторонніх мессенджерах часто з’явлюяться, тому що в них можуть знаходитись не тільки користувачі компанії. Я часто використовую функцію вимкнути повідомлення в таких чатах Тімс, щоб не відволікатись на кожне повідомлення.

Знову ж солюшн дуже простий і вирішується підходом «Но Код»:
Робоче в тімс. Приватне в іншому месенджері. І відсутній перетин між ними (наприклад інтеграція, яку ви запропонували) :)

Я працював в конторі де скайп був основним робочим месенджером. Так ось у мене було 2 аккаунти — для роботи і приватний. Походи на ланч були в робочому, бо в реальності не було людей зовні контори, які б ходили з нами на обід :)

«Как упростить коммуникацию, ...» украинская версия.
Озвучить заказчику стоимость и через пару недель парочка новых офис менеджеров с радостью будут копировать сообщения между мессенджерами.

Мы тут про технологии :), а не про лайфхаки для бизнеса)

Q: Как упростить коммуникацию, «подружив» Telegram и Microsoft Teams.
A: Перекинуть таску на SoftwareON или Дениса лично (зависимо от того кому нужно решение, частному лицу или корпорации), за несколько часов усё будет, там копипасты много, думать мало.

Технологии сейчас становятся проще и доступнее для продвинутых пользователей. Те же чат-боты на сегодня в Тимс создаются за несколько часов, без строчки кода.

Підписатись на коментарі