Skip to content

Instantly share code, notes, and snippets.

@rmulley
Last active December 11, 2016 03:17
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rmulley/6603544 to your computer and use it in GitHub Desktop.
Save rmulley/6603544 to your computer and use it in GitHub Desktop.
Sends an email in Go with text/HTML and an attachment.
package main
import (
"bytes"
"encoding/base64"
"fmt"
"io/ioutil"
"log"
"net/smtp"
) //import
func main() {
var body, file_location, file_name, from, marker, part1, part2, part3, subject, to, to_name string
var buf bytes.Buffer
//set necessary variables
from = "from@example.com"
to = "to@example.com"
to_name = "first last"
marker = "ACUSTOMANDUNIQUEBOUNDARY"
subject = "Check out my test email"
body = "This is a test email" //for HTML emails just put HTML in the body
file_location = "file.csv"
file_name = "Your file"
//part 1 will be the mail headers
part1 = fmt.Sprintf("From: Example <%s>\r\nTo: %s <%s>\r\nSubject: %s\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=%s\r\n--%s", from, to_name, to, subject, marker, marker)
//part 2 will be the body of the email (text or HTML)
part2 = fmt.Sprintf("\r\nContent-Type: text/html\r\nContent-Transfer-Encoding:8bit\r\n\r\n%s\r\n--%s", body, marker)
//read and encode attachment
content, _ := ioutil.ReadFile(file_location)
encoded := base64.StdEncoding.EncodeToString(content)
//split the encoded file in lines (doesn't matter, but low enough not to hit a max limit)
lineMaxLength := 500
nbrLines := len(encoded) / lineMaxLength
//append lines to buffer
for i := 0; i < nbrLines; i++ {
buf.WriteString(encoded[i*lineMaxLength:(i+1)*lineMaxLength] + "\n")
} //for
//append last line in buffer
buf.WriteString(encoded[nbrLines*lineMaxLength:])
//part 3 will be the attachment
part3 = fmt.Sprintf("\r\nContent-Type: application/csv; name=\"%s\"\r\nContent-Transfer-Encoding:base64\r\nContent-Disposition: attachment; filename=\"%s\"\r\n\r\n%s\r\n--%s--", file_location, file_name, buf.String(), marker)
//send the email
err := smtp.SendMail("localhost:25", nil, from, []string{to}, []byte(part1+part2+part3))
//check for SendMail error
if err != nil {
log.Fatal(err)
} //if
} //main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment