Skip to content

Instantly share code, notes, and snippets.

@chrisgillis
Created April 16, 2014 14:48
Show Gist options
  • Save chrisgillis/10888032 to your computer and use it in GitHub Desktop.
Save chrisgillis/10888032 to your computer and use it in GitHub Desktop.
Golang SSL SMTP Example
package main
import (
"fmt"
"log"
"net"
"net/mail"
"net/smtp"
"crypto/tls"
)
// SSL/TLS Email Example
func main() {
from := mail.Address{"", "username@example.tld"}
to := mail.Address{"", "username@anotherexample.tld"}
subj := "This is the email subject"
body := "This is an example body.\n With two lines."
// Setup headers
headers := make(map[string]string)
headers["From"] = from.String()
headers["To"] = to.String()
headers["Subject"] = subj
// Setup message
message := ""
for k,v := range headers {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + body
// Connect to the SMTP Server
servername := "smtp.example.tld:465"
host, _, _ := net.SplitHostPort(servername)
auth := smtp.PlainAuth("","username@example.tld", "password", host)
// TLS config
tlsconfig := &tls.Config {
InsecureSkipVerify: true,
ServerName: host,
}
// Here is the key, you need to call tls.Dial instead of smtp.Dial
// for smtp servers running on 465 that require an ssl connection
// from the very beginning (no starttls)
conn, err := tls.Dial("tcp", servername, tlsconfig)
if err != nil {
log.Panic(err)
}
c, err := smtp.NewClient(conn, host)
if err != nil {
log.Panic(err)
}
// Auth
if err = c.Auth(auth); err != nil {
log.Panic(err)
}
// To && From
if err = c.Mail(from.Address); err != nil {
log.Panic(err)
}
if err = c.Rcpt(to.Address); err != nil {
log.Panic(err)
}
// Data
w, err := c.Data()
if err != nil {
log.Panic(err)
}
_, err = w.Write([]byte(message))
if err != nil {
log.Panic(err)
}
err = w.Close()
if err != nil {
log.Panic(err)
}
c.Quit()
}
@demon36
Copy link

demon36 commented Jan 10, 2021

thanks a lot @chrisgillis & @cddmp

@saphena
Copy link

saphena commented Apr 22, 2021

Works perfectly, thanks for sharing

You can lose the annoying Go Vet warnings about composite literal using unkeyed fields by:-

from := mail.Address{Name:"", Address:"username@example.tld"}
to := mail.Address{Name:"", Address:"username@anotherexample.tld"}

@MArK1done
Copy link

This worked for me. Thanks a lot

@MatthewMarkgraaff
Copy link

Awesome, thanks for this!

@afa7789
Copy link

afa7789 commented Apr 5, 2022

This indeed works.
Appreaciated.

@yngfoxx
Copy link

yngfoxx commented Nov 2, 2022

Generational answer 🫡
Passed on from debugger to debugger

@didate
Copy link

didate commented Mar 1, 2023

Work well.

@denglitong
Copy link

Works great!

@SantiiRepair
Copy link

Thanks a lot

@amitsaha
Copy link

amitsaha commented Sep 5, 2023

This worked great for fastmail.com STMP. My tls config didn't require the insecure verify as well:

// TLS config
tlsconfig := &tls.Config{
	ServerName: host,
}

In case someone finds it useful, to send a HTML body, add the following headers:

body := "<html><body><h1>Hello World!</h1></body></html>"

headers["MIME-Version"] = "1.0"
headers["Content-Type"] = "text/html; charset=UTF-8"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment