Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
c1b3d106a0 | |||
a4fd43e03d |
4 changed files with 96 additions and 57 deletions
|
@ -3,14 +3,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"mime"
|
"mime"
|
||||||
"mime/quotedprintable"
|
"mime/quotedprintable"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MailContent struct {
|
type MailContent struct {
|
||||||
|
@ -49,30 +47,30 @@ type SmtpSettings struct {
|
||||||
Password string `json:"password"`
|
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 + " ...")
|
logger.debug("Generating and sending mails for recipient " + recipient + " ...")
|
||||||
cacheHits := 0
|
cacheHits := 0
|
||||||
cacheMisses := 0
|
cacheMisses := 0
|
||||||
mails := [][]byte{}
|
mails := []*MailContent{}
|
||||||
for _, n := range notices {
|
for _, n := range notices {
|
||||||
var data []byte
|
var mc *MailContent
|
||||||
cacheResult := (*cache)[n.Uuid]
|
cacheResult := (*mailContentCache)[n.Uuid]
|
||||||
if len(cacheResult) > 0 {
|
if cacheResult != nil {
|
||||||
cacheHits++
|
cacheHits++
|
||||||
data = cacheResult
|
mc = cacheResult
|
||||||
} else {
|
} else {
|
||||||
cacheMisses++
|
cacheMisses++
|
||||||
mailContent, err := template.generate(TemplateData{n, Version})
|
mc_, err := template.generate(TemplateData{n, Version})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.error("Could not create mail from template")
|
logger.error("Could not create mail from template")
|
||||||
logger.error(err)
|
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))
|
logger.debug(fmt.Sprintf("%v mail cache hits, %v misses", cacheHits, cacheMisses))
|
||||||
err := sendMails(
|
err := sendMails(
|
||||||
|
@ -86,48 +84,6 @@ func sendNotices(recipient string, notices []*WidNotice, template MailTemplate,
|
||||||
return nil
|
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 {
|
func mailAddressIsValid(address string) bool {
|
||||||
_, err := mail.ParseAddress(address);
|
_, err := mail.ParseAddress(address);
|
||||||
return err == nil
|
return err == nil
|
57
mail_transfer.go
Normal file
57
mail_transfer.go
Normal file
|
@ -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()
|
||||||
|
}
|
26
mail_transfer_debug.go
Normal file
26
mail_transfer_debug.go
Normal file
|
@ -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
|
||||||
|
}
|
2
main.go
2
main.go
|
@ -98,7 +98,7 @@ func main() {
|
||||||
t1 := time.Now().UnixMilli()
|
t1 := time.Now().UnixMilli()
|
||||||
newNotices := []WidNotice{}
|
newNotices := []WidNotice{}
|
||||||
lastPublished := map[string]time.Time{} // endpoint id : last published timestamp
|
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 {
|
for _, a := range enabledApiEndpoints {
|
||||||
logger.info("Querying endpoint '" + a.Id + "' for new notices ...")
|
logger.info("Querying endpoint '" + a.Id + "' for new notices ...")
|
||||||
n, t, err := a.getNotices(persistent.data.(PersistentData).LastPublished[a.Id])
|
n, t, err := a.getNotices(persistent.data.(PersistentData).LastPublished[a.Id])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue