Files
request-portal/src/webparts/requestPortal/shared/chat/chatNotify.ts
T
gorbenko.pavel 2bcfb9f6f4
Tests / frontend-test (pull_request) Failing after 28s
feat: в письме о сообщении чата — строка «Прикреплены файлы: …»
Иначе сообщение из одного файла приходило письмом с пустым текстом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:36:39 +05:00

84 lines
3.9 KiB
TypeScript

import { IChatParticipant, extractMentionedEmails } from './chatMentions';
/**
* Тело запроса к потоку оповещения о сообщении в чате (FLOW_CHAT_NOTIFY_URL).
* Контракт потока: все поля — строки, кроме mentionedEmails; никого не
* отметили — пустой массив, а не null и не пропущенное поле.
*/
export interface IChatNotifyBody {
initiatorEmail: string;
mentionedEmails: string[];
authorName: string;
messageText: string;
RequestUniqueCode: string;
requestUrl: string;
requestTitle: string;
}
export interface IChatNotifyInput {
/** Инициатор заявки (автор строки списка данных). */
initiatorEmail: string;
/** Кого можно было отметить — по ним ищутся «@ФИО» в тексте. */
participants: IChatParticipant[];
authorName: string;
authorEmail: string;
messageText: string;
/** Имена приложенных файлов, как их выбрал пользователь (без складского префикса). */
fileNames?: string[];
requestCode: string;
requestUrl: string;
requestTitle: string;
/** Режим проверки (свойство веб-части chatSelfNotify): письма и о своих сообщениях. */
selfNotify: boolean;
}
const sameEmail = (a: string, b: string): boolean => a.toLowerCase() === b.toLowerCase();
/**
* Текст для письма: сообщение и строка о файлах. Без неё сообщение из одного
* файла пришло бы письмом с пустым текстом. Сами файлы в письмо не кладём —
* они в библиотеке, открываются по ссылке на заявку.
*/
function letterText(text: string, fileNames: string[]): string {
if (fileNames.length === 0) return text;
const files = `Прикреплены файлы: ${fileNames.join(', ')}`;
return text ? `${text}\n\n${files}` : files;
}
/**
* Собрать тело запроса к потоку или undefined, если писать некому.
*
* Поток шлёт инициатору письмо ВСЕГДА, когда его нет среди отмеченных. Значит,
* когда пишет сам инициатор (а режим проверки выключен), письмо «новое сообщение
* по вашей заявке» ушло бы ему же. Отключить его в контракте потока нечем,
* поэтому:
* — никого не отметил → поток не вызываем вовсе;
* — кого-то отметил → в initiatorEmail кладём первого отмеченного: по
* контракту отмеченный инициатор получает только «Вас упомянули», и
* лишнего письма никому не уходит.
*/
export function buildChatNotifyBody(input: IChatNotifyInput): IChatNotifyBody | undefined {
const mentioned = extractMentionedEmails(input.messageText, input.participants).filter(
(email) => input.selfNotify || !sameEmail(email, input.authorEmail)
);
let initiatorEmail = input.initiatorEmail;
const authorIsInitiator =
!!initiatorEmail && !!input.authorEmail && sameEmail(initiatorEmail, input.authorEmail);
if (authorIsInitiator && !input.selfNotify) {
if (mentioned.length === 0) return undefined;
initiatorEmail = mentioned[0];
}
if (!initiatorEmail && mentioned.length === 0) return undefined;
return {
initiatorEmail,
mentionedEmails: mentioned,
authorName: input.authorName,
messageText: letterText(input.messageText, input.fileNames || []),
RequestUniqueCode: input.requestCode,
requestUrl: input.requestUrl,
requestTitle: input.requestTitle
};
}