diff --git a/mail.go b/mail_common.go similarity index 51% rename from mail.go rename to mail_common.go index a37c933..71e29bf 100644 --- a/mail.go +++ b/mail_common.go @@ -3,14 +3,12 @@ package main import ( - "crypto/tls" "fmt" "mime" "mime/quotedprintable" "net/mail" "net/smtp" "strings" - "time" ) type MailContent struct { @@ -49,30 +47,30 @@ type SmtpSettings struct { Password string `json:"password"` } -func sendNotices(recipient string, notices []*WidNotice, template MailTemplate, auth smtp.Auth, smtpConfig SmtpSettings, cache *map[string][]byte) error { +func sendNotices(recipient string, notices []*WidNotice, template MailTemplate, auth smtp.Auth, smtpConfig SmtpSettings, mailContentCache *map[string]*MailContent) error { logger.debug("Generating and sending mails for recipient " + recipient + " ...") cacheHits := 0 cacheMisses := 0 - mails := [][]byte{} + mails := []*MailContent{} for _, n := range notices { - var data []byte - cacheResult := (*cache)[n.Uuid] - if len(cacheResult) > 0 { + var mc *MailContent + cacheResult := (*mailContentCache)[n.Uuid] + if cacheResult != nil { cacheHits++ - data = cacheResult + mc = cacheResult } else { cacheMisses++ - mailContent, err := template.generate(TemplateData{n, Version}) + mc_, err := template.generate(TemplateData{n, Version}) if err != nil { logger.error("Could not create mail from template") logger.error(err) + } else { + mc = &mc_ + // add to cache + (*mailContentCache)[n.Uuid] = mc } - // serialize mail - data = mailContent.serializeValidMail(smtpConfig.From, recipient) - // add to cache - (*cache)[n.Uuid] = data } - mails = append(mails, data) + mails = append(mails, mc) } logger.debug(fmt.Sprintf("%v mail cache hits, %v misses", cacheHits, cacheMisses)) err := sendMails( @@ -86,48 +84,6 @@ func sendNotices(recipient string, notices []*WidNotice, template MailTemplate, return nil } -func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, data [][]byte) error { - addr := fmt.Sprintf("%v:%v", smtpConf.ServerHost, smtpConf.ServerPort) - logger.debug("Connecting to mail server at " + addr + " ...") - connection, err := smtp.Dial(addr) - if err != nil { return err } - defer connection.Close() - // can leave out connection.Hello - hasTlsExt, _ := connection.Extension("starttls") - if hasTlsExt { - err = connection.StartTLS(&tls.Config{ServerName: smtpConf.ServerHost}) - if err != nil { return err } - logger.debug("Mail Server supports TLS") - } else { - logger.debug("Mail Server doesn't support TLS") - } - logger.debug("Authenticating to mail server ...") - err = connection.Auth(auth) - if err != nil { return err } - if logger.LogLevel >= 3 { - fmt.Printf("DEBUG %v Sending mails to server ", time.Now().Format("2006/01/02 15:04:05.000000")) - } - for _, d := range data { - err = connection.Mail(smtpConf.From) - if err != nil { return err } - err = connection.Rcpt(to) - if err != nil { return err } - writer, err := connection.Data() - if err != nil { return err } - _, err = writer.Write(d) - if err != nil { return err } - err = writer.Close() - if err != nil { return err } - if logger.LogLevel >= 3 { - print(".") - } - } - if logger.LogLevel >= 3 { - print("\n") - } - return connection.Quit() -} - func mailAddressIsValid(address string) bool { _, err := mail.ParseAddress(address); return err == nil diff --git a/mail_transfer.go b/mail_transfer.go new file mode 100644 index 0000000..45675d3 --- /dev/null +++ b/mail_transfer.go @@ -0,0 +1,57 @@ +// +build !debug_mail_transfer +// Copyright (c) 2023 Julian Müller (ChaoticByte) + +package main + +import ( + "crypto/tls" + "fmt" + "net/smtp" + "time" +) + + +func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, mails []*MailContent) error { + addr := fmt.Sprintf("%v:%v", smtpConf.ServerHost, smtpConf.ServerPort) + logger.debug("Connecting to mail server at " + addr + " ...") + connection, err := smtp.Dial(addr) + if err != nil { return err } + defer connection.Close() + // can leave out connection.Hello + hasTlsExt, _ := connection.Extension("starttls") + if hasTlsExt { + err = connection.StartTLS(&tls.Config{ServerName: smtpConf.ServerHost}) + if err != nil { return err } + logger.debug("Mail Server supports StartTLS") + } else { + logger.debug("Mail Server doesn't support StartTLS") + } + logger.debug("Authenticating to mail server ...") + err = connection.Auth(auth) + if err != nil { return err } + if logger.LogLevel >= 3 { + fmt.Printf("DEBUG %v Sending mails to server ", time.Now().Format("2006/01/02 15:04:05.000000")) + } + for _, mc := range mails { + // serialize mail + d := mc.serializeValidMail(smtpConf.From, to) + // send mail + err = connection.Mail(smtpConf.From) + if err != nil { return err } + err = connection.Rcpt(to) + if err != nil { return err } + writer, err := connection.Data() + if err != nil { return err } + _, err = writer.Write(d) + if err != nil { return err } + err = writer.Close() + if err != nil { return err } + if logger.LogLevel >= 3 { + print(".") + } + } + if logger.LogLevel >= 3 { + print("\n") + } + return connection.Quit() +} diff --git a/mail_transfer_debug.go b/mail_transfer_debug.go new file mode 100644 index 0000000..60fb2bd --- /dev/null +++ b/mail_transfer_debug.go @@ -0,0 +1,26 @@ +// +build debug_mail_transfer +// Copyright (c) 2023 Julian Müller (ChaoticByte) + +package main + +import ( + "fmt" + "net/smtp" +) + +func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, mails []*MailContent) error { + logger.warn("Mail Transfer Debugging is active. Not connecting.") + logger.info("MAIL TRANSFER: \n\n") + for _, mc := range mails { + // serialize mail + d := mc.serializeValidMail(smtpConf.From, to) + // output mail + fmt.Println("MAIL FROM:" + smtpConf.From) + fmt.Println("RCPT TO:" + to) + fmt.Println("DATA") + fmt.Println(string(d)) + fmt.Println(".") + } + fmt.Print("\n\n") + return nil +} diff --git a/main.go b/main.go index 8fc4ab0..d239bf0 100644 --- a/main.go +++ b/main.go @@ -98,7 +98,7 @@ func main() { t1 := time.Now().UnixMilli() newNotices := []WidNotice{} lastPublished := map[string]time.Time{} // endpoint id : last published timestamp - cache := map[string][]byte{} // cache generated emails for reuse + cache := map[string]*MailContent{} // cache generated emails for reuse for _, a := range enabledApiEndpoints { logger.info("Querying endpoint '" + a.Id + "' for new notices ...") n, t, err := a.getNotices(persistent.data.(PersistentData).LastPublished[a.Id])