# Send an email in Go with smtp.SendMail

- Published: June 13, 2013
- Author: William Kennedy
- URL: https://www.ardanlabs.com/blog/2013/06/send-email-in-go-with-smtpsendmail.html

I wanted to send an email from my TraceLog package when a critical exception occurred. Fortunately Go's standard library has a package called smpt which can be found inside the net package. When you look at the documentation you are left wanting.<br />
<br />

I spent 20 minutes researching how to use this package. After fighting through the parameters and bugs, I came up with this sample code:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
package main<br />
<br />
import (<br />
&nbsp; &nbsp; &quot;bytes&quot;<br />
&nbsp; &nbsp; &quot;fmt&quot;<br />
&nbsp; &nbsp; &quot;net/smtp&quot;<br />
&nbsp; &nbsp; &quot;runtime&quot;<br />
&nbsp; &nbsp; &quot;strings&quot;<br />
&nbsp; &nbsp; &quot;text/template&quot;<br />
)<br />
<br />
func main() {<br />
&nbsp; &nbsp; SendEmail(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;smtp.1and1.com&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; 587,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;username@domain.com&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;password&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; []string{&quot;me@domain.com&quot;},<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;testing subject&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;&lt;html&gt;&lt;body&gt;Exception 1&lt;/body&gt;&lt;/html&gt;<html><body>Exception 1</body></html>&quot;)<br />
&nbsp; &nbsp; }<br />
<br />
func catchPanic(err &#42;error, functionName string) {<br />
&nbsp; &nbsp; if r := recover(); r != nil {<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;%s : PANIC Defered : %v\n&quot;, functionName, r)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; // Capture the stack trace<br />
&nbsp; &nbsp; &nbsp; &nbsp; buf := make([]byte, 10000)<br />
&nbsp; &nbsp; &nbsp; &nbsp; runtime.Stack(buf, false)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;%s : Stack Trace : %s&quot;, functionName, string(buf))<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#42;err = fmt.Errorf(&quot;%v&quot;, r)<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; } else if err != nil &amp;&amp; &#42;err != nil {<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;%s : ERROR : %v\n&quot;, functionName, &#42;err)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; // Capture the stack trace<br />
&nbsp; &nbsp; &nbsp; &nbsp; buf := make([]byte, 10000)<br />
&nbsp; &nbsp; &nbsp; &nbsp; runtime.Stack(buf, false)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;%s : Stack Trace : %s&quot;, functionName, string(buf))<br />
&nbsp; &nbsp; }<br />
}<br />
<br />
func SendEmail(host string, port int, userName string, password string, to []string, subject string, message string) (err error) {<br />
&nbsp; &nbsp; defer catchPanic(&amp;err, &quot;SendEmail&quot;)<br />
<br />
&nbsp; &nbsp; parameters := struct {<br />
&nbsp; &nbsp; &nbsp; &nbsp; From    string<br />
&nbsp; &nbsp; &nbsp; &nbsp; To      string<br />
&nbsp; &nbsp; &nbsp; &nbsp; Subject string<br />
&nbsp; &nbsp; &nbsp; &nbsp; Message string<br />
&nbsp; &nbsp; }{<br />
&nbsp; &nbsp; &nbsp; &nbsp; userName,<br />
&nbsp; &nbsp; &nbsp; &nbsp; strings.Join([]string(to), &quot;,&quot;),<br />
&nbsp; &nbsp; &nbsp; &nbsp; subject,<br />
&nbsp; &nbsp; &nbsp; &nbsp; message,<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; buffer := new(bytes.Buffer)<br />
<br />
&nbsp; &nbsp; template := template.Must(template.New(&quot;emailTemplate&quot;).Parse(emailScript()))<br />
&nbsp; &nbsp; template.Execute(buffer, &amp;parameters)<br />
<br />
&nbsp; &nbsp; auth := smtp.PlainAuth(&quot;&quot;, userName, password, host)<br />
<br />
&nbsp; &nbsp; err = smtp.SendMail(<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Sprintf(&quot;%s:%d&quot;, host, port),<br />
&nbsp; &nbsp; &nbsp; &nbsp; auth,<br />
&nbsp; &nbsp; &nbsp; &nbsp; userName,<br />
&nbsp; &nbsp; &nbsp; &nbsp; to,<br />
&nbsp; &nbsp; &nbsp; &nbsp; buffer.Bytes())<br />
<br />
&nbsp; &nbsp; return err<br />
}<br />
<br />
func emailScript() (script string) {<br />
&nbsp; &nbsp; return `From: {{.From}}<br />
To: {{.To}}<br />
Subject: {{.Subject}}<br />
MIME-version: 1.0<br />
Content-Type: text/html; charset=&quot;UTF-8&quot;<br />
<br />
{{.Message}}`<br />
}
</div>
<br />
The auth variable does not have to be recreated on every call. That can be created once and reused. I added my catchPanic function so you can see any exceptions that are returned while testing the code.<br />
<br />
If you look at the raw source of the email you will see how the message parameter works:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
Return-Path: <ecs .dev="" rdanstudios.com=""><br />
Delivery-Date: Wed, 12 Jun 2013 20:34:59 -0400<br />
Received: from mout.perfora.net (mout.perfora.net [X.X.X.X])<br />
&nbsp; &nbsp; by mx.perfora.net (node=mxus0) with ESMTP (Nemesis)<br />
&nbsp; &nbsp; id 0MZTCn-1V3EP13 for me@domain.com; Wed, 12 Jun 2013 20:34:58 -0400<br />
Received: from localhost (c-50-143-31-151.hsd1.fl.comcast.net [X.X.X.X])<br />
&nbsp; &nbsp; by mrelay.perfora.net (node=mrus4) with ESMTP (Nemesis)<br />
&nbsp; &nbsp; id 0Mhi4R-1V0RuN48ot-00MTc6; Wed, 12 Jun 2013 20:34:58 -0400<br /><b>
From: username@domain.com</b><br /><b>
To: me@domain.com</b><br /><b>
Subject: testing subject</b><br /><b>
MIME-version: 1.0</b><br /><b>
Content-Type: text/html; charset=&quot;UTF-8&quot;</b><br />
Message-Id: &lt;0mhi4r- data-blogger-escaped-mrelay.perfora.net=&quot;&quot;&gt;<br />
Date: Wed, 12 Jun 2013 20:34:56 -0400<br />
Envelope-To: me@domain.com<br /><br />
</ecs><br />
<div class="p1">
<b>&lt;html&gt;&lt;body&gt;Exception 1&lt;/body&gt;&lt;/html&gt;</b></div>
</div>
<br />
<br />
As always I hope this sample program saves you time and&nbsp;aggravation.<br />
<br />
