Skip to content

[CORE-342] Submit Success Email#189

Open
kevinlin0313 wants to merge 5 commits into
mainfrom
feat/CORE-342-submit-success-email
Open

[CORE-342] Submit Success Email#189
kevinlin0313 wants to merge 5 commits into
mainfrom
feat/CORE-342-submit-success-email

Conversation

@kevinlin0313

Copy link
Copy Markdown
Contributor

Type of changes

  • Feature

Purpose

  • Add SMTP service
  • Send email in submit handler

Additional Information

@kevinlin0313
kevinlin0313 requested a review from dytsou July 10, 2026 09:50

@dytsou dytsou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem

After a successful submit, the handler looked up the user's email addresses and sent thank-you messages synchronously before writing the HTTP response. Slow or hung SMTP relays could delay or block 201 even though the submission had already been persisted. Client retries in that window could also trigger duplicate emails.

Proposed change

  1. Return the HTTP response first — write 201 Created as soon as Submit succeeds.
  2. Dispatch email in the background — start a detached goroutine after the response is sent:
go email.SendSubmissionEmails(context.WithoutCancel(traceCtx), currentUser.ID, newResponse)

Comment thread internal/form/submit/handler.go Outdated
Comment on lines 150 to 163
for _, email := range emails {
err := h.mailer.SendSubmissionMail(traceCtx, email, newResponse)
if err != nil {
logger.Error(
"send submission email failed",
zap.Error(err),
zap.String("email", email),
zap.String("user_id", currentUser.ID.String()),
zap.String("response_id", responseID.String()),
)
}
}

submitResponse := Response{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making thank-you email delivery asynchronous by running it in a detached goroutine after the response is sent. By doing so, the HTTP 201 responses are not blocked by SMTP

go email.SendSubmissionEmails(context.WithoutCancel(traceCtx), currentUser.ID, newResponse)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

}
}

func (s *SMTPSender) Send(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a timeout to Email submission, so that it can be shut down if it cannot be sent successfully.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

s.host,
)

message := []byte(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a sanitiser in the message to prevent injection in the email.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the subject is controlled by our application, so it is not user input. However, I'll add validation to prevent potential header injection issues in the future.

ID: newResponse.ID.String(),
FormID: newResponse.FormID.String(),
CreatedAt: newResponse.CreatedAt.Time,
UpdatedAt: newResponse.UpdatedAt.Time,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using the submission time instead of the mail-sent time so it matches the user's actual form submission time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change in internal/email/service.go

@kevinlin0313
kevinlin0313 requested a review from dytsou July 18, 2026 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants