import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import TelegramBot from 'node-telegram-bot-api'; import { Change } from 'src/models/change.model'; import { TelegramBotService } from 'src/telegram-bot/telegram-bot.service'; // eslint-disable-next-line @typescript-eslint/no-namespace namespace StatusChangeAdapter { export type MsgFromBatch = { initiatorId: number; recipientId: number; issueId: number; createdAt: number; msg: string; options?: TelegramBot.SendMessageOptions; }; } @Injectable() export class StatusChangeAdapterService { private periodValidityNotification: number; constructor( private telegramBotService: TelegramBotService, private configService: ConfigService, ) { this.periodValidityNotification = this.configService.get( 'periodValidityNotification', ); } // TODO: Удалить устаревший метод send /** * @deprecated * @see StatusChangeAdapterService.batchSend */ async send(change: Change): Promise { const promises = change.messages.map((m) => { if (!m || !m.recipient || !m.recipient.id || !m.notification_message) { return true; } return this.telegramBotService.sendMessageByRedmineId( m.recipient.id, m.notification_message, { parse_mode: 'HTML' }, ); }); return await Promise.all(promises); } async batchSend(changes: Change[]): Promise { const messages = this.getMessages(changes).map((item) => { item.options = { parse_mode: 'HTML' }; return item; }); for (let i = 0; i < messages.length; i++) { const message = messages[i]; await this.telegramBotService.sendMessageByRedmineId( message.recipientId, message.msg, message.options, ); } } private getMessages(changes: Change[]): StatusChangeAdapter.MsgFromBatch[] { const res: StatusChangeAdapter.MsgFromBatch[] = []; const store: Record = {}; const nowTimestamp = new Date().getTime(); for (let i = 0; i < changes.length; i++) { const change = changes[i]; if ( nowTimestamp - change.created_on_timestamp > this.periodValidityNotification ) { continue; } for (let j = 0; j < change.messages.length; j++) { const message = change.messages[j]; if (!message.notification_message) continue; if (change.initiator.id == message.recipient.id) continue; const item: StatusChangeAdapter.MsgFromBatch = { initiatorId: change.initiator.id, recipientId: message.recipient.id, createdAt: change.created_on_timestamp, issueId: change.issue_id, msg: message.notification_message, }; const key = this.keyForMsgFromBatch(item); if ( !store[key] || (store[key] && store[key].createdAt < item.createdAt) ) { store[key] = item; } } } for (const key in store) { if (Object.prototype.hasOwnProperty.call(store, key)) { const item = store[key]; res.push(item); } } return res; } private keyForMsgFromBatch(item: StatusChangeAdapter.MsgFromBatch): string { return `${item.issueId}-${item.recipientId}`; } }