Created
June 20, 2022 15:18
-
-
Save gustavohenrique/ac265836c5f754fbe749a22e66a12de3 to your computer and use it in GitHub Desktop.
Send mail using Go stdlib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"bytes" | |
"crypto/tls" | |
"encoding/base64" | |
"fmt" | |
"net/mail" | |
"net/smtp" | |
"text/template" | |
) | |
type Sendmail interface { | |
Context(context string) Sendmail | |
ParseBody(tpl string, data map[string]string) Sendmail | |
ParseSubject(tpl string, data map[string]string) Sendmail | |
SendTo(email string) error | |
} | |
type SMTP struct { | |
user string | |
secret string | |
sender string | |
from string | |
server string | |
port string | |
to string | |
context string | |
body string | |
subject string | |
} | |
type Config struct { | |
SMTPUser string `json:"SMTP_USER" envconfig:"SMTP_USER"` | |
SMTPSecret string `json:"SMTP_SECRET" envconfig:"SMTP_SECRET"` | |
SMTPSender string `json:"SMTP_SENDER" envconfig:"SMTP_SENDER"` | |
SMTPFrom string `json:"SMTP_FROM" envconfig:"SMTP_FROM"` | |
SMTPServer string `json:"SMTP_SERVER" envconfig:"SMTP_SERVER"` | |
SMTPPort string `json:"SMTP_PORT" envconfig:"SMTP_PORT"` | |
} | |
func NewSendmail(config *Config) interfaces.Sendmail { | |
user := config.SMTPUser | |
secret := config.SMTPSecret | |
sender := config.SMTPSender | |
from := config.SMTPFrom | |
server := config.SMTPServer | |
port := config.SMTPPort | |
return &SMTP{ | |
user: user, | |
secret: secret, | |
sender: sender, | |
from: from, | |
server: server, | |
port: port, | |
} | |
} | |
func (e *SMTP) ParseBody(tpl string, data map[string]string) interfaces.Sendmail { | |
e.body = e.parseTemplate(tpl, data) | |
return e | |
} | |
func (e *SMTP) ParseSubject(tpl string, data map[string]string) interfaces.Sendmail { | |
e.subject = e.parseTemplate(tpl, data) | |
return e | |
} | |
func (e *SMTP) parseTemplate(tpl string, data map[string]string) string { | |
t := template.Must(template.New("tpl").Parse(tpl)) | |
buf := new(bytes.Buffer) | |
t.Execute(buf, data) | |
return buf.String() | |
} | |
func (e *SMTP) SendTo(email string) error { | |
e.to = email | |
return e.sendHTML() | |
} | |
func (e *SMTP) Context(context string) interfaces.Sendmail { | |
e.context = context | |
return e | |
} | |
func (e *SMTP) sendHTML() error { | |
message := e.writeHTMLEmail(e.to, e.subject, e.body) | |
return e.send(e.to, e.subject, message) | |
} | |
func (e *SMTP) send(dest string, subject, bodyMessage string) error { | |
tlsconfig := &tls.Config{ | |
InsecureSkipVerify: true, | |
ServerName: e.server, | |
} | |
servername := fmt.Sprintf("%s:%s", e.server, e.port) | |
conn, err := tls.Dial("tcp", servername, tlsconfig) | |
if err != nil { | |
return err | |
} | |
c, err := smtp.NewClient(conn, e.server) | |
if err != nil { | |
return err | |
} | |
defer c.Quit() | |
auth := smtp.PlainAuth("", e.user, e.secret, e.server) | |
if err = c.Auth(auth); err != nil { | |
return err | |
} | |
if err = c.Mail(e.sender); err != nil { | |
return err | |
} | |
if err = c.Rcpt(dest); err != nil { | |
return err | |
} | |
w, err := c.Data() | |
if err != nil { | |
return err | |
} | |
_, err = w.Write([]byte(bodyMessage)) | |
if err != nil { | |
return err | |
} | |
err = w.Close() | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
func (e *SMTP) writeHTMLEmail(to, subject, bodyMessage string) string { | |
return e.writeEmail(to, "text/html", subject, bodyMessage) | |
} | |
func (e *SMTP) writeEmail(to, contentType, subject, bodyMessage string) string { | |
from := mail.Address{Name: e.from, Address: e.sender} | |
header := make(map[string]string) | |
header["From"] = from.String() | |
header["To"] = to | |
header["Subject"] = subject | |
header["MIME-Version"] = "1.0" | |
header["Content-Type"] = fmt.Sprintf("%s; charset=\"utf-8\"", contentType) | |
header["Content-Transfer-Encoding"] = "base64" | |
var message string | |
for key, value := range header { | |
message += fmt.Sprintf("%s: %s\r\n", key, value) | |
} | |
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(bodyMessage)) | |
return message | |
} | |
type Template struct { | |
Subject string | |
Body string | |
} | |
type EmailData struct { | |
FullName string | |
ProductName string | |
} | |
func main() { | |
config: &Config{ | |
SMTPUser: "apikey", | |
SMTPSecret: "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", | |
SMTPSender: "no-reply@domain.com" | |
SMTPFrom: "Minha Empresa", | |
SMTPServer: "smtp.sendgrid.net", | |
SMTPPort: 465, | |
} | |
data := map[string]string{ | |
"fullName": "Meu usuário querido", | |
"productName": "Meu incrível produto", | |
} | |
tpl := Template{ | |
Subject: "Bem-vindo {{ .FullName }}", | |
Body: "<p>Parabéns {{ .FullName }}! Você acaba de comprar {{ .ProductName }}</p>", | |
} | |
data := map[string]string{ | |
"FullName": "Henrique", | |
"ProductName": "Notebook", | |
} | |
sendmail := NewSendmail(config) | |
err := sendmail. | |
ParseSubject(tpl.Subject, data). | |
ParseBody(tpl.Body, data). | |
SendTo("cliente@gmail.com") | |
fmt.Println("Error?", err) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment