refactor, working prototype

This commit is contained in:
2023-04-08 02:31:59 +02:00
parent 9b614b549e
commit 214f9d8599
9 changed files with 282 additions and 162 deletions

84
pkg/inline.go Normal file
View File

@@ -0,0 +1,84 @@
package gomailer
import (
"log"
"os"
"path"
"strings"
"golang.org/x/net/html"
"github.com/vanng822/go-premailer/premailer"
)
func Inline(arg string) {
out := LoadTemplate(arg, true)
dir := path.Dir(arg)
ext := path.Ext(arg)
base := strings.ReplaceAll(path.Base(arg), ext, "")
output_file := path.Join(dir, base+"_inlined"+ext)
log.Printf("Template: %s -> %s", arg, output_file)
f, err := os.Create(output_file)
if err != nil {
log.Fatal("error inlining html: " + err.Error())
}
_, err = f.WriteString(out)
if err != nil {
log.Fatal("error inlining html: " + err.Error())
}
}
func LoadTemplate(template string, inline bool) (string) {
rawhtml, err := os.ReadFile(template)
if err != nil {
log.Fatal("error loading template: " + err.Error())
}
if inline {
prem, err := premailer.NewPremailerFromBytes(rawhtml, premailer.NewOptions())
if err != nil {
log.Fatal("error inlining html: " + err.Error())
}
inlinehtml, err := prem.Transform()
if err != nil {
log.Fatal("error transforming html: " + err.Error())
}
return inlinehtml
}
return string(rawhtml)
}
func FindSrcInHtml(doc string) []string {
var results []string
reader := strings.NewReader(doc)
if document, err := html.Parse(reader); err == nil {
var parser func(*html.Node)
parser = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "img" {
var imgSrcUrl string
for _, element := range n.Attr {
if element.Key == "src" {
imgSrcUrl = element.Val
log.Print("found image:" + imgSrcUrl)
results = append(results, imgSrcUrl)
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
parser(c)
}
}
parser(document)
} else {
log.Fatalln("Parse html error", err)
}
return results
}

112
pkg/mail.go Normal file
View File

@@ -0,0 +1,112 @@
package gomailer
import (
"crypto/tls"
"github.com/wneessen/go-mail"
ht "html/template"
"log"
)
type MailSettings struct {
Subject string
From string
To string
Cc string
Inline bool
Template string
}
type MailServer struct {
Port int
Host string
Username string
Password string
Tls string
Authtype string
Skipverify bool
}
func SendMail(mailsettings MailSettings, serversettings MailServer) {
html := LoadTemplate(mailsettings.Template, true)
m := mail.NewMsg()
if err := m.From(mailsettings.From); err != nil {
log.Fatalf("failed to set From address: %s", err)
}
if err := m.To(mailsettings.From); err != nil {
log.Fatalf("failed to set To address: %s", err)
}
m.Subject(mailsettings.Subject)
htpl, err := ht.New("htmltpl").Parse(html)
if err != nil {
log.Fatalf("failed to parse text template: %s", err)
}
// embedd images
for _, val := range FindSrcInHtml(html) {
log.Println("Embedding: " + val)
m.EmbedFile(val)
}
// set template
m.SetBodyHTMLTemplate(htpl, nil)
// generate client
c, err := getClient(serversettings)
if err != nil {
log.Fatalf("failed to create mail client: %s", err)
}
// send mail
if err := c.DialAndSend(m); err != nil {
log.Fatalf("failed to send mail: %s", err)
}
}
func getClient(config MailServer) (*mail.Client, error) {
var authType mail.SMTPAuthType
switch config.Authtype {
case "plain":
authType = mail.SMTPAuthPlain
case "login":
authType = mail.SMTPAuthLogin
case "cram-md5":
authType = mail.SMTPAuthCramMD5
}
// tlsPolicy := mail.TLSOpportunistic
tlsPolicy := mail.DefaultTLSPolicy
switch config.Tls {
case "notls":
tlsPolicy = mail.NoTLS
case "mandatory":
tlsPolicy = mail.TLSMandatory
}
opts := []mail.Option{
mail.WithPort(config.Port),
mail.WithTLSPolicy(tlsPolicy),
mail.WithTLSConfig(&tls.Config{
InsecureSkipVerify: config.Skipverify,
}),
}
if config.Authtype != "nologin" {
opts = append(opts, mail.WithSMTPAuth(authType))
}
if config.Username != "" {
opts = append(opts, mail.WithUsername(config.Username))
}
if config.Password != "" {
opts = append(opts, mail.WithPassword(config.Password))
}
return mail.NewClient(
config.Host,
opts...,
)
}