Telegram-Бот Для Redmine. Как Упростить Жизнь Себе И Другим

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

Особенно если взаимодействие с клиентами происходит через эту систему.

В статье пойдет речь о том, как связать Redmine с Telegram, не нарушая существующие бизнес-процессы.



Telegram-бот для Redmine. Как упростить жизнь себе и другим

Немного предыстории о том, как родилась идея темы.

Наша компания занимается администрированием серверов и сайтов 24/7, разработкой инфраструктуры для крупных и развивающихся интернет-проектов, проектированием отказоустойчивых систем и автоматизацией DevOps. Для взаимодействия с клиентами мы используем Redmine, который мы адаптировали под свои процессы и добавили в него ряд приятных мелочей, облегчающих нашу жизнь.

Еще когда мы только начинали, это было в 2011 году, мы решили, что будем общаться с клиентами только через наш таск-трекер.

Это связано с тем, что помимо поддержки серверов и реагирования на инциденты, большую часть нашей работы составляют задачи по развитию инфраструктуры.

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

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

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

Поэтому вопрос синхронизации знаний и действий внутри коллектива и между сменами для нас крайне важен.

Приняв во внимание все эти факторы, мы решили, что единственный возможный способ держать ситуацию под контролем — сделать так, чтобы все коммуникации и вся работа происходили в одном месте — в системе задач.

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

Если мы добавим к коммуникациям еще один канал, например, мессенджеры, скажем, для быстрого обсуждения каких-то вопросов, клиенты 100% начнут им злоупотреблять, мы быстро утонем в пучине бесконечных комментариев, а важная информация просто начнется.

потеряться.

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

Кто-то, поработав с нами с этим, решил внедрить это в своей компании.

Лишь изредка некоторые клиенты спрашивали, можно ли ставить нам задачи не только через систему задач, но и через какой-нибудь мессенджер, ведь так было бы удобнее.

Но за последние 2 года количество таких запросов значительно возросло.

Настолько, что не учитывать их уже было невозможно.

И мы еще раз задумались, что с этим делать.

Менеджеры по продажам, как обычно, пытались протолкнуть идею каким-то чудесным образом интегрировать общение с клиентами через Skype, WhatsApp или Telegram в наши рабочие процессы.

Администраторы этого категорически не хотели.

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

Набросали небольшой план — сначала минимальный функционал, потом приятные мелочи.

Через некоторое время мы получили прототип будущего бота, который успешно доставлял написанное ему сообщение из Telegram в Redmine и наоборот! Это вселило в меня уверенность в жизнеспособности идеи.

И мы приложили все усилия, чтобы довести его до завершения и запустить.

Чтобы лучше объяснить, как все это работает, статья разделена на два блока.

Первый блок содержит общее описание бота и примеры его работы.

Вторая посвящена дизайну и техническим аспектам бота.

В конце статьи есть ссылки где скачать и как настроить нашего бота.

Итак, что мы имеем?



Авторизация пользователя

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

Для этого у пользователя должна быть активная учетная запись Redmine. Ему нужно разобраться в этом самому имя пользователя и зарегистрируйте его в настройках вашего аккаунта Telegram:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Это же имя пользователя необходимо ввести в настройках учетной записи Redmine в специальное дополнительное поле «Telegram»:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Далее пользователь находит бота в Telegram и нажимает «Старт».

Бот авторизует это и приветствует:

Telegram-бот для Redmine. Как упростить жизнь себе и другим



Ставить цели

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

В этом случае к сообщению можно прикрепить файлы:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

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

При выборе пункта «Добавить к последней задаче» комментарий пользователя будет добавлен к задаче, по которой велась последняя переписка.

Бот показывает это выше.

Если выбрать «Создать новую задачу», бот перейдет в режим создания новой задачи:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

И предложит пользователю:

  • Выберите проект (необязательно, если вас не устраивает проект по умолчанию):


Telegram-бот для Redmine. Как упростить жизнь себе и другим

  • Укажите приоритет задачи (необязательно, если вас не устраивает стандартный):


Telegram-бот для Redmine. Как упростить жизнь себе и другим

