Перейти к содержанию

Чаты — Администрирование

Администрирование чатов не выделено в отдельную форму автоадминки. Чат технически остаётся задачей в чат-категории: участники хранятся как подписчики, сообщения — как комментарии, а настройки — в ChatSettings и ролях чата.

Администратор настраивает:

  • системные категории личных, открытых и закрытых групповых чатов;
  • категорию, открытую в представлении «чат»;
  • почтовые, push- и desktop-уведомления через домен notifications;
  • роли и настройки конкретного чата через chat API/UI;
  • диагностику сообщений, unread и очередей через таблицы комментариев, подписок и очередей.

Механизмы администрирования

Автоадминка и EntityEditor

В карте форм автоадминки не найдено отдельной формы chat/chats. Для чатов используются общие механизмы:

Механизм Где настраивается Что контролирует
system-settings Общие настройки приложения (dbo.Settings) ID системных категорий чата
Настройки категории Домен categories Представление категории, конфиденциальность, email-уведомления
UI/API чата /chat, /api/chats/{taskId}/settings, /api/chats/{taskId}/roles Настройки и роли конкретного чата

Собственных EntityEditor-схем у домена chat в прочитанных источниках не выявлено.

API управления настройками и ролями

Маршруты API для настроек и ролей чата:

Метод Route Назначение
GET /api/chats/{taskId}/settings Получить настройки чата и права на редактирование
POST /api/chats/{taskId}/settings Обновить настройки чата
GET /api/chats/{taskId}/user-settings Получить персональные права пользователя в чате
GET /api/chats/{taskId}/roles Получить роли пользователей и групп
POST /api/chats/{taskId}/roles Назначить роли
DELETE /api/chats/{taskId}/roles Снять роли

Чтение настроек (GET /api/chats/{taskId}/settings) и ролей (GET /api/chats/{taskId}/roles) требует доступа к задаче-чату. Если доступа нет, запрос завершается ответом 404 Not Found — тем же, что и для несуществующего чата, поэтому по коду ответа нельзя определить, существует ли чат.

Вычисленные права в ответе о ролях. Ответ GET /api/chats/{taskId}/roles содержит не только назначения пользователям и группам, но и рассчитанные сервером права текущего пользователя: canChangeSubscribers — менять состав подписчиков (учитывает персональные и групповые роли, права владельца задачи и настройку «Добавлять других подписчиков»), canManageChatThreads — управлять обсуждениями, canDeleteTask — удалять задачу-чат. Благодаря этому клиент показывает пункты управления — «Удалить из подписчиков» в меню участника и удаление в окне «Список подписчиков» — без локального расчёта роли и без передачи в клиент полного списка групп пользователя.

Системные настройки

Категории чатов

Тип чата определяется системными значениями в таблице Settings.

Ключ Что задаёт Эффект
ChatSubcatId Категория личных чатов Задачи этой категории считаются личными чатами; максимум 2 участника. ДП «Обложка социальной сети» в этой категории не привязывается (с 2.268.x).
GroupChatSubCatID Категория открытых групповых чатов Используется для групповых чатов без обязательной приватности
ClosedGroupChatSubcatId Категория закрытых групповых чатов Целевая категория при включении IsPrivate у группового чата или канала
select [Key], [Value]
from Settings
where [Key] in ('ChatSubcatId', 'GroupChatSubCatID', 'ClosedGroupChatSubcatId');

⚠️ Если ClosedGroupChatSubcatId не настроен, платформа при первом запуске может создать подкатегорию «Закрытые группы», записать значение в Settings и перенести приватные групповые чаты в новую категорию. Подробности поведения переключения IsPrivate описаны в бизнес-документации.

Пошаговая настройка категории групповых чатов

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

  1. Создать отдельную категорию в разделе «Системный» с типом представления «Групповой чат» (не «Личный чат»).
  2. В общих настройках приложения в поле выбора категории групповых чатов указать созданную категорию — значение запишется в ключ GroupChatSubCatID таблицы Settings.
  3. Для закрытых групп — отдельная категория с тем же типом представления, привязывается к ClosedGroupChatSubcatId.

⚠️ Типовая ошибка. Если GroupChatSubCatID указывает на ту же категорию, что и ChatSubcatId (категория личных чатов), либо на категорию с типом представления «Личный чат», — при добавлении третьего участника возникает ошибка «в личном чате может быть только два участника». Тип чата определяется по subcatId задачи-чата: групповым он считается, только если subcatId совпадает с GroupChatSubCatID. Решение — переназначить GroupChatSubCatID на отдельную категорию правильного типа.

SettingsCustom / sys_general_settings

Chat-specific ключ SettingsCustom — ConferenceUserChatUseClosedCategory (bool): при true групповой чат, создаваемый после ВКС в личной комнате (более двух участников), помещается в закрытую категорию групповых чатов (ClosedGroupChatSubcatId) вместо открытой (GroupChatSubCatID). По умолчанию (ключ отсутствует или false) — открытая категория; если закрытая категория не задана, чат создаётся в открытой, а в лог пишется предупреждение. Для прочей диагностики конфигурации чатов используйте Settings (system-settings), а не custom-settings.

Второй chat-specific ключ — ChatOpenStatWindowDays (целое): глубина окна, за которое считаются открытия чатов для подсказки частых чатов в мини-поиске. По умолчанию 7 дней; допустимы значения от 1 до 3650, значение вне диапазона или неразобранное заменяется значением по умолчанию. Значение читается из кеша настроек. Записи старше окна ежедневно удаляет регламентное задание, поэтому увеличение окна влияет только на то, что накопится дальше, а уменьшение — сокращает историю ранжирования при ближайшей очистке.

Ограничение прав на коммуникации через ChatSubcatId

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

Шапка группового чата с кнопкой видеоконференции и баннером активной ВКС

Затронуты следующие UI-зоны (с версии 2.268.355; расширение покрытия — с версии 2.268.358):

Зона Что скрывается без права на ChatSubcatId
Мини-карточка пользователя Кнопки «Позвонить» и «Пригласить в видеоконференцию»
Полный профиль пользователя — шапка и меню Кнопка «Начать видеоконференцию» в шапке и пункт меню
Полный профиль — вкладка «Контакты», секция ВКС Кнопка с персональной ссылкой на комнату ВКС
Полный профиль — копирование ссылки на персональную комнату ВКС Кнопка копирования ссылки на персональную комнату ВКС
Левое боковое меню — пункт «Мои звонки и встречи» Пункт меню
Карточка задачи Создание ВКС-встречи — оба входа
Поиск контактов Меню при наведении с кнопками целиком; внутри — отдельная кнопка ВКС

Отдельной настройки «право на ВКС» нет. ВКС-кнопки видны при одновременном выполнении двух условий: у пользователя есть право на категорию ChatSubcatId и включён глобальный флаг конференций (IsConferenceEnabled, см. ниже).

Механизм управления — стандартный: в правах на категорию ChatSubcatId для нужной группы отобрать действие «Создание задач». Никаких отдельных спецправ или новых настроек категории фикс не вводит.

Глубокие ссылки/URL (например, прямой переход в комнату ВКС по ссылке, полученной от другого пользователя) этим механизмом не закрываются — он работает на уровне видимости UI-элементов, а не на уровне доступа к самим ресурсам ВКС.

Настройки категории

Представление категории в режиме чата

Категорию можно открыть в чат-представлении:

/spa/subcat/{subcatId}/chat

В этом режиме задачи категории отображаются как переписки. Пользовательская логика представления (сортировка по времени последнего сообщения, очистка HTML/Markdown в превью) описана в бизнес-документации и здесь не дублируется.

Категорийные флаги

Настройка Что важно для chat
Представления категории Включает доступность чат-представления в категории
Конфиденциальность категории Ограничивает видимость чата подписчиками
«Не посылать почтовые сообщения» Отключает email из категории групповых чатов; отключение уведомлений отдельного чата на email не влияет

