Skip to content

Instantly share code, notes, and snippets.

@gustavohenrique
Created June 20, 2022 15:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gustavohenrique/ac265836c5f754fbe749a22e66a12de3 to your computer and use it in GitHub Desktop.
Save gustavohenrique/ac265836c5f754fbe749a22e66a12de3 to your computer and use it in GitHub Desktop.
Send mail using Go stdlib
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