Пользователь может пропустить эти шаги, если его устраивают значения по умолчанию, и сразу нажать «Создать задачу»; ему нужно только указать для него заголовок:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

После этого бот уведомит клиента о создании задачи (ссылка на задачу кликабельна и при необходимости можно сразу перейти к заявке):

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Что в Redmine будет выглядеть так:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Если пользователь нажал «Выбрать задачу», бот предложит список открытых на данный момент задач, к которым можно отправить письменный комментарий:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

В этом случае пользователь видит в Redmine только те проекты и задачи, к которым он подключен.

Это касается всех действий в боте.



Переписка по задачам

Бот поддерживает доставку уведомлений об изменении задач.

Например, наш администратор выполнил задачу и просит клиента проверить результат:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Вот что получит клиент:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Отвечать на задания можно через Ответить на соответствующее сообщение в Telegram. Это особенно удобно, когда работа ведется сразу над несколькими задачами (ответ пойдет сразу в нужный тикет без дополнительных вопросов):

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Нижняя граница.

Клиент создал задачу, пообщался по ней и все это сделал через Telegram. Для этого ему никогда не приходилось входить в Redmine. Сотрудник получал и обрабатывал задачу в привычном для себя виде в Redmine, в рамках стандартных бизнес-процессов, ему не приходилось переключаться в мессенджер и потом беспокоиться о передаче корреспонденции в систему задач.



Поддержка вложений

В боте мы реализовали поддержку вложений.

И это работает в обе стороны.

Прикрепить можно что угодно: фотографии, документы, видео и аудио.

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

Допустим, система мониторинга сообщила нам о проблеме на одном из серверов.

Администратор создал задачу через Redmine и привязал к ней расписание системы мониторинга.

Клиент получит следующее сообщение:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

На что он может ответить голосовым сообщением:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Голосовое сообщение будет доставлено задаче и прослушано администратором.



Ограничения

Конечно, они есть.

Мы столкнулись со следующим:

  1. Длинные сообщения.

    В Telegram есть ограничение на длину одного сообщения — 4096 символов.

    Изначально длинные комментарии Redmine были просто обрезаны.

    Пришлось написать обработчик, который разбивал бы длинные комментарии на части.

    Причем так, чтобы глаз радовал, то есть чтобы комментарий не заканчивался строго на 4096-м символе в середине слова, а разделение происходило аккуратно, на стыке фраз.

    Неудобство для клиентов состоит в том, что в этом случае будет получено несколько сообщений.

  2. Форматирование.

    Форматирование в Redmine и Telegram — это две разные вселенные.

    Но это понятно; у них несколько разные цели.

    Форматирование Redmine отображается в Telegram в виде служебных символов, и иногда его очень неудобно читать.

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

    Из Telegram в Redmine тоже не всё переносится.

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

  3. Имена изображений.

    Если вы прикрепите изображение (именно изображение) в Telegram, бот получит файл с именем в формате file_xyz.jpg. Соответственно, в Redmine он окажется под тем же именем.

    Здесь мы пока ничего сделать не можем, так как бот сам получает файлы с такими именами.

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



Статистика использования

С момента запуска прошло чуть больше двух месяцев.

Первые наблюдения:

  1. На данный момент около 3,5% задач создаются и обновляются клиентами через бота.

  2. Как я писал выше, бот нашел применение не только среди клиентов, но и активно используется нами самими.

    Очень удобно получать уведомления о задачах (они приходят быстрее, чем на почту) и сразу на них отвечать.

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



Коротко о том, как работает наш бот

  • Написан на C. Точнее, в нашем фреймворке, который написан на C.
  • Использует два типа баз данных: Redis и MySQL.
  • Нам нужно было написать плагин для Redmine, который бы активировал механизм перехвата при создании задач и комментариев.

  • Легко тиражируется и масштабируется
Итак, начнем.

Основная схема работы бота выглядит следующим образом:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

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

На стороне Telegram все происходит аналогичным образом — определяется тип сообщения, к какой задаче оно относится и доставляется в Redmine. Теперь добавим немного действий и познакомимся с некоторыми особенностями доставки сообщений в Telegram! Telegram разбивает большие сообщения на несколько маленьких.

Эти сообщения приходят с некоторой задержкой.

Все вложения доставляются отдельными сообщениями и иногда с большой задержкой (по мере их загрузки пользователем).

Те.

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

так что нам делать? Мы решили создать для этого очереди сообщений и использовать Redis для их хранения.

Наш бот ставит каждое входящее сообщение в очередь и обновляет время задержки его обработки.

Когда эта задержка истечет, мы считаем, что сообщение полностью сформировано и теперь мы можем выбрать задачу и отправить ее в Redmine. Далее возникает вопрос: как выбрать нужную задачу в Redmine? Ведь для того, чтобы бот понял, что делать с полученными данными, ему нужно спросить об этом пользователя, а это, как ни крути, другое сообщение (даже если это нажатие кнопки) и его нужно быть каким-то образом связанным с предыдущими действиями пользователя.

Сеансы помогут нам в этом.

Первое сообщение, полученное от учетной записи пользователя Telegram, создает сеанс, который содержит:

  • Идентификатор пользователя, с которым связана сессия
  • Тип сеанса (т.е.

    его состояние)

  • Данные, с которыми нужно что-то делать
Каждое последующее сообщение, поступающее из Telegram, может либо дополнить сессию данными, либо изменить ее состояние (например, запустить процесс дальнейшей обработки и доставки данных), либо уничтожить сессию (например, если пользователь передумает писать его комментарий) или привести к ошибке (например, если тип полученных данных не соответствует текущему состоянию сессии).

Еще одна важная составляющая бота — кеширование.

Наш Redmine состоит из довольно большого количества проектов, пользователей и некоторых других данных.

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

У бота есть отдельный процесс, который лишь периодически получает от Redmine необходимые для других процессов данные и сохраняет их в Redis. А как насчет MySQL? Выше было отмечено, что помимо Redis бот использует и MySQL. Конечно, все данные можно было бы хранить в Redis, но несмотря на наличие периодических дампов, данные всё равно находятся в памяти и неожиданный сбой в системе может привести к их потере, и среди них есть очень важная информация, которую необходимо сохранить.

относиться с особой осторожностью.

Чтобы лучше понять, о чем идет речь, вспомним первую часть статьи.

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

И бот должен понимать, в какую задачу его нужно добавить.

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

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

Допустим, пользователь пишет свое первое сообщение боту Telegram. Бот открывает сессию и спрашивает пользователя, к какой задаче нужно добавить комментарий.

После получения ответа бот отправляет данные в Redmine и одновременно сохраняет эту переписку у себя.

Далее, когда пользователь ответит на это сообщение в Telegram, бот получит номер «родительского» сообщения и по нему определит номер задачи Redmine, на которую следует отправить комментарий.

Описанная переписка установится и для этого нового сообщения, т.е.

на него потом можно будет и ответить.

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

Теперь представим, что мы потеряли все эти переписки.

Те.

Клиент по привычке нажимает ответить на пришедшее ему сообщение от администратора, пишет свой комментарий и отправляет его боту.

Но т.к.

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

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

А т. к.

по опросам бот чуть ли не чаще используется в качестве нотификатора (для подмены почты), то мы можем попасть в еще большие неприятности.

Чтобы не расстраивать пользователей, мы поместили эти данные в менее быстрый, но более надежный MySQL. Справедливости ради стоит отметить, что наша команда до сих пор обсуждает, стоит ли отказываться от MySQL и переносить эти данные в Redis. Поэтому не исключено, что в будущем мы можем полностью перейти на работу с Redis, а может быть, даже на какую-то другую систему хранения данных.

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



Масштабирование и отказоустойчивость

Теперь хотелось бы поговорить о том, как обеспечить масштабируемость и отказоустойчивость бота.

С появлением бота наш Redmine в некоторых случаях превратился в чат и интенсивность общения постоянно растёт. Некоторые из наших клиентов также хотят интегрировать его в свою инфраструктуру.

А учитывая, что наша разработка полностью открытая, неизвестно, какая еще компания или команда администраторов/разработчиков захочет ее использовать и неизвестно, с какими нагрузками столкнется бот. Поэтому еще на стадии разработки проекта мы заложили в него возможность масштабирования.