Настройки конкретного чата

Таблица dbo.ChatSettings хранит настройки отдельного чата. Полный список полей и бизнес-ограничений описан в бизнес-документации.

Панель «Информация» чата: название, тип («Открытый»), участники и кнопки добавления, встречи и уведомлений

Группа настроек Поля Что контролирует
Приватность IsPrivate Перенос группового чата между открытой и закрытой категорией
Участники и профиль IsAddSubscribersEnabled, IsEditProfileEnabled, IsSubscribersVisibile Можно ли участникам добавлять подписчиков, менять профиль и видеть список участников
Сообщения IsRootCommentsEnabled, IsThreadsEnabled, IsThreadCommentsEnabled Корневые сообщения и треды
Функции сообщений IsReactionsEnabled, IsMessagePinEnabled, IsAttachmentsEnabled, IsSurveysEnabled, IsVoiceMessagesEnabled, IsStickersEnabled Реакции, закрепление, файлы, опросы, голосовые, стикеры
ВКС IsConferenceEnabled Доступность конференции из чата

Роли хранятся в dbo.ChatRolesUsers и dbo.ChatRolesGroups; модель ролей описана в бизнес-документации.

URL-навигация

Создание нового чата

/spa/chat/new?with={UserID,UserID,...}&name={chat_name}&msg={текст}
/spa/chat/new?with={UserID}&with={UserID}&name={chat_name}&msg={текст}
Параметр Назначение
with ID пользователей-участников; можно передать через запятую или повторить параметр несколько раз
name Название чата
msg В групповом чате подставляется как название создаваемого чата (наравне с name), а не как публикуемое сообщение — на этом построен штатный диалог создания группового чата

Приватный чат с пользователем

/spa/chat/new?with={userId}&private=true&msg={chat_message}
Параметр Назначение
with ID пользователя
private Признак приватного чата
msg Текст, подставляемый в поле ввода созданного чата; не публикуется автоматически — сообщение отправляет пользователь

Уведомления и тикеры

Chat использует общий контур уведомлений:

  • ChatNotificationMode управляет push, непрочитанностью и desktop-уведомлениями конкретного участника;
  • email отключается не на уровне отдельного чата, а настройками категории и пользователя;
  • push для личных и групповых чатов имеет отдельное форматирование.

Правила уведомлений в этом файле не дублируются: административные настройки и диагностика — в администрировании уведомлений, бизнес-правила — в бизнес-документации уведомлений, счётчики и тикеры — в runbook по тикерам.

Аудит и диагностика

Объекты БД

Таблицы и представления, полезные при диагностике чатов:

Объект Назначение
ChatSettings Настройки конкретного чата
ChatRolesUsers, ChatRolesGroups Роли пользователей и групп в чате
ChatAvatars Аватары чатов
Comments, CommentRecipients Сообщения и состояние прочтения
MailSubscribersUsers, MailSubscribersGroups Участники чата
vUserChatUnreadCount, vUserPinnedAndChatUnreadCount Представление непрочитанных чатов
MessageQueue, MessageQueueLog Очереди обработки событий, если проблема связана с доставкой уведомлений

⚠️ ChatSettings не покрывает все сценарии использования мессенджера. Для полного охвата учитывать три источника: Settings.ChatSubcatId, Settings.GroupChatSubCatID и задачи, закреплённые в мессенджере через подписки. Активность сообщений проверяется через Comments и CommentRecipients.

Быстрые проверки

Готовые SQL-запросы для диагностики:

-- Тип системной чат-категории
select
        t.TaskID,
        t.SubcatID,
        case
            when t.SubcatID = (select top 1 cast(v.Value as int) from Settings v where v.[Key] = 'ChatSubcatId') then 'Personal'
            when t.SubcatID = (select top 1 cast(v.Value as int) from Settings v where v.[Key] = 'GroupChatSubCatID') then 'Group'
            else 'Channel/SocialNetwork/CategoryChat'
        end as ChatType
from Tasks t
where t.TaskID = @chatTaskId;

