feat: Add support for custom email recipients in workflow steps

This commit is contained in:
Dries Augustyns
2026-02-17 18:57:15 +01:00
parent f9b1354460
commit 78d3d224af
7 changed files with 1274 additions and 736 deletions
@@ -519,18 +519,25 @@ export class WorkflowExecutionService {
}
/**
* SEND_EMAIL step - Send an email to the contact
* SEND_EMAIL step - Send an email to the contact or a custom recipient
*/
private static async executeSendEmail(
step: WorkflowStepWithTemplate,
execution: WorkflowExecutionWithRelations,
stepExecution: WorkflowStepExecution,
_config: StepConfig,
config: StepConfig,
): Promise<StepResult> {
if (!step.template) {
throw new Error('No template configured for SEND_EMAIL step');
}
// Parse step config to get recipient configuration
const stepConfig = config && typeof config === 'object' && !Array.isArray(config) ? config : {};
const recipientConfig =
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
const contact = execution.contact;
const contactData =
@@ -558,10 +565,20 @@ export class WorkflowExecutionService {
const renderedSubject = this.renderTemplate(step.template.subject, variables);
const renderedBody = this.renderTemplate(step.template.body, variables);
// Determine recipient email
let recipientEmail = contact.email;
let recipientContactId = contact.id;
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
const email = await EmailService.sendWorkflowEmail({
projectId: execution.workflow.projectId,
contactId: contact.id,
contactId: recipientContactId,
workflowExecutionId: execution.id,
workflowStepExecutionId: stepExecution.id, // Use stepExecution.id, not step.id
templateId: step.template.id,
@@ -570,11 +587,15 @@ export class WorkflowExecutionService {
from: step.template.from,
fromName: step.template.fromName || undefined,
replyTo: step.template.replyTo || undefined,
// Pass custom recipient email if specified
recipientEmail: recipientConfig.type === 'CUSTOM' ? recipientEmail : undefined,
});
return {
emailId: email.id,
sentAt: email.createdAt,
recipientType: recipientConfig.type,
recipientEmail,
};
}