go: email with attachments
Here is an example showing how to use the gomail package to produce email containing plain-text content, alternative html content with an embedded image, and an HTML attachment.
It doesn’t worry about trying to actually send mail but only tries to create a well-composed message. See the documentation or repository on GitHub for more details.
package main
import (
"encoding/base64"
"fmt"
"net/smtp"
"gopkg.in/gomail.v1"
)
func main() {
m := gomail.NewMessage()
m.SetHeaders(map[string][]string{
"From": {"alice@foobar.com"},
"To": {"bob@foobar.com"},
"Subject": {"inbound crap"},
})
m.SetBody("text/plain", "hello. i am sending you crap.")
// from: http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever
blankEncoded := "R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
// i'm a bad person. ignoring errors!
blankContent, _ := base64.StdEncoding.DecodeString(blankEncoded)
blank := gomail.CreateFile("blank.gif", blankContent)
m.Embed(blank)
m.AddAlternative("text/html", `<p>hello. i am sending you <img border="2" src="cid:blank.gif" alt="blank" /> crap.</p>`)
crap := gomail.CreateFile("crap.html", []byte("<!doctype html>\n<html><title>crap</title><body>this is crap, y'know?</body></html>"))
m.Attach(crap)
mailDumper := func(addr string, a smtp.Auth, from string, to []string, msg []byte) error {
// This dumps out the mail message so it can piped straight to `sendmail -t`
// and proves that this is a parsable message.
fmt.Print(string(msg))
return nil
}
mailer := gomail.NewMailer("localhost", "user", "pass", 465, gomail.SetSendMail(mailDumper))
mailer.Send(m)
}
Here is the resulting message:
Date: Wed, 29 Apr 2015 16:33:56 -0400
Content-Type: multipart/mixed; boundary=21ee3da964c7bf70def62adb9ee1a061747003c026e363e47231258c48f1
From: alice@foobar.com
To: bob@foobar.com
Subject: inbound crap
Mime-Version: 1.0
--21ee3da964c7bf70def62adb9ee1a061747003c026e363e47231258c48f1
Content-Type: multipart/related; boundary=76a1282373c08a65dd49db1dea2c55111fda9a715c89720a844fabb7d497
--76a1282373c08a65dd49db1dea2c55111fda9a715c89720a844fabb7d497
Content-Type: multipart/alternative; boundary=4186c39e13b2140c88094b3933206336f2bb3948db7ecf064c7a7d7473f2
--4186c39e13b2140c88094b3933206336f2bb3948db7ecf064c7a7d7473f2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
hello. i am sending you crap.
--4186c39e13b2140c88094b3933206336f2bb3948db7ecf064c7a7d7473f2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p>hello. i am sending you <img border=3D"2" src=3D"cid:blank.gif" alt=3D"bl=
ank" /> crap.</p>
--4186c39e13b2140c88094b3933206336f2bb3948db7ecf064c7a7d7473f2--
--76a1282373c08a65dd49db1dea2c55111fda9a715c89720a844fabb7d497
Content-Type: image/gif; name="blank.gif"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="blank.gif"
Content-ID: <blank.gif>
R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
--76a1282373c08a65dd49db1dea2c55111fda9a715c89720a844fabb7d497--
--21ee3da964c7bf70def62adb9ee1a061747003c026e363e47231258c48f1
Content-Type: text/html; charset=utf-8; name="crap.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="crap.html"
PCFkb2N0eXBlIGh0bWw+CjxodG1sPjx0aXRsZT5jcmFwPC90aXRsZT48Ym9keT50aGlzIGlzIGNy
YXAsIHkna25vdz88L2JvZHk+PC9odG1sPg==
--21ee3da964c7bf70def62adb9ee1a061747003c026e363e47231258c48f1--