fix: display email progress instead of scheduling progress for campaigns
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
* Processes individual emails from the queue (for all sources: transactional, campaign, workflow)
|
* Processes individual emails from the queue (for all sources: transactional, campaign, workflow)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {EmailSourceType, EmailStatus} from '@plunk/db';
|
import {CampaignStatus, EmailSourceType, EmailStatus} from '@plunk/db';
|
||||||
import {type Job, Worker} from 'bullmq';
|
import {type Job, Worker} from 'bullmq';
|
||||||
import signale from 'signale';
|
import signale from 'signale';
|
||||||
|
|
||||||
@@ -170,6 +170,57 @@ export async function createEmailWorker() {
|
|||||||
sourceType: email.sourceType,
|
sourceType: email.sourceType,
|
||||||
sentAt: new Date().toISOString(),
|
sentAt: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If this email belongs to a campaign, check if all campaign emails have been sent
|
||||||
|
if (email.campaignId) {
|
||||||
|
const campaign = await prisma.campaign.findUnique({
|
||||||
|
where: {id: email.campaignId},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
status: true,
|
||||||
|
totalRecipients: true,
|
||||||
|
projectId: true,
|
||||||
|
project: {
|
||||||
|
select: {name: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only check if campaign is still in SENDING status
|
||||||
|
if (campaign && campaign.status === CampaignStatus.SENDING) {
|
||||||
|
// Count how many emails have been sent for this campaign
|
||||||
|
const sentCount = await prisma.email.count({
|
||||||
|
where: {
|
||||||
|
campaignId: email.campaignId,
|
||||||
|
sentAt: {not: null},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// If all emails have been sent, mark campaign as SENT
|
||||||
|
if (sentCount >= campaign.totalRecipients) {
|
||||||
|
await prisma.campaign.update({
|
||||||
|
where: {id: email.campaignId},
|
||||||
|
data: {
|
||||||
|
status: CampaignStatus.SENT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
signale.success(
|
||||||
|
`[EMAIL-PROCESSOR] Campaign ${campaign.name} completed: ${sentCount}/${campaign.totalRecipients} emails sent`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send notification about campaign send completed
|
||||||
|
const {NtfyService} = await import('../services/NtfyService.js');
|
||||||
|
await NtfyService.notifyCampaignSendCompleted(
|
||||||
|
campaign.name,
|
||||||
|
campaign.project.name,
|
||||||
|
campaign.projectId,
|
||||||
|
campaign.totalRecipients,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
signale.error(`[EMAIL-PROCESSOR] Failed to send email ${emailId}:`, error);
|
signale.error(`[EMAIL-PROCESSOR] Failed to send email ${emailId}:`, error);
|
||||||
|
|
||||||
|
|||||||
@@ -513,16 +513,6 @@ export class CampaignService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update sent count
|
|
||||||
await prisma.campaign.update({
|
|
||||||
where: {id: campaignId},
|
|
||||||
data: {
|
|
||||||
sentCount: {
|
|
||||||
increment: contacts.length,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Queue next batch if there are more contacts
|
// Queue next batch if there are more contacts
|
||||||
if (hasMore && nextCursor) {
|
if (hasMore && nextCursor) {
|
||||||
await QueueService.queueCampaignBatch({
|
await QueueService.queueCampaignBatch({
|
||||||
@@ -532,27 +522,6 @@ export class CampaignService {
|
|||||||
limit,
|
limit,
|
||||||
cursor: nextCursor,
|
cursor: nextCursor,
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// All batches processed, mark campaign as SENT
|
|
||||||
const completedCampaign = await prisma.campaign.update({
|
|
||||||
where: {id: campaignId},
|
|
||||||
data: {
|
|
||||||
status: CampaignStatus.SENT,
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
project: {
|
|
||||||
select: {name: true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send notification about campaign send completed
|
|
||||||
await NtfyService.notifyCampaignSendCompleted(
|
|
||||||
completedCampaign.name,
|
|
||||||
completedCampaign.project.name,
|
|
||||||
completedCampaign.projectId,
|
|
||||||
completedCampaign.totalRecipients || 0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default function CampaignDetailsPage() {
|
|||||||
id && campaign?.data.status !== CampaignStatus.DRAFT ? `/campaigns/${id}/stats` : null,
|
id && campaign?.data.status !== CampaignStatus.DRAFT ? `/campaigns/${id}/stats` : null,
|
||||||
{
|
{
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
refreshInterval: campaign?.data.status === CampaignStatus.SENDING ? 5000 : 0, // Refresh every 5s if sending
|
refreshInterval: campaign?.data.status === CampaignStatus.SENDING ? 15000 : 0, // Refresh every 15s while sending
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user