feat: add HTML email support to HTTP channel (#4387)

Closes #4350
This commit is contained in:
Aran Donohue 2025-04-28 03:04:26 -07:00 committed by GitHub
parent 63800ecc37
commit fb8856eb11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 38 additions and 15 deletions

View File

@ -49,9 +49,11 @@ func (c *httpChannel) ID() string {
}
type httpDataModel struct {
Recipient string `json:"recipient"`
Subject string `json:"subject"`
Body string `json:"body"`
Recipient string `json:"recipient"`
Subject string `json:"subject"`
Body string `json:"body"`
// Optional HTMLBody contains the HTML version of an email template when available.
HTMLBody string `json:"html_body,omitempty"`
TemplateType template.TemplateType `json:"template_type"`
TemplateData Template `json:"template_data"`
MessageType string `json:"message_type"`
@ -80,6 +82,8 @@ func (c *httpChannel) Dispatch(ctx context.Context, msg Message) (err error) {
MessageType: msg.Type.String(),
}
c.tryPopulateHTMLBody(ctx, tmpl, &td)
req, err := builder.BuildRequest(ctx, td)
if err != nil {
return errors.WithStack(err)
@ -114,6 +118,18 @@ func (c *httpChannel) Dispatch(ctx context.Context, msg Message) (err error) {
return errors.WithStack(err)
}
func (c *httpChannel) tryPopulateHTMLBody(ctx context.Context, tmpl Template, td *httpDataModel) {
if emailTmpl, ok := tmpl.(EmailTemplate); ok {
// Only get the HTML body from the template; plaintext body comes from msg.Body
// to maintain backward compatibility with existing behavior
if htmlBody, err := emailTmpl.EmailBody(ctx); err != nil {
c.d.Logger().WithError(err).Error("Unable to get email HTML body from template.")
} else {
td.HTMLBody = htmlBody
}
}
}
func newTemplate(d template.Dependencies, msg Message) (Template, error) {
switch msg.Type {
case MessageTypeEmail:

View File

@ -40,14 +40,16 @@ func TestQueueHTTPEmail(t *testing.T) {
VerificationURL string `json:"verification_url"`
VerificationCode string `json:"verification_code"`
Body string `json:"body"`
HTMLBody string `json:"html_body"`
Subject string `json:"subject"`
}
expectedEmail := []*email.TestStubModel{
{
To: "test-2@test.com",
Subject: "test-mailer-subject-1",
Body: "test-mailer-body-1",
To: "test-2@test.com",
Subject: "test-mailer-subject-1",
Body: "test-mailer-body-1",
HTMLBody: "<html><body>test-mailer-body-html-1</body></html>",
},
{
To: "test-2@test.com",
@ -58,7 +60,6 @@ func TestQueueHTTPEmail(t *testing.T) {
actual := make([]sendEmailRequestBody, 0, 2)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rb, err := io.ReadAll(r.Body)
require.NoError(t, err)
@ -83,7 +84,8 @@ func TestQueueHTTPEmail(t *testing.T) {
"user": "me",
"password": "12345"
}
}
},
"body": "file://./stub/request.config.mailer.jsonnet"
}`, srv.URL)
conf, reg := internal.NewFastRegistryWithMocks(t)
@ -119,7 +121,10 @@ func TestQueueHTTPEmail(t *testing.T) {
expected := email.NewTestStub(reg, expectedEmail[i])
assert.Equal(t, x.Must(expected.EmailRecipient()), message.To)
assert.Equal(t, x.Must(expected.EmailBody(ctx)), message.Body)
assert.Equal(t, x.Must(expected.EmailSubject(ctx)), message.Subject)
assert.Equal(t, expectedEmail[i].Body, message.Body)
if expectedEmail[i].HTMLBody != "" {
assert.Equal(t, expectedEmail[i].HTMLBody, message.HTMLBody)
}
assert.Equal(t, expectedEmail[i].Subject, message.Subject)
}
}

View File

@ -7,5 +7,6 @@ function(ctx) {
verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null,
verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null,
subject: if "template_data" in ctx && "subject" in ctx.template_data then ctx.template_data.subject else null,
body: if "template_data" in ctx && "body" in ctx.template_data then ctx.template_data.body else null
body: if "template_data" in ctx && "body" in ctx.template_data then ctx.template_data.body else null,
html_body: if "template_data" in ctx && "html_body" in ctx.template_data then ctx.template_data.html_body else null
}

View File

@ -1 +1 @@
stub email body {{ .Body }}
stub email body {{ if .HTMLBody }}{{ .HTMLBody }}{{ else }}{{ .Body }}{{ end }}

View File

@ -18,9 +18,10 @@ type (
m *TestStubModel
}
TestStubModel struct {
To string `json:"to"`
Subject string `json:"subject"`
Body string `json:"body"`
To string `json:"to"`
Subject string `json:"subject"`
Body string `json:"body"`
HTMLBody string `json:"html_body,omitempty"`
}
)