disabled html minfiy, added some headers and new templateS
parent
bf95daba4a
commit
b8c2ec315e
1
go.mod
1
go.mod
|
@ -12,6 +12,7 @@ require (
|
||||||
require (
|
require (
|
||||||
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 // indirect
|
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/uuid v1.5.0 // indirect
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -21,6 +21,8 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||||
|
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||||
|
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"clickandjoin.app/emailserver/modules/cache"
|
"clickandjoin.app/emailserver/modules/cache"
|
||||||
"clickandjoin.app/emailserver/modules/config"
|
"clickandjoin.app/emailserver/modules/config"
|
||||||
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
|
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
|
||||||
"github.com/tdewolff/minify/v2/minify"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func readTemplatesConfig() {
|
func readTemplatesConfig() {
|
||||||
|
@ -37,14 +36,16 @@ func loadTemplateFiles() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gocnjhelper.LogFatalf("Failed to read file, err: %s", err)
|
gocnjhelper.LogFatalf("Failed to read file, err: %s", err)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
minifiedHtml, err := minify.HTML(string(data))
|
||||||
|
|
||||||
minifiedHtml, err := minify.HTML(string(data))
|
if err != nil {
|
||||||
|
gocnjhelper.LogFatalf("Failed to minify html, err: %s", err)
|
||||||
|
} */
|
||||||
|
|
||||||
if err != nil {
|
// cache.BodyTemplates[templateName] = []byte(minifiedHtml)
|
||||||
gocnjhelper.LogFatalf("Failed to minify html, err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.BodyTemplates[templateName] = []byte(minifiedHtml)
|
cache.BodyTemplates[templateName] = []byte(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
gocnjhelper.LogDebug("FINISHED IMPORTING TEMPLATE FILES")
|
gocnjhelper.LogDebug("FINISHED IMPORTING TEMPLATE FILES")
|
||||||
|
|
|
@ -27,11 +27,12 @@ type RabbitMq struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mail struct {
|
type Mail struct {
|
||||||
Host string
|
Host string
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
Port string
|
Port string
|
||||||
From string
|
FromName string
|
||||||
|
FromEmail string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Templates struct {
|
type Templates struct {
|
||||||
|
@ -77,11 +78,12 @@ func LoadConfig() {
|
||||||
Password: os.Getenv("RABBITMQ_PASSWORD"),
|
Password: os.Getenv("RABBITMQ_PASSWORD"),
|
||||||
},
|
},
|
||||||
Mail: Mail{
|
Mail: Mail{
|
||||||
Host: os.Getenv("MAIL_HOST"),
|
Host: os.Getenv("MAIL_HOST"),
|
||||||
Username: os.Getenv("MAIL_USERNAME"),
|
Username: os.Getenv("MAIL_USERNAME"),
|
||||||
Password: os.Getenv("MAIL_PASSWORD"),
|
Password: os.Getenv("MAIL_PASSWORD"),
|
||||||
Port: os.Getenv("MAIL_PORT"),
|
Port: os.Getenv("MAIL_PORT"),
|
||||||
From: os.Getenv("MAIL_FROM"),
|
FromName: os.Getenv("MAIL_FROM_NAME"),
|
||||||
|
FromEmail: os.Getenv("MAIL_FROM_EMAIL"),
|
||||||
},
|
},
|
||||||
Templates: Templates{
|
Templates: Templates{
|
||||||
FolderPath: os.Getenv("TEMPLATES_FOLDER_PATH"),
|
FolderPath: os.Getenv("TEMPLATES_FOLDER_PATH"),
|
||||||
|
|
|
@ -58,7 +58,8 @@ func MailMessagesHandling() {
|
||||||
// only for testing
|
// only for testing
|
||||||
if !strings.HasSuffix(mailMessage.UserMail, "@roese.dev") &&
|
if !strings.HasSuffix(mailMessage.UserMail, "@roese.dev") &&
|
||||||
!strings.HasSuffix(mailMessage.UserMail, "@umbach.dev") &&
|
!strings.HasSuffix(mailMessage.UserMail, "@umbach.dev") &&
|
||||||
!strings.HasSuffix(mailMessage.UserMail, "@kk-innovation.eu") {
|
!strings.HasSuffix(mailMessage.UserMail, "@kk-innovation.eu") &&
|
||||||
|
!strings.HasSuffix(mailMessage.UserMail, "@srv1.mail-tester.com") {
|
||||||
mailMessage.UserMail = "myprojects@roese.dev"
|
mailMessage.UserMail = "myprojects@roese.dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,17 @@ package structs
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"clickandjoin.app/emailserver/modules/cache"
|
"clickandjoin.app/emailserver/modules/cache"
|
||||||
"clickandjoin.app/emailserver/modules/config"
|
"clickandjoin.app/emailserver/modules/config"
|
||||||
"clickandjoin.app/emailserver/modules/escaper"
|
"clickandjoin.app/emailserver/modules/escaper"
|
||||||
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
|
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mail struct {
|
type Mail struct {
|
||||||
|
@ -24,13 +27,15 @@ type Mail struct {
|
||||||
func (m *Mail) Send(body string) error {
|
func (m *Mail) Send(body string) error {
|
||||||
cfg := config.Cfg.Mail
|
cfg := config.Cfg.Mail
|
||||||
|
|
||||||
msg := "From: " + cfg.From + "\n" +
|
msg := "From: " + EncodeBase64(cfg.FromName) + " <" + cfg.FromEmail + ">\n" +
|
||||||
"To: " + strings.Join(m.To, ",") + "\n" +
|
"To: " + strings.Join(m.To, ",") + "\n" +
|
||||||
"Subject: " + m.Subject + "\n" +
|
"Subject: " + m.Subject + "\n" +
|
||||||
|
"Date: " + time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700") + "\n" +
|
||||||
|
"Message-ID: <" + uuid.New().String() + "@" + strings.Split(cfg.FromEmail, "@")[1] + ">\n" +
|
||||||
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
|
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
|
||||||
body
|
body
|
||||||
|
|
||||||
err := smtp.SendMail(cfg.Host+":"+cfg.Port, cache.SmtpAuth, cfg.From, m.To, []byte(msg))
|
err := smtp.SendMail(cfg.Host+":"+cfg.Port, cache.SmtpAuth, cfg.FromEmail, m.To, []byte(msg))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gocnjhelper.LogErrorf("smtp error: %s", err)
|
gocnjhelper.LogErrorf("smtp error: %s", err)
|
||||||
|
@ -84,7 +89,9 @@ func (m *Mail) RenderTemplate() (string, error) {
|
||||||
// The subject line of an email is an independent header and utf 8 must be set for it
|
// The subject line of an email is an independent header and utf 8 must be set for it
|
||||||
// https://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
|
// https://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
|
||||||
if m.LanguageId == "de" {
|
if m.LanguageId == "de" {
|
||||||
m.Subject = "=?utf-8?B?" + base64.StdEncoding.EncodeToString([]byte(m.Subject)) + "?="
|
//m.Subject = "=?utf-8?B?" + base64.StdEncoding.EncodeToString([]byte(m.Subject)) + "?="
|
||||||
|
|
||||||
|
m.Subject = EncodeBase64(m.Subject)
|
||||||
}
|
}
|
||||||
|
|
||||||
t := template.Must(template.New("").Parse(string(body)))
|
t := template.Must(template.New("").Parse(string(body)))
|
||||||
|
@ -97,3 +104,8 @@ func (m *Mail) RenderTemplate() (string, error) {
|
||||||
|
|
||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
|
||||||
|
func EncodeBase64(s string) string {
|
||||||
|
return fmt.Sprintf("=?utf-8?B?%s?=", base64.StdEncoding.EncodeToString([]byte(s)))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Arial", sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
table.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 20px auto;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
table.content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #555;
|
||||||
|
margin: 0 0 15px;
|
||||||
|
}
|
||||||
|
.verification-code {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3498db;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.booking-details {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.booking-details p {
|
||||||
|
margin: 5px 20px;
|
||||||
|
}
|
||||||
|
.booking-desc {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.booking-label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3498db;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #777;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.confirm-button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 15px;
|
||||||
|
background-color: #3498db;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.cancel-button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 15px;
|
||||||
|
background-color: #e74c3c;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.divider {
|
||||||
|
margin: 20px 0;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table class="container" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td class="content">
|
||||||
|
<h1>%title%</h1>
|
||||||
|
<p>%header%</p>
|
||||||
|
<p>%text1%</p>
|
||||||
|
<a href="{{.verifyURL}}" class="confirm-button">%verifyButton%</a>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<p>%cancelText%</p>
|
||||||
|
<a href="{{.cancelURL}}" class="cancel-button">%cancelButton%</a>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<table class="booking-details">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="booking-label">%yourAppointment%</p>
|
||||||
|
<p class="booking-desc">%appointment1%</p>
|
||||||
|
<p class="booking-desc">%appointment2%</p>
|
||||||
|
<p class="booking-desc">%appointment3%</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<p>{{.address}}</p>
|
||||||
|
|
||||||
|
<p class="footer">%footer%</p>
|
||||||
|
<a class="footer" href="https://www.kk-innovation.eu">%dsgvo%</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Arial", sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
table.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 20px auto;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
table.content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #555;
|
||||||
|
margin: 0 0 15px;
|
||||||
|
}
|
||||||
|
.verification-code {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3498db;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.booking-details {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.booking-details p {
|
||||||
|
margin: 5px 20px;
|
||||||
|
}
|
||||||
|
.booking-desc {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.booking-label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3498db;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #777;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.divider {
|
||||||
|
margin: 20px 0;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table class="container" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td class="content">
|
||||||
|
<h1>%title%</h1>
|
||||||
|
<p>%header%</p>
|
||||||
|
<p>%text1%</p>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<table class="booking-details">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="booking-label">%yourAppointment%</p>
|
||||||
|
<p class="booking-desc">%appointment1%</p>
|
||||||
|
<p class="booking-desc">%appointment2%</p>
|
||||||
|
<p class="booking-desc">%appointment3%</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<p>{{.address}}</p>
|
||||||
|
|
||||||
|
<a class="footer" href="https://www.kk-innovation.eu">%dsgvo%</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -18,6 +18,78 @@
|
||||||
"de": "Bitte gebe diesen Code in der App ein"
|
"de": "Bitte gebe diesen Code in der App ein"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"emailVerifyFailed": {
|
||||||
|
"mailSubject": {
|
||||||
|
"de": "Ihre Buchung wurde storniert"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"de": "Ihre Buchung wurde storniert"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"de": "Liebe(r) {{.name}},"
|
||||||
|
},
|
||||||
|
"text1": {
|
||||||
|
"de": "Ihre Buchung wurde storniert. Sie können gerne einen neuen Termin auf unserer Webseite festlegen."
|
||||||
|
},
|
||||||
|
"yourAppointment": {
|
||||||
|
"de": "Ihr Termin:"
|
||||||
|
},
|
||||||
|
"appointment1": {
|
||||||
|
"de": "{{.activityName}} bei {{.username}},"
|
||||||
|
},
|
||||||
|
"appointment2": {
|
||||||
|
"de": "{{.day}}, {{.dayNumber}}. {{.month}} {{.year}}"
|
||||||
|
},
|
||||||
|
"appointment3": {
|
||||||
|
"de": "von {{.startTime}} bis {{.endTime}} Uhr"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"de": "Vielen Dank, dass Sie unseren Service gewählt haben. Bei Fragen kontaktieren Sie uns gerne."
|
||||||
|
},
|
||||||
|
"dsgvo": {
|
||||||
|
"de": "Datenschutzerklärung"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"emailVerification2": {
|
||||||
|
"mailSubject": {
|
||||||
|
"de": "Bitte Bestätigen Sie Ihre Buchung"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"de": "Buchungsbestätigung"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"de": "Liebe(r) {{.name}},"
|
||||||
|
},
|
||||||
|
"text1": {
|
||||||
|
"de": "Ihre Buchung wurde erfolgreich empfangen und wartet auf Bestätigung. Bitte klicken Sie auf die untenstehende Schaltfläche, um den Vorgang abzuschließen."
|
||||||
|
},
|
||||||
|
"verifyButton": {
|
||||||
|
"de": "Buchung bestätigen"
|
||||||
|
},"cancelButton": {
|
||||||
|
"de": "Buchung stornieren"
|
||||||
|
},
|
||||||
|
"cancelText": {
|
||||||
|
"de": "Falls Sie Ihren Termin nicht wahrnehmen können, bitten wir Sie, den Termin zu stornieren."
|
||||||
|
},
|
||||||
|
"yourAppointment": {
|
||||||
|
"de": "Ihr Termin:"
|
||||||
|
},
|
||||||
|
"appointment1": {
|
||||||
|
"de": "{{.activityName}} bei {{.username}},"
|
||||||
|
},
|
||||||
|
"appointment2": {
|
||||||
|
"de": "{{.day}}, {{.dayNumber}}. {{.month}} {{.year}}"
|
||||||
|
},
|
||||||
|
"appointment3": {
|
||||||
|
"de": "von {{.startTime}} bis {{.endTime}} Uhr"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"de": "Vielen Dank, dass Sie unseren Service gewählt haben. Bei Fragen kontaktieren Sie uns gerne."
|
||||||
|
},
|
||||||
|
"dsgvo": {
|
||||||
|
"de": "Datenschutzerklärung"
|
||||||
|
}
|
||||||
|
},
|
||||||
"newUserSignIn": {
|
"newUserSignIn": {
|
||||||
"mailSubject": {
|
"mailSubject": {
|
||||||
"en": "A new sign-in was detected",
|
"en": "A new sign-in was detected",
|
||||||
|
|
Loading…
Reference in New Issue