Skip to content

Instantly share code, notes, and snippets.

@zaydek
Last active March 19, 2020 23:21
Show Gist options
  • Save zaydek/b5bcbd584bfe8030408ebaea3c96762e to your computer and use it in GitHub Desktop.
Save zaydek/b5bcbd584bfe8030408ebaea3c96762e to your computer and use it in GitHub Desktop.
Automate sending personalized emails (from Gmail) using Go
package main
import (
"errors"
"log"
"net/smtp"
"os"
"strings"
)
// Represents an email account.
type Account struct {
// Unexported
auth smtp.Auth
// Exported
DisplayName string
Address string
}
// Signs into an email account (linked to Gmail).
func SignIn(displayName, username, password string) (*Account, error) {
if displayName == "" {
return nil, errors.New("displayName cannot be empty")
} else if username == "" {
return nil, errors.New("username cannot be empty")
} else if password == "" {
return nil, errors.New("password cannot be empty")
}
auth := smtp.PlainAuth("", username, password, "smtp.gmail.com")
account := &Account{
auth: auth,
DisplayName: displayName,
Address: username,
}
return account, nil
}
type Draft struct {
// Unexported
auth smtp.Auth
msg string
// Exported
From string
To string
Body string
}
// Returns a draft.
func (a *Account) Compose(displayName, address, subject, body string) Draft {
// https://golang.org/pkg/net/smtp/#example_SendMail
// https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#SMTP_transport_example
from := a.DisplayName + " <" + a.Address + ">"
to := displayName + " <" + address + ">"
draft := Draft{
auth: a.auth,
msg: "From:" + from + "\r\n" +
"To: " + to + "\r\n" +
"Subject: " + subject + "\r\n" +
"\r\n" +
body,
From: a.Address,
To: address,
Body: body,
}
return draft
}
// Sends a draft.
func (d Draft) Send() error {
return smtp.SendMail("smtp.gmail.com:587", d.auth, d.From, []string{d.To}, []byte(d.msg))
}
func must(err error) {
if err == nil {
// No-op
return
}
log.Fatal(err)
}
type Receipient struct {
displayName string
address string
firstName string
}
var receipients = []Receipient{
{
address: "[email protected]",
displayName: "John Appleseed",
firstName: "John",
},
}
func main() {
// NOTE: This program requires temporarily enabling ‘Less
// secure app access’ from Google. You can disable it
// immediately after.
//
// https://myaccount.google.com/lesssecureapps
user, err := SignIn(os.Getenv("DISPLAY_NAME"), os.Getenv("USERNAME"), os.Getenv("PASSWORD"))
must(err)
for _, r := range receipients {
draft := user.Compose(r.displayName, r.address, "Hey "+r.firstName, strings.TrimSpace(`
Hi `+r.firstName+`,
Lorem ipsum dolor sit amet, consectetur adipiscing elit…
`))
must(draft.Send())
log.Printf("sent %s", draft.To)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment