# Chat API Documentation ## Обзор Система чата является комплексным решением для обмена сообщениями в CRM системе, поддерживающим множественные провайдеры (WhatsApp, Telegram, Messenger и др.), персональные и групповые чаты, а также интеграцию с сущностями системы. ## Архитектура ### Компоненты системы 1. **Backend (NestJS)** - REST API для управления чатами - WebSocket для real-time сообщений - Интеграция с внешними провайдерами 2. **Frontend (React/TypeScript)** - Веб-интерфейс для управления чатами - Модальные окна и встроенные компоненты 3. **Android приложение** - Мобильный клиент для Android устройств - Полная функциональность чата 4. **База данных** - PostgreSQL с TypeORM - Комплексная схема для чатов, сообщений, пользователей ## Backend API ### Детальная спецификация API #### MultichatController (`/chat`) Основной контроллер для общих операций с чатами. ```typescript @ApiTags('multichat') @Controller('chat') @JwtAuthorized() export class MultichatController { // Получение количества непрочитанных сообщений @Get('unseen-count') async getUnseenCount(): Promise // Обновление статуса сообщений для всех чатов @Put('status/:status') async updateMessagesStatus() } ``` ##### GET /chat/unseen-count **Описание:** Получить общее количество непрочитанных сообщений для текущего пользователя. **Аутентификация:** JWT токен обязательна **Параметры:** Нет **Ответ:** ```json { "statusCode": 200, "data": 5 } ``` ##### PUT /chat/status/{status} **Описание:** Обновить статус всех сообщений во всех чатах пользователя. **Аутентификация:** JWT токен обязательна **Параметры пути:** - `status` (string): Новый статус (received/seen) **Тело запроса:** ```json { "accountId": 1, "user": {...}, "status": "seen" } ``` **Ответ:** ```json { "statusCode": 200, "message": "Messages status updated" } ``` #### ChatController (`/chat/chats`) Контроллер для операций с конкретными чатами. **Создание чатов:** - `POST /personal` - персональный чат - `POST /group` - групповой чат - `POST /external` - внешний чат **Получение чатов:** - `GET /` - список чатов с пагинацией - `GET /find` - простой поиск - `GET /find/full` - полный поиск с дополнительными данными - `GET /find/full/personal` - поиск по имени пользователя - `GET /find/full/by-message-content` - поиск по содержимому сообщений - `GET /:chatId` - получение конкретного чата **Управление чатами:** - `PATCH /group/:chatId` - обновление группового чата - `DELETE /:chatId` - удаление чата - `PUT /:chatId/pin/:messageId` - закрепление сообщения - `PUT /:chatId/unpin/:messageId` - открепление сообщения - `PUT /:chatId/status/:status` - обновление статуса сообщений в чате **Дополнительные операции:** - `POST /:chatId/contact` - создание контакта и лида #### ChatMessageController (`/chat/chats/:chatId/messages`) Контроллер для работы с сообщениями в чате. **Операции с сообщениями:** - `POST /` - отправка сообщения - `GET /` - получение списка сообщений - `GET /:messageId` - получение конкретного сообщения - `PUT /:messageId` - редактирование сообщения - `DELETE /:messageId` - удаление сообщения **Статусы сообщений:** - `POST /status/:status` - обновление статуса нескольких сообщений - `PUT /:messageId/status/:status` - обновление статуса одного сообщения **Реакции:** - `PUT /:messageId/react/:reaction` - добавление реакции - `PUT /:messageId/unreact/:reactionId` - удаление реакции #### ChatProviderController (`/chat/providers`) Контроллер для работы с провайдерами чатов. ```typescript @ApiTags('multichat/providers') @Controller('chat/providers') @JwtAuthorized() export class ChatProviderController { @Get() async findMany(): Promise } ``` ### Модели данных #### Chat (Чат) ```typescript export class ChatDto { id: number; // ID чата providerId: number; // ID провайдера createdBy: number; // ID создателя externalId: string | null; // Внешний ID type: ChatType; // Тип чата (PERSONAL/GROUP) title: string | null; // Название entityId: number | null; // ID связанной сущности createdAt: string; // Дата создания users: ChatUserDto[]; // Пользователи чата pinnedMessages: ChatMessageDto[]; // Закрепленные сообщения lastMessage: ChatMessageDto | null; // Последнее сообщение unseenCount: number; // Количество непрочитанных updatedAt: string; // Дата обновления entityInfo: EntityInfoDto | null; // Информация о сущности hasAccess?: boolean | null; // Доступ пользователя } ``` #### ChatMessage (Сообщение) ```typescript export class ChatMessageDto { id: number; // ID сообщения chatId: number; // ID чата chatUserId: number; // ID пользователя чата text: string | null; // Текст сообщения replyToId: number | null; // ID сообщения-ответа createdAt: string; // Дата создания files: ChatMessageFileDto[]; // Прикрепленные файлы reactions: ChatMessageReactionDto[]; // Реакции status: ChatMessageStatus; // Статус для текущего пользователя } ``` #### ChatUser (Пользователь чата) ```typescript export class ChatUserDto { id: number; // ID в чате chatId: number; // ID чата userId: number | null; // ID пользователя системы role: ChatUserRole; // Роль в чате name: string | null; // Имя avatarUrl: string | null; // URL аватара } ``` #### ChatProvider (Провайдер) ```typescript export class ChatProviderDto { id: number; // ID провайдера type: ChatProviderType; // Тип провайдера title: string; // Название status: ChatProviderStatus; // Статус transport: ChatProviderTransport; // Транспорт unseenCount: number; // Непрочитанные сообщения } ``` ### Статусы и типы #### ChatType ```typescript export enum ChatType { PERSONAL = 'personal', // Персональный чат между двумя пользователями GROUP = 'group' // Групповой чат с множеством участников } ``` #### ChatMessageStatus ```typescript export enum ChatMessageStatus { RECEIVED = 'received', // Сообщение получено SEEN = 'seen' // Сообщение просмотрено } ``` #### ChatProviderType ```typescript export enum ChatProviderType { Amwork = 'amwork', // Внутренняя система Amwork Twilio = 'twilio', // Twilio WhatsApp Facebook = 'facebook', // Facebook Messenger Wazzup = 'wazzup' // Wazzup WhatsApp } ``` #### ChatProviderTransport ```typescript export enum ChatProviderTransport { Amwork = 'amwork', // Внутренняя система Whatsapp = 'whatsapp', // WhatsApp Messenger = 'messenger', // Facebook Messenger Telegram = 'telegram', // Telegram Instagram = 'instagram', // Instagram Vk = 'vk', // VKontakte Avito = 'avito' // Avito } ``` #### ChatProviderStatus ```typescript export enum ChatProviderStatus { Draft = 'draft', // Черновик настройки Active = 'active', // Активен Inactive = 'inactive', // Неактивен Deleted = 'deleted' // Удален } ``` #### ChatUserRole ```typescript export enum ChatUserRole { OWNER = 'owner', // Владелец чата ADMIN = 'admin', // Администратор SUPERVISOR = 'supervisor', // Супервайзер USER = 'user', // Обычный пользователь EXTERNAL = 'external' // Внешний пользователь } ``` ### DTOs для создания чатов #### CreatePersonalChatDto ```typescript export class CreatePersonalChatDto { @ApiProperty({ description: 'Provider ID' }) @IsNumber() providerId: number; @ApiProperty({ description: 'User ID of chat companion' }) @IsNumber() companionId: number; } ``` **Пример запроса:** ```json { "providerId": 1, "companionId": 123 } ``` #### CreateGroupChatDto ```typescript export class CreateGroupChatDto { @ApiProperty({ description: 'Provider ID' }) @IsNumber() providerId: number; @ApiProperty({ description: 'Chat title' }) @IsString() title: string; @ApiProperty({ description: 'User IDs of chat participants', type: [Number] }) @IsArray() participantIds: number[]; @ApiPropertyOptional({ description: 'Entity ID associated with the chat', nullable: true }) @IsOptional() @IsNumber() entityId?: number | null; } ``` **Пример запроса:** ```json { "providerId": 1, "title": "Проект Alpha", "participantIds": [123, 456, 789], "entityId": 1001 } ``` ### DTOs для сообщений #### SendChatMessageDto ```typescript export class SendChatMessageDto { @ApiPropertyOptional() @IsOptional() @IsNumber() replyToId?: number | null; @ApiProperty() @IsString() text: string; @ApiPropertyOptional({ nullable: true }) @IsOptional() @IsArray() fileIds?: string[] | null; } ``` **Пример запроса:** ```json { "text": "Привет, как дела?", "replyToId": 123, "fileIds": ["file_123", "file_456"] } ``` ## База данных ### Основные таблицы #### chat ```sql CREATE TABLE public.chat ( id integer NOT NULL, provider_id integer NOT NULL, created_by integer, external_id character varying, type character varying NOT NULL, title character varying, entity_id integer, account_id integer NOT NULL, created_at timestamp without time zone NOT NULL ); ``` #### chat_message ```sql CREATE TABLE public.chat_message ( id integer NOT NULL, chat_id integer NOT NULL, chat_user_id integer NOT NULL, external_id character varying, text text, account_id integer NOT NULL, created_at timestamp without time zone NOT NULL, reply_to_id integer ); ``` #### chat_user ```sql CREATE TABLE public.chat_user ( id integer NOT NULL, chat_id integer NOT NULL, user_id integer, role character varying NOT NULL, account_id integer NOT NULL ); ``` #### chat_provider ```sql CREATE TABLE public.chat_provider ( id integer NOT NULL, created_by integer, type character varying NOT NULL, title character varying NOT NULL, account_id integer NOT NULL, created_at timestamp without time zone NOT NULL, status character varying NOT NULL, transport character varying NOT NULL ); ``` #### chat_message_reaction ```sql CREATE TABLE public.chat_message_reaction ( id integer NOT NULL, message_id integer NOT NULL, chat_user_id integer NOT NULL, reaction character varying NOT NULL, account_id integer NOT NULL, created_at timestamp without time zone NOT NULL ); ``` #### chat_message_user_status ```sql CREATE TABLE public.chat_message_user_status ( chat_id integer NOT NULL, message_id integer NOT NULL, chat_user_id integer NOT NULL, status character varying NOT NULL, account_id integer NOT NULL, created_at timestamp without time zone NOT NULL ); ``` ## Frontend ### Архитектура компонентов Система чата построена на базе React с использованием контекстов для управления состоянием и кастомных хуков для работы с API. #### MultichatProvider Контекст-провайдер для глобального управления состоянием чата в приложении. **Ключевые свойства:** ```typescript interface MultichatContextValue { // Видимость модальных окон opened: boolean; pageOpened: boolean; hide: () => void; toggle: () => void; // Активный чат activeChatId: number | null; activeProviderId: number | null; setActiveChatId: (id: number | null) => void; setActiveProviderId: (id: number | null) => void; // Управление сообщениями editMessageId: number | null; replyToId: number | null; setEditMessageId: (id: number | null) => void; setReplyToId: (id: number | null) => void; // Навигация show: (params: { activeChatId?: number; activeProviderId?: number }) => void; openPage: (returnUrl?: string) => void; closePage: () => void; } ``` **Использование:** ```tsx const { show, opened, activeChatId } = useMultichatContext(); // Открыть чат show({ activeChatId: 123, activeProviderId: 1 }); // Проверить видимость if (opened) { // Показать модальное окно } ``` #### MultichatModal Модальное окно для отображения интерфейса чата в модальном режиме. **Особенности:** - Перетаскиваемое и изменяемое по размеру - Адаптивный дизайн - Сохранение позиции и размера - Интеграция с основным UI **Props:** ```typescript interface MultichatModalProps { children?: ReactNode; modalBounds?: DraggableResizableControlBounds; setModalBounds?: (bounds: DraggableResizableControlBounds) => void; } ``` #### MultichatControl Основной контейнер управления чатом с боковой панелью и областью сообщений. **Структура:** ``` MultichatControl ├── MultichatControlHeader (при модальном просмотре) ├── ChatsSidebar │ ├── ChatList │ ├── CreateAmworkChatButton │ └── ProviderSelector └── ChatMessagesPanel ├── ChatMessagesPanelHeader ├── ChatMessagesList └── SendChatMessageBlock ``` #### ChatMessagesPanel Компонент для отображения и управления сообщениями в чате. **Ключевые функции:** - Ленивая загрузка сообщений - Автоматическая прокрутка к новым сообщениям - Отметка сообщений как прочитанные - Обработка реакций и ответов **Props:** ```typescript interface ChatMessagesPanelProps { activeChatId: number; mobileView?: boolean; providers?: ChatProvider[]; activeProvider?: ChatProvider; modalWidth?: string; onBack?: () => void; } ``` #### SendChatMessageBlock Компонент для отправки сообщений с поддержкой различных типов контента. **Возможности:** - Текстовые сообщения - Файловые вложения (drag & drop) - Ответы на сообщения - Редактирование сообщений - Отправка через Enter или кнопку **Состояния:** - Обычное сообщение - Ответ на сообщение - Редактирование сообщения - Отправка файла ### Кастомные хуки #### useGetChat Получение данных о конкретном чате. ```typescript const { data: chat, isLoading, error } = useGetChat(chatId); ``` #### useGetChatMessages Получение сообщений чата с пагинацией. ```typescript const { data: messages, hasNextPage, fetchNextPage, isLoading } = useGetChatMessages(chatId); ``` #### useSendChatMessage Отправка сообщений в чат. ```typescript const { mutateAsync: sendMessage, isPending } = useSendChatMessage({ chatId, providerId }); // Отправка await sendMessage({ text: "Привет!", fileIds: ["file_123"] }); ``` #### useCreateGroupChat Создание группового чата. ```typescript const { mutateAsync: createChat } = useCreateGroupChat(); // Создание const newChat = await createChat({ providerId: 1, title: "Новый проект", participantIds: [123, 456] }); ``` ### API интеграция #### ChatApi Основной API клиент для работы с чатами: ```typescript export const chatApi = { // Получение чатов getChats: (params: CursorPagingQuery) => api.get('/chat/chats', { params }), getChat: (chatId: number) => api.get(`/chat/chats/${chatId}`), // Создание чатов createPersonalChat: (data: CreatePersonalChatDto) => api.post('/chat/chats/personal', data), createGroupChat: (data: CreateGroupChatDto) => api.post('/chat/chats/group', data), createExternalChat: (data: CreateExternalChatDto) => api.post('/chat/chats/external', data), // Поиск чатов findChats: (params: { filter: ChatFindFilterDto; paging: PagingQuery }) => api.get('/chat/chats/find', { params }), findChatsFull: (params: { filter: ChatFindFilterDto; paging: PagingQuery }) => api.get('/chat/chats/find/full', { params }), // Сообщения getChatMessages: (chatId: number, params: ChatMessagesFilterDto & PagingQuery) => api.get(`/chat/chats/${chatId}/messages`, { params }), sendMessage: (chatId: number, data: SendChatMessageDto) => api.post(`/chat/chats/${chatId}/messages`, data), updateMessage: (chatId: number, messageId: number, data: SendChatMessageDto) => api.put(`/chat/chats/${chatId}/messages/${messageId}`, data), deleteMessage: (chatId: number, messageId: number) => api.delete(`/chat/chats/${chatId}/messages/${messageId}`), // Статусы markAllChatMessagesAsRead: (chatId: number) => api.put(`/chat/chats/${chatId}/status/read`), updateMessageStatus: (chatId: number, messageId: number, status: ChatMessageStatus) => api.put(`/chat/chats/${chatId}/messages/${messageId}/status/${status}`), // Реакции reactToMessage: (chatId: number, messageId: number, reaction: string) => api.put(`/chat/chats/${chatId}/messages/${messageId}/react/${reaction}`), unreactToMessage: (chatId: number, messageId: number, reactionId: number) => api.put(`/chat/chats/${chatId}/messages/${messageId}/unreact/${reactionId}`), // Управление чатами updateGroupChat: (chatId: number, data: UpdateGroupChatDto) => api.patch(`/chat/chats/group/${chatId}`, data), deleteChat: (chatId: number) => api.delete(`/chat/chats/${chatId}`), pinMessage: (chatId: number, messageId: number) => api.put(`/chat/chats/${chatId}/pin/${messageId}`), unpinMessage: (chatId: number, messageId: number) => api.put(`/chat/chats/${chatId}/unpin/${messageId}`), // Провайдеры getChatProviders: () => api.get('/chat/providers'), // Счетчики getUnseenCount: () => api.get('/chat/unseen-count'), }; ``` ### React Query интеграция Система использует React Query для кеширования и синхронизации данных: ```typescript // Ключи запросов export const MULTICHAT_QUERY_KEYS = { chats: ['multichat', 'chats'] as const, chat: (chatId: number) => ['multichat', 'chats', chatId] as const, chatMessages: (chatId: number) => ['multichat', 'chats', chatId, 'messages'] as const, chatProviders: ['multichat', 'providers'] as const, unseenCount: ['multichat', 'unseen-count'] as const, } as const; // Инвалидация кеша queryClient.invalidateQueries({ queryKey: MULTICHAT_QUERY_KEYS.chats }); ``` ### Стилизация Компоненты используют styled-components с поддержкой тем: ```typescript const Root = styled.div` background-color: var(--graphite-graphite-20); border-radius: 8px; ${p => p.$mobileView && css` width: calc(100vw - var(--sidebar-width)); `} `; ``` ### Обработка событий Система поддерживает real-time обновления через WebSocket события: ```typescript // Обработчик событий чата const chatEventHandler = { subscribe: (context: MultichatContextValue) => { // Подписка на события }, unsubscribe: () => { // Отписка от событий } }; ``` ## Android приложение ### Архитектура Приложение построено на базе **MVVM** архитектуры с использованием **Android Architecture Components**: - **Activities/Fragments** - представление данных - **ViewModels** - бизнес-логика и управление состоянием - **Repositories** - абстракция доступа к данным - **Retrofit** - HTTP клиент для API - **Room** - локальная база данных (опционально) - **WorkManager** - фоновая синхронизация ### Основные Activity #### ChatActivity Основная активность для отображения чата с полным жизненным циклом управления. **Жизненный цикл:** ```kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityChatBinding.inflate(layoutInflater) setContentView(binding.root) // Инициализация ViewModel viewModel.initialize(serverUrl, token, apiKey, chatId) // Настройка UI компонентов setupViews() observeViewModel() observeAddressBook() } override fun onResume() { super.onResume() viewModel.setChatActive(true) // Активация чата } override fun onPause() { super.onPause() viewModel.setChatActive(false) // Деактивация чата } ``` **Основные функции:** - Отображение списка сообщений с `RecyclerView` - Отправка текстовых сообщений - Отправка файлов через `FilePicker` - Ответы на сообщения с визуальным индикатором - Автоматическая отметка сообщений как прочитанные при прокрутке - Управление прикрепленными файлами **Ключевые компоненты:** - `MessageAdapter` - адаптер для `RecyclerView` с поддержкой разных типов сообщений - `ChatViewModel` - управление состоянием чата и бизнес-логикой - `NotificationHelper` - обработка push-уведомлений - `BackgroundSyncWorker` - фоновая синхронизация #### MainActivity Главная активность с навигацией и списком чатов. **Особенности:** - `BottomNavigationView` для переключения разделов - `SwipeRefreshLayout` для обновления списка чатов - `FloatingActionButton` для создания новых чатов - Управление жизненным циклом всех чатов #### CreateChatActivity Активность для создания новых чатов с пошаговым мастером. **Этапы создания:** 1. Выбор типа чата (персональный/групповой) 2. Выбор участников через `UserSelectionActivity` 3. Настройка параметров чата 4. Создание и переход к чату ### ViewModels #### ChatViewModel Управляет состоянием конкретного чата и сообщениями. **Состояния:** ```kotlin sealed class ChatState { object Loading : ChatState() data class Success(val chat: Chat) : ChatState() data class Error(val message: String) : ChatState() } sealed class MessagesState { object Loading : MessagesState() data class Success(val messages: List) : MessagesState() data class Error(val message: String) : MessagesState() } sealed class SendMessageState { object Loading : SendMessageState() object Success : SendMessageState() data class Error(val message: String) : SendMessageState() } ``` **Ключевые методы:** ```kotlin // Загрузка данных чата fun refreshChat() // Загрузка сообщений fun refreshMessages() // Отправка сообщения fun sendMessage(text: String, replyToMessage: ChatMessage?, fileIds: List? = null) // Отправка файла fun sendFileMessage(uri: Uri, contentResolver: ContentResolver) // Отметка как прочитанное fun markMessagesAsRead() // Управление активностью чата fun setChatActive(active: Boolean) ``` #### MainViewModel Глобальная ViewModel для управления приложением. **Функции:** - Управление списком чатов - Кеширование данных пользователей (адресная книга) - Синхронизация состояния между активностями - Управление подключением к серверу **Ключевые методы:** ```kotlin // Получение имени пользователя fun getUserName(userId: Long): String // Получение URL аватара fun getUserAvatarUrl(userId: Long): String? // Уведомление об обновлении чата fun notifyChatUpdated(chatId: Long) // Управление адресной книгой fun refreshAddressBook() ``` ### Репозитории #### ChatRepository Репозиторий для работы с API чатов с поддержкой кеширования. **Основные методы:** ```kotlin suspend fun getChats(): Result> suspend fun getChat(chatId: Long): Result suspend fun getMessages(chatId: Long, limit: Int = 50, offset: Long? = null): Result> suspend fun sendMessage(chatId: Long, message: SendChatMessageDto): Result suspend fun uploadFile(uri: Uri, contentResolver: ContentResolver): Result> suspend fun markAsRead(chatId: Long): Result suspend fun updateMessageStatus(chatId: Long, messageId: Long, status: ChatMessageStatus): Result ``` **Обработка ошибок:** ```kotlin sealed class Result { data class Success(val data: T) : Result() data class Failure(val exception: Throwable) : Result() } ``` ### Модели данных #### ChatRequests.kt DTO для запросов к API: ```kotlin data class CreatePersonalChatRequest( val providerId: Long, val companionId: Long ) data class CreateGroupChatRequest( val providerId: Long, val title: String, val participantIds: List, val entityId: Long? = null ) data class UpdateGroupChatRequest( val title: String? = null, val participantIds: List? = null ) ``` #### ChatModels.kt Основные модели данных приложения: ```kotlin data class Chat( val id: Long, val providerId: Long, val type: String, val title: String?, val users: List, val lastMessage: ChatMessage?, val unseenCount: Int, val createdAt: String ) data class ChatMessage( val id: Long, val chatId: Long, val chatUserId: Long, val text: String?, val replyToId: Long?, val files: List, val reactions: List, val status: ChatMessageStatus, val createdAt: String ) data class ChatUserItem( val id: Long, val userId: Long?, val name: String?, val avatarUrl: String? ) ``` ### UI Компоненты #### MessageAdapter Адаптер для отображения сообщений в `RecyclerView`. **Типы ViewHolder:** - `TextMessageViewHolder` - текстовые сообщения - `FileMessageViewHolder` - сообщения с файлами - `ReplyMessageViewHolder` - ответы на сообщения - `SystemMessageViewHolder` - системные сообщения **Особенности:** - Поддержка разных типов сообщений через `getItemViewType()` - Оптимизация производительности с `DiffUtil` - Обработка кликов и долгого нажатия - Анимации для новых сообщений #### MessageAdapter.kt ```kotlin class MessageAdapter( private val getUserName: (Long) -> String, private val chatUsers: List?, private val onScrollToMessage: (Long) -> Unit, private val onReplyToMessage: (ChatMessage) -> Unit, private val serverUrl: String, private val token: String?, private val apiKey: String? ) : RecyclerView.Adapter() { private val messages = mutableListOf() fun submitList(newMessages: List) { val diffResult = DiffUtil.calculateDiff(MessageDiffCallback(messages, newMessages)) messages.clear() messages.addAll(newMessages) diffResult.dispatchUpdatesTo(this) } } ``` ### Background Sync #### BackgroundSyncWorker Worker для фоновой синхронизации данных. **Функции:** - Периодическая проверка новых сообщений - Обновление уведомлений - Синхронизация аватаров пользователей - Обработка оффлайн режима **Конфигурация:** ```kotlin val syncWork = PeriodicWorkRequestBuilder( 15, TimeUnit.MINUTES // Синхронизация каждые 15 минут ) .addConstraints( Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() ) .build() ``` ### Уведомления #### NotificationHelper Управление push-уведомлениями и локальными уведомлениями. **Функции:** - Создание уведомлений о новых сообщениях - Группировка уведомлений по чатам - Кастомные звуки и вибрация - Deep linking в конкретные чаты ```kotlin fun showMessageNotification( chatId: Long, message: ChatMessage, senderName: String, chatTitle: String ) { val intent = Intent(context, ChatActivity::class.java).apply { putExtra("chat_id", chatId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent = PendingIntent.getActivity( context, chatId.toInt(), intent, PendingIntent.FLAG_IMMUTABLE ) val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(chatTitle) .setContentText("$senderName: ${message.text}") .setContentIntent(pendingIntent) .setAutoCancel(true) .build() notificationManager.notify(chatId.toInt(), notification) } ``` ### Работа с файлами #### File Handling Обработка загрузки и отображения файлов. **Поддерживаемые операции:** - Выбор файлов через `Intent.ACTION_GET_CONTENT` - Загрузка файлов на сервер - Отображение превью изображений - Скачивание файлов - Управление разрешениями на хранение ```kotlin private fun uploadFileAndSendMessage(message: String) { selectedFileUri?.let { uri -> lifecycleScope.launch { try { val result = ChatRepository(apiClient).uploadFile(uri, contentResolver) result.fold( onSuccess = { files -> viewModel.sendMessage(message, replyingToMessage, files.map { it.id }) clearFileSelection() }, onFailure = { error -> Toast.makeText(this@ChatActivity, "Upload failed: ${error.message}", Toast.LENGTH_SHORT).show() } ) } catch (e: Exception) { Toast.makeText(this@ChatActivity, "Error: ${e.message}", Toast.LENGTH_SHORT).show() } } } } ``` ### Темизация и локализация **Поддержка тем:** - Светлая тема - Темная тема - Системная тема **Локализация:** - Русский язык - Английский язык - Поддержка RTL для арабского и иврита ### Производительность **Оптимизации:** - ViewBinding вместо findViewById - DiffUtil для RecyclerView - Кеширование изображений с Glide - Пейджинг для больших списков - Background threading для тяжелых операций ## Интеграция с внешними провайдерами ### Поддерживаемые провайдеры 1. **Facebook Messenger** - Требует: `page_id`, `page_access_token`, `user_access_token` - Транспорт: `messenger` 2. **Telegram** - Интеграция через Telegram API 3. **WhatsApp (Twilio)** - Требует: `account_sid`, `auth_token`, `phone_number` - Транспорт: `whatsapp` 4. **Whazzup** - Требует: `api_key`, `channel_id`, `plain_id` - Транспорт: `whatsapp` ### Настройка провайдеров Провайдеры настраиваются через интерфейс интеграций в разделе "Settings > Integrations". ## Безопасность ### Аутентификация - JWT токены для API запросов - Проверка прав доступа на уровне аккаунта - Валидация принадлежности пользователя к чату ### Авторизация - Проверка доступа к чатам - Ролевая модель для групповых чатов - Ограничение действий с сообщениями ## Real-time обновления ### WebSocket - Автоматическое обновление сообщений - Статусы прочтения в реальном времени - Уведомления о новых сообщениях ### Background Sync (Android) - `BackgroundSyncWorker` для синхронизации в фоне - Обновление уведомлений - Синхронизация аватаров пользователей ## Файловые вложения ### Поддерживаемые форматы - Изображения, документы, видео, аудио - Максимальный размер файла настраивается ### Загрузка файлов - Backend: хранение в файловом хранилище - Frontend: drag & drop, выбор файла - Android: выбор из галереи/файлового менеджера ### Безопасность файлов - Валидация MIME типов - Сканирование на вирусы (опционально) - Ограничение доступа по ссылкам ## Поиск и фильтрация ### Поиск чатов - По имени пользователя (персональные чаты) - По содержимому сообщений - По связанным сущностям - Фильтрация по провайдеру ### Полнотекстовый поиск - Индексы в базе данных - Поиск по тексту сообщений - Поддержка регулярных выражений ## Мониторинг и логирование ### Метрики - Количество активных чатов - Статистика сообщений - Производительность API ### Логи - Детальное логирование API запросов - Ошибки интеграции с провайдерами - Аудит действий пользователей ## Расширение системы ### Добавление нового провайдера 1. Создать конфигурацию провайдера в базе данных 2. Реализовать интеграцию в `ChatProviderService` 3. Добавить DTO для настроек 4. Создать миграцию для новой таблицы провайдера 5. Обновить UI для настройки ### Кастомизация UI - Темизация компонентов - Кастомные аватары - Дополнительные поля в сообщениях ## Заключение Система чата предоставляет полнофункциональное решение для коммуникации в CRM, поддерживая множественные каналы связи, real-time обновления и интеграцию с бизнес-логикой системы. Архитектура обеспечивает масштабируемость, безопасность и гибкость для будущих расширений.