Визуализация результатов Telegram-опросов в Grafana
Хотел бы поделиться интересным решением, которое, уверен, было бы полезно для кооперативов и товариществ.
Современные технологии постепенно проникают во все области нашей жизни. Сегодня сложно представить соседей многоквартирных домов или земельных участков СНТ/ДНТ без группового чата в мессенджере. Такие группы удобны для общения, они позволяют оперативно решать вопросы, публиковать объявления, делиться новостями и даже проводить опросы и голосования.
Кстати, голосование в мессенджере может иметь юридическую силу. Для этого нужно принять решение о возможности применения электронных средств при принятии решений общим собранием членов товарищества и внести соответствующие изменения в устав товарищества (п. 25 ч. 1 ст. 17 федерального закона № 217-ФЗ). При создании нашего товарищества так мы и сделали, и теперь большинство вопросов мы решаем удаленно через Telegram.
Результаты опросов, проведенных в Telegram, отображаются почти моментально в интерфейсе мессенджера. Однако такие результаты не учитывают случаи, когда количество голосов у членов товарищества отличается. Кроме того, в общем чате могут присутствовать супруги/родственники участников, которые могут проголосовать без права голоса. В итоге всё сводится к тому, что необходимо каждый раз пересчитывать голоса.
Чтобы не утомлять секретаря собрания лишней рутиной, мы решили автоматизировать этот процесс. И вот, что у нас получилось.
На скриншотах ниже представлены результаты одного из первых Telegram-опросов, которые мы провели.
Панели Pie Chart и Stat
Панель Geomap
Таким образом, участник товарищества просто отдает голос в опросе Telegram, а система автоматически в онлайн-режиме учитывает его голос (голоса) и отображает данные на дашборде.
Здорово, не так ли?
Визуальная часть нашего решения реализована в Grafana. Мы использовали панели Pie Chart, Stat и Geomap. Источником данных служит база данных MongoDB с коллекциями «Соседи», «Земли», «Опросы». Для подключения MongoDB в Grafana мы используем плагин grafana-mongodb-community-plugin.
Чтобы программно «отлавливать» голоса в Telegram, нужно чтобы опрос был создан Telegram-ботом. Такого бота мы написали на Golang с использованием библиотеки telegram-bot-api.
Учет голосов реализован в функции handlePollAnswer. Ниже представлена её упрощенная версия.
func handlePollAnswer(pollAnswer *tgbotapi.PollAnswer) {
// Ищем пользователя в БД
neighbor, err := db.GetNeighborByChatID(pollAnswer.User.ID)
if err != nil {
// handle error
return
}
// Если пользователь отменил голос, исключим его голос из базы
if len(pollAnswer.OptionIDs) == 0 {
err := db.DeleteVote(pollAnswer.PollID, neighbor.ID)
if err != nil {
// handle error
return
}
} else { // Если проголосовал, добавим голоса в базу
for _, optionID := range pollAnswer.OptionIDs {
err := db.AddVote(pollAnswer.PollID, neighbor, optionID)
if err != nil {
// handle error
return
}
}
}
}
Пример создания опроса в интерфейсе Telegram приведен на скриншоте ниже.
Пример создания опроса через интерфейс Telegram-бота
Для отображения данных на карте мы написали небольшой веб-сервис, который по данным коллекций «Опросы» и «Земли» формирует GeoJSON и возвращет его по HTTP-запросу. URL до нашего веб-сервиса мы указали в настройках панели Geomap. Там же настроили правила отображения.
Подложку для карты (тайлы) для нашего некоммерческого проекта мы сначала попросили у Yandex, так как на ней указаны названия улиц нашего посёлка. Но Yandex нам отказал. В итоге было принято решение взять подложку Here, за что мы им очень благодарны.
На этом у меня всё. Пишите Ваши вопросы в комментариях.
Спасибо за внимание!