В нашем проекте масштабирование можно разделить на два класса:

  • Масштабирование базы данных Здесь все достаточно известно:
    • Для MySQL можно использовать Percona Cluster или аналоги.

    • Для Redis — кластер Redis
  • Масштабирование самого бота
Чтобы понять, как масштабировать бота, давайте подробнее рассмотрим процесс получения и обработки сообщений.

Принципиальная схема выглядит следующим образом:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Единственная задача процесса «Rest API» — поместить полученное от Redmine или Telegram сообщение в очередь (ra-queue) и ждать следующих.

Эта очередь постоянно контролируется процессами «Queue-workers» и когда в ней появляются данные, они их читают. Сообщения от Redmine моментально обрабатываются и отправляются нужным пользователям в Telegram. С событиями из Telegram все сложнее.

из-за того, что их нельзя отправить в Redmine сразу (причины описаны выше), они переносятся в другую очередь, уже разделенную по пользователям.

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

Рано или поздно все эти сообщения читаются, проходят предварительную подготовку, тем или иным образом меняют состояние сессии и могут быть отправлены в Redmine со всеми прикрепленными файлами, которые на этом же шаге загружаются из Telegram. Здесь важно отметить, что благодаря такому подходу и существующему механизму блокировки обработка всегда происходит на одном конкретном узле.

Именно это позволяет создавать столько экземпляров ботов и с таким количеством процессов «Queue-workers», сколько необходимо в рамках существующей нагрузки.

Когда Redmine получает сообщение, срабатывает перехват и это же сообщение отправляется обратно боту, после чего оно доставляется в другие аккаунты Telegram, подписанные на задание.

Таким образом, инфраструктуру бота в распределенном варианте можно представить следующим образом:

Telegram-бот для Redmine. Как упростить жизнь себе и другим

Но все описанное никоим образом не ограничивает возможности использования бота в обычной автономной версии с одним сервером MySQL и обычной некластеризованной версией Redis.

Как попробовать бота?

Чтобы продемонстрировать работу бота, мы сделали демо-версию, доступную по адресу demo.nxs-chat.nixys.ru .

Чтобы попробовать его в действии, необходимо выполнить несколько предварительных шагов:

  • В demo.nxs-chat.nixys.ru/account/register зарегистрируйте минимум 2 аккаунта (чтобы иметь возможность переписываться между ними) и заполните поля Телеграмма хотя бы для одного из них
  • Активируйте созданные аккаунты
  • Найти бота @nixys_demo_chat_bot для каждого аккаунта Telegram, указанного при регистрации, и нажмите кнопку Начинать .

    Убедитесь, что в настройках аккаунта Telegram указаны те же имена пользователей, что и в настройках аккаунта в demo.nxs-chat.nixys.ru

  • Создать проект в Редмине и добавьте в него созданные аккаунты в роли «Участник проекта»
  • В созданный проект добавьте задачу и начните общение!
Важная заметка! Бот будет отправлять сообщения в Telegram в следующих случаях:
  • Аккаунт, который является автором задания (при условии, что это не автор конкретного комментария)
  • Аккаунт, который является исполнителем задания (при условии, что это не автор конкретного комментария)
  • Аккаунты, находящиеся в списке наблюдателей в задании (при условии, что это не автор конкретного комментария)


Как получить бота?

Бот имеет полностью открытый исходный код и его можно получить как в виде исходного кода, так и в виде пакета (на данный момент пакеты доступны только для Debian 8, но в ближайшем будущем будут доступны для Debian 9 и CentOS 7).

Ссылка к Репозиторий Github с исходными кодами ботов .

Также есть инструкция по установке бота из пакетов и его настройке.



Заключение

В ближайшее время мы планируем добавить следующий функционал:
  • Упрощение создания задач
  • Настройка уведомлений
  • Многоязычный интерфейс
  • Подписка на задачи и отписка от них через бота (на данный момент это можно сделать только через Redmine)
  • В будущем мы планируем добавить распознавание голосовых файлов в текст, что будет очень полезно для задач, которые клиенты создают с помощью голоса.

  • И многое другое
Теги: #Разработка Linux #Управление проектами #Telegram #Redmine #telegram bot
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.