all repos — navani @ 860f7d536fa7b7bea67918d8dffda4fda0f9fb19

forlater's primary mail processing service

Implement sending mail
Anirudh Oppiliappan x@icyphox.sh
Mon, 13 Sep 2021 11:03:32 +0530
commit

860f7d536fa7b7bea67918d8dffda4fda0f9fb19

parent

40dd2de2c974ae8dbe1dcdb59a9382a8ead35513

7 files changed, 290 insertions(+), 4 deletions(-)

jump to
M .gitignore.gitignore

@@ -1,1 +1,2 @@

navani +.env
M go.modgo.mod

@@ -5,6 +5,9 @@

require ( github.com/go-shiori/go-readability v0.0.0-20210627123243-82cc33435520 github.com/gomodule/redigo v1.8.5 + github.com/joegrasse/mail v1.0.0 + github.com/joegrasse/mime v0.0.0-20151001172835-f543c4783e35 // indirect + github.com/joho/godotenv v1.3.0 github.com/microcosm-cc/bluemonday v1.0.15 golang.org/x/net v0.0.0-20210908191846-a5e095526f91 // indirect mvdan.cc/xurls/v2 v2.3.0
M go.sumgo.sum

@@ -55,6 +55,12 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=

github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joegrasse/mail v1.0.0 h1:yi8Mk55sXYRZ5OhOyCzozKlj9l3HGPY6P3KEhZMCUKQ= +github.com/joegrasse/mail v1.0.0/go.mod h1:4bofkOaSoOo/INXkD1lCV5OP2MH0K6BQBQtmPX8Hf54= +github.com/joegrasse/mime v0.0.0-20151001172835-f543c4783e35 h1:onVWojd9sn2EXatgzU6X61N05cZVga4bTLyTuJY/W5M= +github.com/joegrasse/mime v0.0.0-20151001172835-f543c4783e35/go.mod h1:HCNVm2oxH9F8N1jYFa03+MWzfPddTG6n5R5P7qdgAZk= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
M mail/send.gomail/send.go

@@ -1,1 +1,45 @@

+package mail +import ( + "fmt" + "log" + "os" + + "github.com/go-shiori/go-readability" + "github.com/joegrasse/mail" + "github.com/joho/godotenv" +) + +func init() { + err := godotenv.Load() + if err != nil { + log.Fatal("error loading .env file") + } +} + +func SendArticle(article *readability.Article, to string) error { + var ( + EMAIL_USER_SECRET = os.Getenv("EMAIL_USER_SECRET") + EMAIL_PASSWORD = os.Getenv("EMAIL_PASSWORD") + EMAIL_FROM = os.Getenv("EMAIL_FROM") + SMTP_HOST = os.Getenv("SMTP_HOST") + SMTP_PORT = os.Getenv("SMTP_PORT") + ) + + email := mail.New() + email.Encryption = mail.EncryptionTLS + email.SetFrom(fmt.Sprintf("saved forlater <%s>", EMAIL_FROM)) + email.AddTo(to) + email.SetSubject(article.Title) + email.SetBody("text/plain", article.TextContent) + email.AddAlternative("text/html", article.Content) + email.Username = EMAIL_USER_SECRET + email.Password = EMAIL_PASSWORD + + err := email.Send(SMTP_HOST + ":" + SMTP_PORT) + if err != nil { + return err + } + + return nil +}
M main.gomain.go

@@ -16,23 +16,28 @@ m := mail.Mail{}

json.NewDecoder(r.Body).Decode(&m) body, err := mail.MailBody(m.Parts) if err != nil { - log.Fatal(err) + log.Println(err) } for _, u := range distinct(mail.ExtractURLs(body)) { parsedURL, err := url.Parse(u) if err != nil { - log.Fatal(err) + log.Println(err) } f, err := reader.Fetch(parsedURL.String()) if err != nil { - log.Fatal(err) + log.Println(err) } article, err := reader.Readable(f, parsedURL) if err != nil { - log.Fatal(err) + log.Println(err) + } + + err = mail.SendArticle(&article, m.From) + if err != nil { + log.Println(err) } } w.WriteHeader(204)
A templates/html.tpl

@@ -0,0 +1,181 @@

+<!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:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="x-apple-disable-message-reformatting"> + <title></title> + + <style type="text/css"> + table, td { color: #000000; } @media only screen and (min-width: 520px) { + .u-row { + width: 500px !important; + } + .u-row .u-col { + vertical-align: top; + } + + .u-row .u-col-100 { + width: 500px !important; + } + +} + +@media (max-width: 520px) { + .u-row-container { + max-width: 100% !important; + padding-left: 0px !important; + padding-right: 0px !important; + } + .u-row .u-col { + min-width: 320px !important; + max-width: 100% !important; + display: block !important; + } + .u-row { + width: calc(100% - 40px) !important; + } + .u-col { + width: 100% !important; + } + .u-col > div { + margin: 0 auto; + } +} +body { + margin: 0; + padding: 0; +} + +table, +tr, +td { + vertical-align: top; + border-collapse: collapse; +} + +.ie-container table, +.mso-container table { + table-layout: fixed; +} + +* { + line-height: inherit; +} + +a[x-apple-data-detectors='true'] { + color: inherit !important; + text-decoration: none !important; +} + +</style> +</head> + +<body class="clean-body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #f4f4f4;color: #000000"> + <!--[if IE]><div class="ie-container"><![endif]--> + <!--[if mso]><div class="mso-container"><![endif]--> + <table style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #f4f4f4;width:100%" cellpadding="0" cellspacing="0"> + <tbody> + <tr style="vertical-align: top"> + <td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top"> + <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: #f4f4f4;"><![endif]--> + + +<div class="u-row-container" style="padding: 0px;background-color: transparent"> + <div class="u-row" style="Margin: 0 auto;min-width: 320px;max-width: 500px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;"> + <div style="border-collapse: collapse;display: table;width: 100%;background-color: transparent;"> + <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:500px;"><tr style="background-color: transparent;"><![endif]--> + +<!--[if (mso)|(IE)]><td align="center" width="500" style="width: 500px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]--> +<div class="u-col u-col-100" style="max-width: 320px;min-width: 500px;display: table-cell;vertical-align: top;"> + <div style="width: 100% !important;"> + <!--[if (!mso)&(!IE)]><!--><div style="padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;"><!--<![endif]--> + +<table style="font-family:serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0"> + <tbody> + <tr> + <td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:serif;" align="left"> + + <h1 style="margin: 0px; line-height: 140%; text-align: left; word-wrap: break-word; font-weight: normal; font-family: serif; font-size: 22px;"> + {{ .Heading }} + </h1> + + </td> + </tr> + </tbody> +</table> + +<table style="font-family:serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0"> + <tbody> + <tr> + <td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:serif;" align="left"> + + <table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #BBBBBB;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%"> + <tbody> + <tr style="vertical-align: top"> + <td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%"> + <span>&#160;</span> + </td> + </tr> + </tbody> + </table> + + </td> + </tr> + </tbody> +</table> + +<table style="font-family:serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0"> + <tbody> + <tr> + <td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:serif;" align="left"> +<!-- main content --> + <div> + {{ .Body }} + </div> + + </td> + </tr> + </tbody> +</table> + +<table style="font-family:serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0"> + <tbody> + <tr> + <td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:serif;" align="left"> + + <table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #BBBBBB;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%"> + <tbody> + <tr style="vertical-align: top"> + <td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%"> + <span>&#160;</span> + </td> + </tr> + </tbody> + </table> + + </td> + </tr> + </tbody> +</table> + + <!--[if (!mso)&(!IE)]><!--></div><!--<![endif]--> + </div> +</div> +<!--[if (mso)|(IE)]></td><![endif]--> + <!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]--> + </div> + </div> +</div> + + + <!--[if (mso)|(IE)]></td></tr></table><![endif]--> + </td> + </tr> + </tbody> + </table> + <!--[if mso]></div><![endif]--> + <!--[if IE]></div><![endif]--> +</body> + +</html>
A templates/index.html

@@ -0,0 +1,46 @@

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="x-apple-disable-message-reformatting"> + </head> + <body> + <p class="wrapper"> + Test + </p> + </body> +</html> +<style> + body,table,thead,tbody,tr,td,img { + padding: 0; + margin: 0; + border: none; + border-spacing: 0px; + border-collapse: collapse; + vertical-align: top; + } + + /* Add some padding for small screens */ + .wrapper { + padding-left: 10px; + padding-right: 10px; + } + + h1,h2,h3,h4,h5,h6,p { + margin: 0; + padding: 0; + padding-bottom: 20px; + line-height: 1.6; + font-family: serif; + } + + p,a,li { + font-family: serif; + } + + img { + width: 100%; + display: block; + } +</style>