"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.campaignEmailsService = void 0; const client_1 = require("@prisma/client"); const database_1 = require("../../../config/database"); const error_handler_1 = require("../../../middleware/error-handler"); const email_queue_service_1 = require("../../../services/email-queue.service"); const metrics_1 = require("../../../utils/metrics"); exports.campaignEmailsService = { async sendEmail(slug, data, senderIp) { const campaign = await database_1.prisma.campaign.findUnique({ where: { slug }, select: { id: true, slug: true, title: true, status: true, emailSubject: true, emailBody: true, allowSmtpEmail: true, allowMailtoLink: true, allowEmailEditing: true, }, }); if (!campaign) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } if (campaign.status !== client_1.CampaignStatus.ACTIVE) { throw new error_handler_1.AppError(400, 'Campaign is not active', 'CAMPAIGN_NOT_ACTIVE'); } if (data.emailMethod === client_1.EmailMethod.SMTP && !campaign.allowSmtpEmail) { throw new error_handler_1.AppError(400, 'SMTP email is not enabled for this campaign', 'SMTP_NOT_ALLOWED'); } if (data.emailMethod === client_1.EmailMethod.MAILTO && !campaign.allowMailtoLink) { throw new error_handler_1.AppError(400, 'Mailto link is not enabled for this campaign', 'MAILTO_NOT_ALLOWED'); } // Determine subject and body (custom only if campaign allows editing) const subject = (campaign.allowEmailEditing && data.customEmailSubject) ? data.customEmailSubject : campaign.emailSubject; const message = (campaign.allowEmailEditing && data.customEmailBody) ? data.customEmailBody : campaign.emailBody; const status = data.emailMethod === client_1.EmailMethod.SMTP ? client_1.CampaignEmailStatus.QUEUED : client_1.CampaignEmailStatus.CLICKED; const campaignEmail = await database_1.prisma.campaignEmail.create({ data: { campaignId: campaign.id, campaignSlug: campaign.slug, userEmail: data.userEmail, userName: data.userName, userPostalCode: data.postalCode, recipientEmail: data.recipientEmail, recipientName: data.recipientName, recipientTitle: data.recipientTitle, recipientLevel: data.recipientLevel, emailMethod: data.emailMethod, subject, message, status, senderIp, }, }); if (data.emailMethod === client_1.EmailMethod.SMTP) { await email_queue_service_1.emailQueueService.addCampaignEmail({ campaignEmailId: campaignEmail.id, recipientEmail: data.recipientEmail, recipientName: data.recipientName, recipientLevel: data.recipientLevel, userEmail: data.userEmail, userName: data.userName, postalCode: data.postalCode, subject, message, campaignTitle: campaign.title, }); } (0, metrics_1.recordCampaignEmail)(campaign.id); return { id: campaignEmail.id, status: campaignEmail.status, emailMethod: campaignEmail.emailMethod, }; }, async trackMailto(slug, data, senderIp) { const campaign = await database_1.prisma.campaign.findUnique({ where: { slug }, select: { id: true, slug: true, title: true, status: true, emailSubject: true, emailBody: true, allowMailtoLink: true, }, }); if (!campaign) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } if (campaign.status !== client_1.CampaignStatus.ACTIVE) { throw new error_handler_1.AppError(400, 'Campaign is not active', 'CAMPAIGN_NOT_ACTIVE'); } const campaignEmail = await database_1.prisma.campaignEmail.create({ data: { campaignId: campaign.id, campaignSlug: campaign.slug, userEmail: data.userEmail, userName: data.userName, userPostalCode: data.postalCode, recipientEmail: data.recipientEmail, recipientName: data.recipientName, recipientTitle: data.recipientTitle, recipientLevel: data.recipientLevel, emailMethod: client_1.EmailMethod.MAILTO, subject: campaign.emailSubject, message: campaign.emailBody, status: client_1.CampaignEmailStatus.CLICKED, senderIp, }, }); return { id: campaignEmail.id, status: campaignEmail.status, emailMethod: campaignEmail.emailMethod, }; }, async listByCampaign(campaignId, filters) { const { page, limit, status, emailMethod } = filters; const skip = (page - 1) * limit; const where = { campaignId }; if (status) where.status = status; if (emailMethod) where.emailMethod = emailMethod; const [emails, total] = await Promise.all([ database_1.prisma.campaignEmail.findMany({ where, skip, take: limit, orderBy: { sentAt: 'desc' }, select: { id: true, userEmail: true, userName: true, userPostalCode: true, recipientEmail: true, recipientName: true, recipientLevel: true, emailMethod: true, subject: true, status: true, sentAt: true, }, }), database_1.prisma.campaignEmail.count({ where }), ]); return { emails, pagination: { page, limit, total, totalPages: Math.ceil(total / limit), }, }; }, async getStats(campaignId) { const [totals, byMethod] = await Promise.all([ database_1.prisma.campaignEmail.groupBy({ by: ['status'], where: { campaignId }, _count: true, }), database_1.prisma.campaignEmail.groupBy({ by: ['emailMethod'], where: { campaignId }, _count: true, }), ]); const stats = { total: 0, queued: 0, sent: 0, failed: 0, clicked: 0, smtpCount: 0, mailtoCount: 0, }; for (const row of totals) { stats.total += row._count; const key = row.status.toLowerCase(); if (key in stats) stats[key] = row._count; } for (const row of byMethod) { if (row.emailMethod === client_1.EmailMethod.SMTP) stats.smtpCount = row._count; if (row.emailMethod === client_1.EmailMethod.MAILTO) stats.mailtoCount = row._count; } return stats; }, }; //# sourceMappingURL=campaign-emails.service.js.map