138 lines
4.0 KiB
Go
138 lines
4.0 KiB
Go
package domain
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"github.com/matcornic/hermes/v2"
|
||
)
|
||
|
||
// BuildHermesHTML renders a hermes email skeleton (same stack as stand-alone notification).
|
||
func BuildHermesHTML(brand Brand, body hermes.Body) (string, error) {
|
||
if brand.Name == "" {
|
||
brand.Name = "Harbor Desk"
|
||
}
|
||
h := hermes.Hermes{
|
||
Product: hermes.Product{
|
||
Name: brand.Name,
|
||
Link: brand.Link,
|
||
Logo: brand.LogoURL,
|
||
Copyright: brand.Copyright,
|
||
},
|
||
// Default theme is clean table layout suitable for most clients.
|
||
}
|
||
return h.GenerateHTML(hermes.Email{Body: body})
|
||
}
|
||
|
||
// GenerateTemplate builds subject + HTML for a kind/lang with placeholders still present
|
||
// ({{.Username}}, {{.VerifyCode}}, {{.ResetURL}} filled later by text/template).
|
||
func GenerateTemplate(kind TemplateKind, lang Language, brand Brand) (*EmailTemplate, error) {
|
||
lang = NormalizeLanguage(string(lang))
|
||
switch kind {
|
||
case TemplateEmailVerify:
|
||
return generateEmailVerify(lang, brand)
|
||
case TemplatePasswordReset:
|
||
return generatePasswordReset(lang, brand)
|
||
default:
|
||
return nil, fmt.Errorf("unknown template kind: %s", kind)
|
||
}
|
||
}
|
||
|
||
func generateEmailVerify(lang Language, brand Brand) (*EmailTemplate, error) {
|
||
var subject string
|
||
var intros, outros []string
|
||
var instr string
|
||
if lang == LangEnUS {
|
||
subject = "[Harbor Desk] Verify your email"
|
||
intros = []string{
|
||
"You received this email because we need to verify your email address.",
|
||
}
|
||
instr = "Copy this verification code and enter it on the verify page (valid for 30 minutes):"
|
||
outros = []string{
|
||
"If you did not create an account, you can ignore this email.",
|
||
"This is an automated message — please do not reply.",
|
||
}
|
||
} else {
|
||
subject = "【Harbor Desk】信箱驗證碼"
|
||
intros = []string{
|
||
"您收到此信是因為需要驗證您的電子信箱。",
|
||
}
|
||
instr = "請複製下方驗證碼,於 30 分鐘內到驗證頁完成確認:"
|
||
outros = []string{
|
||
"若您並未註冊帳號,可忽略本信。",
|
||
"此為系統自動發出,請勿直接回覆。",
|
||
}
|
||
}
|
||
html, err := BuildHermesHTML(brand, hermes.Body{
|
||
Name: "{{.Username}}",
|
||
Intros: intros,
|
||
Actions: []hermes.Action{
|
||
{
|
||
Instructions: instr,
|
||
InviteCode: "{{.VerifyCode}}",
|
||
},
|
||
},
|
||
Outros: outros,
|
||
Signature: " ",
|
||
})
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &EmailTemplate{Subject: subject, Body: html}, nil
|
||
}
|
||
|
||
func generatePasswordReset(lang Language, brand Brand) (*EmailTemplate, error) {
|
||
var subject, instr, btnText string
|
||
var intros, outros []string
|
||
if lang == LangEnUS {
|
||
subject = "[Harbor Desk] Reset your password"
|
||
intros = []string{
|
||
"You received this email because a password reset was requested for your account.",
|
||
}
|
||
instr = "Copy this code, or open the reset page with the button below (valid for 30 minutes):"
|
||
btnText = "Open reset page"
|
||
outros = []string{
|
||
"If you did not request a password reset, no further action is required.",
|
||
"This is an automated message — please do not reply.",
|
||
}
|
||
} else {
|
||
subject = "【Harbor Desk】重設密碼"
|
||
intros = []string{
|
||
"您收到此信是因為有人申請重設您的帳戶密碼。",
|
||
}
|
||
instr = "請複製下方驗證碼,或點擊按鈕開啟重設頁(30 分鐘內有效):"
|
||
btnText = "開啟重設密碼頁"
|
||
outros = []string{
|
||
"若您並未申請重設密碼,可忽略本信,帳號不會有任何變更。",
|
||
"此為系統自動發出,請勿直接回覆。",
|
||
}
|
||
}
|
||
|
||
actions := []hermes.Action{
|
||
{
|
||
Instructions: instr,
|
||
InviteCode: "{{.VerifyCode}}",
|
||
},
|
||
}
|
||
// Button only when ResetURL placeholder present after render — always include;
|
||
// empty href is avoided by filling ResetURL before send.
|
||
actions = append(actions, hermes.Action{
|
||
Button: hermes.Button{
|
||
Color: "#0f172a",
|
||
Text: btnText,
|
||
Link: "{{.ResetURL}}",
|
||
},
|
||
})
|
||
|
||
html, err := BuildHermesHTML(brand, hermes.Body{
|
||
Name: "{{.Username}}",
|
||
Intros: intros,
|
||
Actions: actions,
|
||
Outros: outros,
|
||
Signature: " ",
|
||
})
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &EmailTemplate{Subject: subject, Body: html}, nil
|
||
}
|