chore: add unread event for webscoket
This commit is contained in:
@@ -134,6 +134,12 @@ export class EmailGateway implements OnGatewayInit, OnGatewayConnection, OnGatew
|
|||||||
async notifyEmailRead(userId: string, data: EmailStatusPayload) {
|
async notifyEmailRead(userId: string, data: EmailStatusPayload) {
|
||||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_READ, data, `Message ${data.messageId} marked as read`);
|
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_READ, data, `Message ${data.messageId} marked as read`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//************************************************************************ */
|
||||||
|
async notifyEmailUnread(userId: string, data: EmailStatusPayload) {
|
||||||
|
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_UNREAD, data, `Message ${data.messageId} marked as unread`);
|
||||||
|
}
|
||||||
|
|
||||||
//************************************************************************ */
|
//************************************************************************ */
|
||||||
async notifyEmailDeleted(userId: string, data: EmailDeletePayload) {
|
async notifyEmailDeleted(userId: string, data: EmailDeletePayload) {
|
||||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_DELETED, data, `Message ${data.messageId} deleted`);
|
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_DELETED, data, `Message ${data.messageId} deleted`);
|
||||||
|
|||||||
@@ -58,6 +58,41 @@ export class EmailNotificationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//************************************************************************ */
|
||||||
|
async notifyEmailUnread(params: EmailStatusNotificationParams) {
|
||||||
|
try {
|
||||||
|
const em = this.em.fork();
|
||||||
|
const user = await em.findOne(User, {
|
||||||
|
wildduckUserId: params.userId,
|
||||||
|
emailEnabled: true,
|
||||||
|
deletedAt: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
this.logger.warn(`User not found with wildduckUserId: ${params.userId}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload: EmailStatusPayload = {
|
||||||
|
userId: user.id,
|
||||||
|
messageId: params.messageId,
|
||||||
|
mailboxId: params.mailboxId,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const success = await this.emailGateway.notifyEmailUnread(user.id, payload);
|
||||||
|
await this.updateUnreadCount(params.userId);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
this.logger.log(`Email unread notification dispatched for user ${user.id}: message ${params.messageId}`);
|
||||||
|
} else {
|
||||||
|
this.logger.warn(`Failed to dispatch email unread notification for user ${user.id}: user not connected`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Failed to notify email unread for user ${params.userId}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//************************************************************************ */
|
//************************************************************************ */
|
||||||
async notifyEmailRead(params: EmailStatusNotificationParams) {
|
async notifyEmailRead(params: EmailStatusNotificationParams) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -237,6 +237,11 @@ export class EmailService {
|
|||||||
async markMessageAsUnseen(wildduckUserId: string, messageId: number, mailboxId: string) {
|
async markMessageAsUnseen(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||||
const { updated } = await firstValueFrom(this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, { seen: false }));
|
const { updated } = await firstValueFrom(this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, { seen: false }));
|
||||||
|
|
||||||
|
await this.emailNotificationService.notifyEmailUnread({
|
||||||
|
userId: wildduckUserId,
|
||||||
|
messageId,
|
||||||
|
mailboxId,
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: EmailMessage.MESSAGE_MARKED_AS_UNSEEN_SUCCESSFULLY,
|
message: EmailMessage.MESSAGE_MARKED_AS_UNSEEN_SUCCESSFULLY,
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ export class MailboxService {
|
|||||||
|
|
||||||
constructor(private readonly mailServerService: MailServerService) {}
|
constructor(private readonly mailServerService: MailServerService) {}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* List all mailboxes for a user
|
|
||||||
*/
|
|
||||||
listMailboxes(userId: string, query?: MailboxQueryDto): Observable<any[]> {
|
listMailboxes(userId: string, query?: MailboxQueryDto): Observable<any[]> {
|
||||||
this.logger.log(`Listing mailboxes for user: ${userId}`);
|
this.logger.log(`Listing mailboxes for user: ${userId}`);
|
||||||
|
|
||||||
@@ -29,50 +27,27 @@ export class MailboxService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* Get mailbox message counts for a user
|
|
||||||
*/
|
|
||||||
getMailboxCounts(userId: string) {
|
getMailboxCounts(userId: string) {
|
||||||
this.logger.log(`Getting mailbox counts for user: ${userId}`);
|
|
||||||
|
|
||||||
return this.mailServerService.mailboxes.listMailboxes(userId, { counters: true }).pipe(
|
return this.mailServerService.mailboxes.listMailboxes(userId, { counters: true }).pipe(
|
||||||
map((response) => {
|
map((response) => {
|
||||||
this.logger.log(`Found ${response.results.length} mailboxes with counts for user: ${userId}`);
|
|
||||||
|
|
||||||
const mailboxes = response.results.map((mailbox) => ({
|
const mailboxes = response.results.map((mailbox) => ({
|
||||||
id: mailbox.id,
|
id: mailbox.id,
|
||||||
name: mailbox.name,
|
name: mailbox.name,
|
||||||
path: mailbox.path,
|
|
||||||
specialUse: mailbox.specialUse,
|
|
||||||
total: mailbox.total || 0,
|
|
||||||
unseen: mailbox.unseen || 0,
|
unseen: mailbox.unseen || 0,
|
||||||
size: mailbox.size || 0,
|
total: mailbox.total || 0,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const totalMailboxes = mailboxes.length;
|
return { mailboxes };
|
||||||
const totalMessages = mailboxes.reduce((sum, mailbox) => sum + mailbox.total, 0);
|
|
||||||
const totalUnseen = mailboxes.reduce((sum, mailbox) => sum + mailbox.unseen, 0);
|
|
||||||
const totalSize = mailboxes.reduce((sum, mailbox) => sum + mailbox.size, 0);
|
|
||||||
|
|
||||||
return {
|
|
||||||
mailboxes,
|
|
||||||
totalMailboxes,
|
|
||||||
totalMessages,
|
|
||||||
totalUnseen,
|
|
||||||
totalSize,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
catchError((error) => {
|
catchError((error) => {
|
||||||
this.logger.error(`Failed to get mailbox counts for user ${userId}: ${error.message}`);
|
|
||||||
return throwError(() => error);
|
return throwError(() => error);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* Get a specific mailbox
|
getMailbox(userId: string, mailboxId: string) {
|
||||||
*/
|
|
||||||
getMailbox(userId: string, mailboxId: string): Observable<any> {
|
|
||||||
this.logger.log(`Getting mailbox ${mailboxId} for user: ${userId}`);
|
this.logger.log(`Getting mailbox ${mailboxId} for user: ${userId}`);
|
||||||
|
|
||||||
return this.mailServerService.mailboxes.getMailbox(userId, mailboxId).pipe(
|
return this.mailServerService.mailboxes.getMailbox(userId, mailboxId).pipe(
|
||||||
@@ -90,9 +65,7 @@ export class MailboxService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* Create a new mailbox
|
|
||||||
*/
|
|
||||||
createMailbox(userId: string, createMailboxDto: CreateMailboxDto): Observable<any> {
|
createMailbox(userId: string, createMailboxDto: CreateMailboxDto): Observable<any> {
|
||||||
this.logger.log(`Creating mailbox "${createMailboxDto.path}" for user: ${userId}`);
|
this.logger.log(`Creating mailbox "${createMailboxDto.path}" for user: ${userId}`);
|
||||||
|
|
||||||
@@ -108,9 +81,7 @@ export class MailboxService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* Update a mailbox
|
|
||||||
*/
|
|
||||||
updateMailbox(userId: string, mailboxId: string, updateMailboxDto: UpdateMailboxDto): Observable<any> {
|
updateMailbox(userId: string, mailboxId: string, updateMailboxDto: UpdateMailboxDto): Observable<any> {
|
||||||
this.logger.log(`Updating mailbox ${mailboxId} for user: ${userId}`);
|
this.logger.log(`Updating mailbox ${mailboxId} for user: ${userId}`);
|
||||||
|
|
||||||
@@ -129,9 +100,7 @@ export class MailboxService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//########################################################
|
||||||
* Delete a mailbox
|
|
||||||
*/
|
|
||||||
deleteMailbox(userId: string, mailboxId: string): Observable<any> {
|
deleteMailbox(userId: string, mailboxId: string): Observable<any> {
|
||||||
this.logger.log(`Deleting mailbox ${mailboxId} for user: ${userId}`);
|
this.logger.log(`Deleting mailbox ${mailboxId} for user: ${userId}`);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user