fix: Enhance email step configuration validation and recipient handling

This commit is contained in:
Dries Augustyns
2026-03-19 15:18:40 +01:00
parent f44d987bc9
commit a99cde8839
@@ -531,12 +531,9 @@ export class WorkflowExecutionService {
throw new Error('No template configured for SEND_EMAIL step'); throw new Error('No template configured for SEND_EMAIL step');
} }
// Parse step config to get recipient configuration // Parse and validate step config using schema
const stepConfig = config && typeof config === 'object' && !Array.isArray(config) ? config : {}; const stepConfig = WorkflowStepConfigSchemas.sendEmail.parse(config);
const recipientConfig = const recipientConfig = stepConfig.recipient || {type: 'CONTACT' as const};
stepConfig.recipient && typeof stepConfig.recipient === 'object' && !Array.isArray(stepConfig.recipient)
? (stepConfig.recipient as {type?: string; customEmail?: string})
: {type: 'CONTACT'};
// Get contact data for variable substitution // Get contact data for variable substitution
const contact = execution.contact; const contact = execution.contact;
@@ -566,19 +563,13 @@ export class WorkflowExecutionService {
const renderedBody = this.renderTemplate(step.template.body, variables); const renderedBody = this.renderTemplate(step.template.body, variables);
// Determine recipient email // Determine recipient email
let recipientEmail = contact.email; // Schema validation ensures customEmail exists when type is CUSTOM
let recipientContactId = contact.id; const recipientEmail = recipientConfig.type === 'CUSTOM' ? recipientConfig.customEmail! : contact.email;
if (recipientConfig.type === 'CUSTOM' && recipientConfig.customEmail) {
recipientEmail = recipientConfig.customEmail;
// For custom recipients, we don't associate with a contact
recipientContactId = contact.id; // Keep original contact for tracking
}
// Send email via EmailService // Send email via EmailService
const email = await EmailService.sendWorkflowEmail({ const email = await EmailService.sendWorkflowEmail({
projectId: execution.workflow.projectId, projectId: execution.workflow.projectId,
contactId: recipientContactId, contactId: contact.id, // Keep original contact for tracking
workflowExecutionId: execution.id, workflowExecutionId: execution.id,
workflowStepExecutionId: stepExecution.id, // Use stepExecution.id, not step.id workflowStepExecutionId: stepExecution.id, // Use stepExecution.id, not step.id
templateId: step.template.id, templateId: step.template.id,
@@ -588,7 +579,7 @@ export class WorkflowExecutionService {
fromName: step.template.fromName || undefined, fromName: step.template.fromName || undefined,
replyTo: step.template.replyTo || undefined, replyTo: step.template.replyTo || undefined,
// Pass custom recipient email if specified // Pass custom recipient email if specified
recipientEmail: recipientConfig.type === 'CUSTOM' ? recipientEmail : undefined, recipientEmail: recipientConfig.type === 'CUSTOM' ? recipientConfig.customEmail : undefined,
}); });
return { return {