Pull to refresh

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

Reading time 5 min
Views 9.9K
Эта статья о том, как мы проектировали универсальную систему оповещений для наших веб-приложений и что в итоге получилось. Не стану утверждать, что полученный результат является единственно верным, однако считаю его достаточно хорошим. Если у вас есть опыт решения подобной задачи, приглашаю поделиться им в комментариях.

Суть задачи


Дано: веб-приложение для совместной работы. Для простоты будем считать, что это CRM или Task Tracker.
Требуется: своевременно уведомлять пользователей о событиях в приложении, на которые требуется их реакция.

В чем проблема?


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

Первый блин Первое быстрое решение


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



Помимо слишком большого списка изменений, есть у этого блока «Что нового?» и другие проблемы:
  • Не видно, какие именно изменения произошли в данных (какое поле поменялось и как)
  • Неизвестно, кто и когда внес эти изменения
  • Непонятно, требуется ли от меня (как от пользователя) какая-то реакция на эти изменения

Казалось бы, для ответа на все эти вопросы есть журнал действий, в котором хранится максимально подробная информация о каждой транзакции:



Однако, как показывает практика, пользоваться журналом действий для получения оперативной информации о событиях в приложении неудобно. Как правило, такая подробная информация об изменениях требуется в редких случаях — ее использует руководитель при «разборе полетов». А в реальном времени сотруднику нужна не столько подробная, сколько выборочная информация — с акцентом на интересующие его изменения. Например, после «Завершения дела» (из примера выше) мне хотелось бы видеть такую информацию:
Сегодня в 12:48 Иванов завершил дело P4D1: Подготовка документов на подачу заявки.
Петрову назначено дело P4D2: Получение оригиналов заявки от клиента.

Это если я руководитель этих Иванова и Петрова и хочу максимально их контролировать. Если же я Петров, то мне будет удобнее получить оповещение в таком виде:
Вам назначено дело P4D2: Получение оригиналов заявки от клиента. Срок выполнения – 2 дня.

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

Классификация оповещений


По источнику возникновения

  • Изменены интересующие меня данные. Например, если на меня назначена задача, я хочу это знать. Если создаются или меняются задачи, не имеющие ко мне никакого отношения, то мне это неинтересно.
  • Наступил заданный момент времени. Например, неделю назад мы договорились с клиентом, что я позвоню ему сегодня в 15:00. Если это не единственная моя договоренность за эту неделю, то велика вероятность, что я о ней благополучно забуду. Так что мне будет полезно в нужный момент (или за некоторое время до него) получить напоминание.
  • Произошло определенное событие. Например, зафиксирована попытка входа в приложение с неверным паролем или с запрещенного IP-адреса. Меня (как администратора приложения) это может волновать.

По тому, кого нужно оповещать

  • Всех пользователей. На практике редко бывает, что всех надо оповещать об одних и тех же событиях. Разве что это какие-то новости компании, о которых должны знать все сотрудники.
  • Пользователей с определенной ролью. Администратор настраивает, каким ролям пользователей какие оповещения должны показываться.
  • Конкретных пользователей. Бывает, что какому-то пользователю нужен уникальный набор оповещений, и создавать для него новую роль только для настройки этого набора нет смысла. Тогда можно назначить оповещение для конкретного пользователя. Другая ситуация, когда это может понадобиться — это если администратор не против, чтобы пользователи самостоятельно выбирали, какие оповещения они хотят видеть. В этом случае тоже надо хранить настройку для конкретного пользователя.
  • Вычисляемых пользователей. Например, при создании задачи нужно оповещать только пользователя, указанного в поле «Ответственный». Заранее (на этапе настройки) неизвестно, кто в какой задаче будет назначен ответственным, поэтому назначить оповещение на конкретного пользователя невозможно. А при сохранении данных эта информация в системе уже есть — вот ее и используем при формировании оповещения.

По способу оповещения

  • Real-time. Оповещения приходят в реальном времени. Как только наступило событие, пользователю выдается сообщение прямо в браузере или в виде всплывающего окна в трее. Для привлечения внимания сообщение может мигать и издавать звук.
  • По SMS. Такой способ оповещения имеет смысл в том случае, когда реакция на событие требуется незамедлительно, а у пользователя нет доступа к real-time оповещению. Как правило, такой способ используется для сообщения о важных событиях сотрудникам, работающим «в полях» без доступа к интернету или просто без возможности держать браузер постоянно открытым.
  • По email. Уведомление в виде письма на электронную почту имеет смысл использовать для редких событий, не требующих оперативного реагирования. Также можно использовать оповещение по email как запасной вариант на случай, что в нужный момент пользователь не был в приложении.
  • В ленту новостей. Такие оповещения никак не привлекают к себе внимания в момент появления, зато их можно просмотреть в любое время по инициативе пользователя. Это, скорее, даже не оповещения, а персональная история событий в приложении.

По сроку хранения

  • Вообще не хранится в базе. Сообщили пользователю о важном для него событии — отправили сообщение в браузер или письмо на почту — и никак не контролируем, достигло ли оно адресата. Проблема такого варианта в том, что в некоторых случаях пользователь может не получить уведомление — например, закрыл браузер, не прочитав сообщение, или письмо попало в спам — и мы никак об этом не узнаем. И пользователь не узнает, что что-то пропустил.
  • Удаляется автоматически после прочтения. Подходящий вариант, когда оповещений много, а информации в тексте оповещения содержится мало. Когда пользователю достаточно один раз прочитать сообщение и он может сразу приступить к выполнению задачи.
  • Помечается прочитанным, требуется явное удаление. Подойдет для случая, когда о задаче узнаем сейчас, а выполнить ее можно и позже. Тогда оповещение останется в списке в качестве напоминания, а когда задача будет выполнена, его можно удалить вручную.
  • Удаляется автоматически через некоторое время. Если оповещений много и они теряют актуальность со временем (например, оповещение о дне рождения коллеги или об изменении графика работы в определенный день), то имеет смысл удалять их автоматически по прошествии заданного времени — независимо от того, прочитаны они пользователем или нет.

Результат


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



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

Заключение


Как уже было сказано в начале статьи, найденное решение не претендует на идеальность. Не исключаю, что в дальнейшем оно может быть как-то дополнено или даже полностью изменено. Надеюсь в комментариях встретить конструктивную критику и другие варианты решения задачи.
Tags:
Hubs:
+5
Comments 5
Comments Comments 5

Articles