mail templates
Some checks failed
ci/woodpecker/push/db Pipeline is pending
ci/woodpecker/push/frontend Pipeline is pending
ci/woodpecker/push/fx_ingestor Pipeline is pending
ci/woodpecker/push/fx_oracle Pipeline is pending
ci/woodpecker/push/ledger Pipeline is pending
ci/woodpecker/push/nats Pipeline is pending
ci/woodpecker/push/notification Pipeline is pending
ci/woodpecker/push/payments_orchestrator Pipeline is pending
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline failed
ci/woodpecker/push/bump_version unknown status
ci/woodpecker/push/chain_gateway Pipeline failed

This commit is contained in:
Stephan D
2025-11-24 21:42:06 +01:00
parent d65e442cb6
commit e3a8fb4f2d
8 changed files with 309 additions and 130 deletions

View File

@@ -46,7 +46,7 @@ func (m *EmailNotificationTemplate) prepareUnsubscribe(msg mmail.Message) error
return err
}
localization.AddLocData(d, "UnsubscribeLink", unsLink)
if block, err = m.l.LocalizeTemplate("mail.template.unsubscribe.block", d, nil, msg.Locale()); err != nil {
if block, err = renderUnsubscribeBlock(d); err != nil {
return err
}
}
@@ -58,7 +58,7 @@ func (m *EmailNotificationTemplate) prepareButton(msg mmail.Message) error {
var block string
if m.hasButton {
var err error
if block, err = m.l.LocalizeTemplate("mail.template.btn.block", m.data, nil, msg.Locale()); err != nil {
if block, err = renderButtonBlock(m.data); err != nil {
return err
}
}
@@ -91,7 +91,7 @@ func (m *EmailNotificationTemplate) SignatureData(msg mmail.Message, content, su
return "", err
}
return m.l.LocalizeTemplate("mail.template.one_button", m.data, nil, msg.Locale())
return renderOneButtonEmail(m.data)
}
func (m *EmailNotificationTemplate) putOnHTMLTemplate(msg mmail.Message, content, subj string) (string, error) {

View File

@@ -0,0 +1,285 @@
package mailimp
import (
"bytes"
"text/template"
)
var (
unsubscribeBlockTpl = template.Must(template.New("unsubscribeBlock").Parse(`
<a
target="_blank"
style="-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;text-decoration:none;color:#2D3142;font-size:13px"
href=""
>
</a>
<a
target="_blank"
style="-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;text-decoration:none;color:#2D3142;font-size:14px"
href="{{.UnsubscribeLink}}"
>
{{.Unsubscribe}}
</a>`))
buttonBlockTpl = template.Must(template.New("buttonBlock").Parse(`
<tr>
<td align="center" style="padding:0;Margin:0">
<!--[if mso]>
<a href="" target="_blank" hidden>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" esdevVmlButton href="{{.ButtonLink}}"
style="height:56px; v-text-anchor:middle; width:520px" arcsize="14%" stroke="f" fillcolor="#0b58ff">
<w:anchorlock></w:anchorlock>
<center style='color:#ffffff; font-family:montserrat, roboto; font-size:22px; font-weight:700; line-height:22px; mso-text-raise:1px'>{{.ButtonText}}</center>
</v:roundrect>
</a>
<![endif]-->
<!--[if !mso]><!-- -->
<span class="msohide es-button-border" style="border-style:solid;border-color:#0b58ff;background:#0b58ff;border-width:0px;display:block;border-radius:8px;width:auto;mso-border-alt:10px;mso-hide:all;width:520px">
<a
href="{{.ButtonLink}}"
class="es-button msohide"
target="_blank"
style="mso-style-priority:100 !important;text-decoration:none;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;color:#ffffff;font-size:22px;padding:15px 20px 15px 20px;display:block;background:#0b58ff;border-radius:8px;font-family:montserrat, roboto;font-weight:bold;font-style:normal;line-height:26px;width:auto;text-align:center;border-color:#0b58ff;mso-hide:all;padding-left:5px;padding-right:5px"
>
{{.ButtonText}}
</a>
</span>
<!--<![endif]-->
</td>
</tr>`))
oneButtonEmailTpl = template.Must(template.New("oneButtonEmail").Parse(`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" style="font-family:montserrat, roboto">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<meta name="x-apple-disable-message-reformatting">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="telephone=no" name="format-detection">
<title>{{.MessageTitle}}</title>
<!--[if (mso 16)]>
<style type="text/css">
a {text-decoration: none;}
</style>
<![endif]-->
<!--[if gte mso 9]><style>sup { font-size: 100% !important; }</style><![endif]-->
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG></o:AllowPNG>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<!--[if !mso]><!-- -->
<link href="https://fonts.googleapis.com/css2?family=Imprima&display=swap" rel="stylesheet">
<!--<![endif]-->
<!--[if !mso]><!-- -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:100,300,400,500,700,900">
<!--<![endif]-->
<style type="text/css">
#outlook a { padding:0; }
.es-button { mso-style-priority:100!important; text-decoration:none!important; }
a[x-apple-data-detectors] {
color:inherit!important;
text-decoration:none!important;
font-size:inherit!important;
font-family:inherit!important;
font-weight:inherit!important;
line-height:inherit!important;
}
.es-desk-hidden { display:none; float:left; overflow:hidden; width:0; max-height:0; line-height:0; mso-hide:all; }
@media only screen and (max-width:600px) {
p, ul li, ol li, a { line-height:150%!important }
h1, h2, h3, h1 a, h2 a, h3 a { line-height:120% }
h1 { font-size:30px!important; text-align:left }
h2 { font-size:24px!important; text-align:left }
h3 { font-size:20px!important; text-align:left }
.es-header-body h1 a, .es-content-body h1 a, .es-footer-body h1 a { font-size:30px!important; text-align:left }
.es-header-body h2 a, .es-content-body h2 a, .es-footer-body h2 a { font-size:24px!important; text-align:left }
.es-header-body h3 a, .es-content-body h3 a, .es-footer-body h3 a { font-size:20px!important; text-align:left }
.es-menu td a { font-size:14px!important }
.es-header-body p, .es-header-body ul li, .es-header-body ol li, .es-header-body a { font-size:14px!important }
.es-content-body p, .es-content-body ul li, .es-content-body ol li, .es-content-body a { font-size:14px!important }
.es-footer-body p, .es-footer-body ul li, .es-footer-body ol li, .es-footer-body a { font-size:14px!important }
.es-infoblock p, .es-infoblock ul li, .es-infoblock ol li, .es-infoblock a { font-size:12px!important }
*[class="gmail-fix"] { display:none!important }
.es-m-txt-c, .es-m-txt-c h1, .es-m-txt-c h2, .es-m-txt-c h3 { text-align:center!important }
.es-m-txt-r, .es-m-txt-r h1, .es-m-txt-r h2, .es-m-txt-r h3 { text-align:right!important }
.es-m-txt-l, .es-m-txt-l h1, .es-m-txt-l h2, .es-m-txt-l h3 { text-align:left!important }
.es-m-txt-r img, .es-m-txt-c img, .es-m-txt-l img { display:inline!important }
.es-button-border { display:block!important }
a.es-button, button.es-button { font-size:18px!important; display:block!important; border-right-width:0px!important; border-left-width:0px!important; border-top-width:15px!important; border-bottom-width:15px!important; padding-left:0px!important; padding-right:0px!important }
.es-adaptive table, .es-left, .es-right { width:100%!important }
.es-content table, .es-header table, .es-footer table, .es-content, .es-footer, .es-header { width:100%!important; max-width:600px!important }
.es-adapt-td { display:block!important; width:100%!important }
.adapt-img { width:100%!important; height:auto!important }
.es-m-p0 { padding:0px!important }
.es-m-p0r { padding-right:0px!important }
.es-m-p0l { padding-left:0px!important }
.es-m-p0t { padding-top:0px!important }
.es-m-p0b { padding-bottom:0!important }
.es-m-p20b { padding-bottom:20px!important }
.es-mobile-hidden, .es-hidden { display:none!important }
tr.es-desk-hidden, td.es-desk-hidden, table.es-desk-hidden { width:auto!important; overflow:visible!important; float:none!important; max-height:inherit!important; line-height:inherit!important }
tr.es-desk-hidden { display:table-row!important }
table.es-desk-hidden { display:table!important }
td.es-desk-menu-hidden { display:table-cell!important }
.es-menu td { width:1%!important }
table.es-table-not-adapt, .esd-block-html table { width:auto!important }
table.es-social { display:inline-block!important }
table.es-social td { display:inline-block!important }
.es-desk-hidden { display:table-row!important; width:auto!important; overflow:visible!important; max-height:inherit!important }
}
</style>
</head>
<body style="width:100%;font-family:montserrat, roboto;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;padding:0;Margin:0">
<div class="es-wrapper-color" style="background-color:#FFFFFF">
<!--[if gte mso 9]>
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
<v:fill type="tile" color="#ffffff"></v:fill>
</v:background>
<![endif]-->
<table class="es-wrapper" width="100%" cellspacing="0" cellpadding="0" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;padding:0;Margin:0;width:100%;height:100%;background-repeat:repeat;background-position:center top;background-color:#FFFFFF">
<tr>
<td valign="top" style="padding:0;Margin:0">
<table cellpadding="0" cellspacing="0" class="es-content" align="center" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;table-layout:fixed !important;width:100%">
<tr>
<td align="center" style="padding:0;Margin:0">
<table bgcolor="#ffffff" class="es-content-body" align="center" cellpadding="0" cellspacing="0" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;background-color:#FFFFFF;border-radius:20px 20px 0 0;width:600px">
<tr>
<td align="left" style="padding:0;Margin:0;padding-top:20px;padding-left:40px;padding-right:40px;border-radius:8px 8px 0px 0px">
<table cellpadding="0" cellspacing="0" width="100%" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px">
<tr>
<td align="center" valign="top" style="padding:0;Margin:0;width:520px">
<table cellpadding="0" cellspacing="0" width="100%" bgcolor="#fafafa" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:separate;border-spacing:0px;background-color:#fafafa;border-radius:10px" role="presentation">
<tr>
<td align="left" style="padding:20px;Margin:0">
<h3 style="Margin:0;line-height:34px;mso-line-height-rule:exactly;font-family:montserrat, roboto;font-size:28px;font-style:normal;font-weight:bold;color:#2D3142">
{{.Greeting}}
</h3>
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:27px;color:#2D3142;font-size:18px"><br></p>
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:27px;color:#2D3142;font-size:18px">
{{.Content}}
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" class="es-content" align="center" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;table-layout:fixed !important;width:100%">
{{.ButtonBlock}}
</table>
<table cellpadding="0" cellspacing="0" class="es-footer" align="center" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;table-layout:fixed !important;width:100%;background-color:transparent;background-repeat:repeat;background-position:center top">
<tr>
<td align="center" style="padding:0;Margin:0">
<table bgcolor="#bcb8b1" class="es-footer-body" align="center" cellpadding="0" cellspacing="0" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;background-color:#FFFFFF;width:600px">
<tr>
<td align="left" style="Margin:0;padding-left:20px;padding-right:20px;padding-bottom:30px;padding-top:40px">
<!--[if mso]><table style="width:560px" cellpadding="0" cellspacing="0"><tr><td style="width:82px" valign="top"><![endif]-->
<table cellpadding="0" cellspacing="0" align="left" class="es-left" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;float:left">
<tr>
<td align="left" class="es-m-p20b" style="padding:0;Margin:0;width:82px">
<table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px">
<tr>
<td
align="center"
style="padding:0;Margin:0;padding-left:20px;font-size:0px">
<img class="adapt-img"
src="{{.LogoLink}}"
alt
style="display:block;border:0;outline:none;text-decoration:none;-ms-interpolation-mode:bicubic" width="62"
/>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!--[if mso]></td><td style="width:20px"></td><td style="width:458px" valign="top"><![endif]-->
<table cellpadding="0" cellspacing="0" class="es-right" align="right" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;float:right">
<tr>
<td align="left" style="padding:0;Margin:0;width:458px">
<table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px">
<tr>
<td align="left" style="padding:0;Margin:0">
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:20px;color:#2D3142;font-size:13px">
<a target="_blank" style="-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;text-decoration:none;color:#2D3142;font-size:14px" href=""></a>
<a
target="_blank"
style="-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;text-decoration:none;color:#2D3142;font-size:14px"
href="{{.PolicyLink}}"
>
{{.Privacy}}
</a>
{{.UnsubscribeBlock}}
</p>
</td>
</tr>
<tr>
<td align="left" style="padding:0;Margin:0">
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:20px;color:#2D3142;font-size:13px">
{{.ServiceOwner}}
</p>
</td>
</tr>
<tr>
<td align="left" style="padding:0;Margin:0">
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:20px;color:#2D3142;font-size:13px">
{{.OwnerAddress}}
</p>
</td>
</tr>
<tr>
<td align="left" style="padding:0;Margin:0">
<p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:montserrat, roboto;line-height:20px;color:#2D3142;font-size:13px">
{{.OwnerPhone}}
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!--[if mso]></td></tr></table><![endif]-->
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>`))
)
func renderTemplate(tpl *template.Template, data any) (string, error) {
var buf bytes.Buffer
if err := tpl.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func renderUnsubscribeBlock(data any) (string, error) {
return renderTemplate(unsubscribeBlockTpl, data)
}
func renderButtonBlock(data any) (string, error) {
return renderTemplate(buttonBlockTpl, data)
}
func renderOneButtonEmail(data any) (string, error) {
return renderTemplate(oneButtonEmailTpl, data)
}