-- Настройки и роли конкретного чата
select *
from ChatSettings
where TaskId = @chatTaskId;

select *
from ChatRolesUsers
where TaskId = @chatTaskId;

select *
from ChatRolesGroups
where TaskId = @chatTaskId;

Для правил комментариев и форматирования см. администрирование комментариев и форматирование текста.

Типичные тикеты

«Не могу добавить подписчика в личном чате»

Добавление подписчика в личном чате — корректное поведение: личный чат (Personal) не поддерживает добавление подписчиков по дизайну. Решение — создать новый групповой чат с нужными участниками.

SQL-диагностика типа чата:

-- Определить тип чата
select t.TaskID, t.SubcatID,
    case
        when t.SubcatID = (select top 1 cast(v.Value as int) from Settings v where v.[Key] = 'ChatSubcatId') then 'Personal'
        when t.SubcatID = (select top 1 cast(v.Value as int) from Settings v where v.[Key] = 'GroupChatSubCatID') then 'Group'
        else 'Channel/SocialNetwork'
    end as ChatType
from Tasks t
where t.TaskID = @chatTaskId;

-- Подписчики чата
select s.UserID, u.FullName, s.IsDeleted, s.CreatedDate
from MailSubscribersUsers s
        join Users u on u.UserID = s.UserID
where s.TaskID = @chatTaskId and s.IsDeleted = cast(0 as bit)
order by s.CreatedDate;

-- Настройки чата
select * from ChatSettings where TaskId = @chatTaskId;

Диагностика папок чатов и ссылок.

-- все ссылки папки, включая отозванные
select ShareId, FolderId, Title, Token, Revoked
from dbo.UserChatFolderShares
where FolderId = @FolderId
order by ShareId;

-- явный набор чатов ссылки (правил наполнения здесь нет)
select ShareId, TaskId
from dbo.UserChatFolderSharePeers
where ShareId = @ShareId
order by TaskId;

-- кто по какой ссылке завёл папку
select ShareId, UserId, FolderId
from dbo.UserChatFolderShareJoins
where UserId = @UserId or FolderId = @FolderId;

-- что взято (Dismissed = 0) и что скрыто как предложение (Dismissed = 1)
select JoinId, TaskId, Dismissed
from dbo.UserChatFolderShareJoinPeers
where JoinId = @JoinId
order by TaskId;

-- папки пользователя
select Id, Title, SortOrder, HideIfEmpty
from dbo.UserChatFolders
where OwnerUserId = @UserId
order by SortOrder;

«Не вижу чат в списке»

Возможные причины:

  1. Пользователь не подписчик чата
  2. Чат закрыт
  3. Чат конфиденциальный, и пользователь не подписчик
  4. Категория чата не попадает под текущий фильтр

«Ссылка на папку не открывается, пишет, что не найдено»

Код 404 одинаков для отозванной ссылки и для несуществующего адреса — отличить их по ответу нельзя. Проверить строку ссылки в dbo.UserChatFolderShares: у неё должен быть Revoked = 0 и совпадающий Token.

«Человек вступил по ссылке, но в его папке нет того чата, что был в ссылке»

Сравнить состав ссылки (dbo.UserChatFolderSharePeers) и то, что получатель забрал (dbo.UserChatFolderShareJoinPeers по его JoinId): разница — чаты без доступа, отказ подписки либо те, что он вышел. Отказ подписки виден в журнале строкой Chat folder join: subscription of user {0} to task {1} was silently rejected.

«У получателя папка, которой он не создавал»

Это нормально: вступление по ссылке создаёт папку получателю. Источник — строка в dbo.UserChatFolderShareJoins по его UserId; там же ShareId и FolderId — по ним видно, из какой ссылки папка взята.

«Чаты в папке, но подписки нет»

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

«Пришли уведомления по чату, который не добавляли»

Вступление по ссылке подписывает на выбранные чаты — так и задумано. Режим уведомлений при этом не меняется, гасится он обычным пунктом «Выключить уведомления».

Связанные документы

Смежные разделы: