Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/internal/flow/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,6 @@ const (
ForwardedDataKeyConsentPrompt = "consent_prompt"
// ForwardedDataKeyActionType holds the action type selected by the user for the immediate next node
ForwardedDataKeyActionType = "actionType"
// ForwardedDataKeyTemplateData holds template parameters for notification executors
ForwardedDataKeyTemplateData = "templateData"
)
35 changes: 22 additions & 13 deletions backend/internal/flow/executor/email_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,15 @@ func (e *emailExecutor) executeSend(ctx *core.NodeContext) (*common.ExecutorResp
propertyKeyEmailTemplate, tmplProp, tmplProp)
}
if tmplStr == "" {
scenario = template.ScenarioUserInvite
} else {
scenario = template.ScenarioType(tmplStr)
return nil, fmt.Errorf("email template property is empty in node configuration")
}
scenario = template.ScenarioType(tmplStr)
} else {
scenario = template.ScenarioUserInvite
// No more guessing! If it's missing, fail loudly.
return nil, fmt.Errorf("missing required property: %s", propertyKeyEmailTemplate)
}

inviteLink := ctx.RuntimeData[common.RuntimeKeyInviteLink]
if (scenario == template.ScenarioUserInvite || scenario == template.ScenarioSelfRegistration) && inviteLink == "" {
return nil, errors.New("invite link not found in runtime data")
}

templateData := template.TemplateData{
"inviteLink": inviteLink,
"appName": ctx.Application.Name,
}
templateData := e.resolveTemplateData(ctx)
rendered, svcErr := e.templateService.Render(ctx.Context, scenario, template.TemplateTypeEmail, templateData)
if svcErr != nil {
return nil, fmt.Errorf("failed to render email template: %s", svcErr.Code)
Expand Down Expand Up @@ -213,6 +205,23 @@ func (e *emailExecutor) resolveRecipientEmail(ctx *core.NodeContext, logger *log
return "", nil
}

// resolveTemplateData extracts template data from forwarded data or initializes an empty map if not present.
func (e *emailExecutor) resolveTemplateData(ctx *core.NodeContext) template.TemplateData {
if ctx.ForwardedData != nil {
if forwardedTemplateData, ok := ctx.ForwardedData[common.ForwardedDataKeyTemplateData]; ok {
if interfaceData, isInterfaceMap := forwardedTemplateData.(map[string]interface{}); isInterfaceMap {
templateData := template.TemplateData{}
for k, v := range interfaceData {
templateData[k] = fmt.Sprintf("%v", v)
}
return templateData
}
}
}

return template.TemplateData{}
}
Comment thread
RandithaK marked this conversation as resolved.

// isEmailError returns true if the error originated from the email subsystem,
// covering both client-side validation errors and server-side SMTP transport errors.
func isEmailError(err error) bool {
Expand Down
Loading