Улучшена групповая отправка уведомлений
* Отправка только последнего уведомления пользователю по задаче * Предотвращены отправки сообщений самому себе
This commit is contained in:
parent
5140e5a442
commit
d9cfb523b9
3 changed files with 70 additions and 14 deletions
|
|
@ -104,20 +104,8 @@ export class AppModule implements OnModuleInit {
|
|||
);
|
||||
this.personalNotificationAdapterService.send(resp);
|
||||
});
|
||||
this.statusChangeNotificationsService.$changes.subscribe((change) => {
|
||||
const messages = change.messages
|
||||
.map((m) => m.change_message)
|
||||
.filter((m) => !!m);
|
||||
const notifications = change.messages
|
||||
.map((m) => m.notification_message)
|
||||
.filter((m) => !!m);
|
||||
this.logger.log(
|
||||
`Get status changes messages for ` +
|
||||
`issue_id = ${change.issue_id}, ` +
|
||||
`messages = ${JSON.stringify(messages)}, ` +
|
||||
`notifications = ${JSON.stringify(notifications)}`,
|
||||
);
|
||||
this.statusChangeAdapterService.send(change);
|
||||
this.statusChangeNotificationsService.$batchChanges.subscribe((changes) => {
|
||||
this.statusChangeAdapterService.batchSend(changes);
|
||||
});
|
||||
|
||||
this.redmineIssuesCacheWriterService.subject
|
||||
|
|
|
|||
|
|
@ -1,7 +1,20 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
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 {
|
||||
constructor(private telegramBotService: TelegramBotService) {}
|
||||
|
|
@ -19,4 +32,57 @@ export class StatusChangeAdapterService {
|
|||
});
|
||||
return await Promise.all(promises);
|
||||
}
|
||||
|
||||
async batchSend(changes: Change[]): Promise<void> {
|
||||
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<string, StatusChangeAdapter.MsgFromBatch> = {};
|
||||
for (let i = 0; i < changes.length; i++) {
|
||||
const change = changes[i];
|
||||
for (let j = 0; j < change.messages.length; j++) {
|
||||
const message = change.messages[j];
|
||||
if (!message.change_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.change_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}`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export class StatusChangeNotificationsService {
|
|||
private statusChanges: StatusChangesConfig.Config;
|
||||
|
||||
$changes = new Subject<Change>();
|
||||
$batchChanges = new Subject<Change[]>();
|
||||
|
||||
constructor(
|
||||
private usersService: UsersService,
|
||||
|
|
@ -68,6 +69,7 @@ export class StatusChangeNotificationsService {
|
|||
);
|
||||
|
||||
changes.forEach((c) => this.$changes.next(c));
|
||||
this.$batchChanges.next(changes);
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue