chore: remove webhook system

This commit is contained in:
mahyargdz
2025-07-29 15:52:03 +03:30
parent 3bf158c433
commit 5315fae914
15 changed files with 837 additions and 746 deletions
@@ -0,0 +1,160 @@
import { Processor } from "@nestjs/bullmq";
import { Logger } from "@nestjs/common";
import { Job } from "bullmq";
import { firstValueFrom } from "rxjs";
import { WorkerProcessor } from "../../../common/queues/worker.processor";
import { EMAIL_QUEUE_CONSTANTS } from "../../email/constants/email-events.constant";
import { UserMailboxIds } from "../../email/interfaces/user-mailbox.interface";
import { EmailGateway } from "../../email-gateway/email.gateway";
import { MailServerService } from "../../mail-server/services/mail-server.service";
import { EmailPollingJobData } from "../interfaces/email-polling-job.interface";
import { MailboxResolverService } from "../services/mailbox-resolver.service";
@Processor(EMAIL_QUEUE_CONSTANTS.EMAIL_POLLING_QUEUE)
export class EmailPollingProcessor extends WorkerProcessor {
protected readonly logger = new Logger(EmailPollingProcessor.name);
constructor(
private readonly emailGateway: EmailGateway,
private readonly mailboxResolverService: MailboxResolverService,
private readonly mailServerService: MailServerService,
) {
super();
}
async process(job: Job<EmailPollingJobData>): Promise<void> {
const { userId, lastCheckTimestamp, connectionId } = job.data;
this.logger.debug(`Processing email polling job for user ${userId} (connection: ${connectionId})`);
try {
// Check if user is still connected before processing
if (!this.emailGateway.isUserConnected(userId)) {
this.logger.debug(`User ${userId} no longer connected, skipping email check`);
return;
}
// Get user's mailbox information
const mailboxIds = await this.mailboxResolverService.getUserMailboxIds(userId);
if (!mailboxIds.inbox) {
this.logger.warn(`No inbox found for user ${userId}`);
return;
}
// Calculate time range for checking new emails
const checkSince = lastCheckTimestamp ? new Date(lastCheckTimestamp) : new Date(Date.now() - 5 * 60 * 1000);
const now = new Date();
this.logger.debug(`Checking emails for user ${userId} since ${checkSince.toISOString()}`);
// Get new emails from inbox since last check
const newEmails = await this.getRecentEmails(userId, mailboxIds.inbox, checkSince);
if (newEmails.length > 0) {
this.logger.log(`Found ${newEmails.length} new emails for user ${userId}`);
// Notify user of each new email via websocket
const lastEmail = newEmails[newEmails.length - 1];
await this.emailGateway.notifyNewEmail(userId, {
wildduckUserId: userId,
messageId: lastEmail.id,
date: lastEmail.date || new Date().toISOString(),
from: lastEmail.from,
to: lastEmail.to || [],
subject: lastEmail.subject,
userId,
timestamp: lastEmail.date || new Date().toISOString(),
mailboxId: lastEmail.mailbox,
mailboxName: "Inbox",
isRead: !!lastEmail.seen,
hasAttachments: !!(lastEmail.attachments && Array.isArray(lastEmail.attachments) && lastEmail.attachments.length > 0),
});
// Update unread count
const unreadStats = await this.getUnreadCounts(userId, mailboxIds);
await this.emailGateway.notifyUnreadCountUpdate(userId, {
userId,
totalUnread: unreadStats.total,
mailboxCounts: unreadStats.mailboxCounts,
count: unreadStats.total,
timestamp: now.toISOString(),
});
this.logger.log(`Notified user ${userId} of ${newEmails.length} new emails`);
} else {
this.logger.debug(`No new emails found for user ${userId}`);
}
// Update job data with new timestamp for next run
job.updateData({
...job.data,
lastCheckTimestamp: now.toISOString(),
});
} catch (error) {
this.logger.error(`Error processing email polling job for user ${userId}:`, error);
throw error; // Re-throw to trigger retry mechanism
}
}
// Helper method to get recent emails from a mailbox
private async getRecentEmails(userId: string, mailboxId: string, since: Date) {
try {
const response = await firstValueFrom(
this.mailServerService.messages.searchMessages(userId, {
mailbox: mailboxId,
limit: 50, // Limit to avoid too many results
order: "desc", // Most recent first
}),
);
if (!response.success || !response.results) {
return [];
}
return response.results.filter((email) => {
const emailDate = new Date(email.date || new Date().toISOString());
return emailDate >= since;
});
} catch (error) {
this.logger.error(`Error fetching recent emails for user ${userId}:`, error);
return [];
}
}
// Helper method to get unread counts from all mailboxes
private async getUnreadCounts(userId: string, mailboxIds: UserMailboxIds) {
try {
const mailboxCounts: Record<string, number> = {};
let total = 0;
// Get unread count from each mailbox
for (const [mailboxName, mailboxId] of Object.entries(mailboxIds)) {
if (mailboxId) {
try {
const response = await firstValueFrom(this.mailServerService.mailboxes.getMailbox(userId, mailboxId));
if (response.success && response.unseen !== undefined) {
mailboxCounts[mailboxName] = response.unseen;
total += response.unseen;
}
} catch (error) {
this.logger.warn(`Error getting unread count for ${mailboxName} (${mailboxId}):`, error);
mailboxCounts[mailboxName] = 0;
}
}
}
return {
total,
mailboxCounts,
};
} catch (error) {
this.logger.error(`Error calculating unread counts for user ${userId}:`, error);
return {
total: 0,
mailboxCounts: {},
};
}
}
}