Essential Go  Suggest an edit

Sending emails

Sometimes you need to send an email from your Go program.

It could be an alert your backend server sends to notify you that something bad happen.

It could be a notification email your cron job sends when it's finished.

It could be account registration verification e-mail for your web service. Those are called transactional emails.

It could a marketing email.

When sending emails you have 2 choices:

And we can't talk about sending email without talking about spam. Spam is why it's hard to send legitimate email and even harder to send spam email (a paradox, I know).

Because there is so much spam email, most email services (like gmail) distrust open smtp servers so setting up smtp server that won't be blacklisted is very difficult.

If you send a lot of email via your gmail (or similar account), you can be blocked by email provider.

Similarly, if you send a lot of low quality emails via service like SendGrid, they will block your account too.

All this to say that you should be conservative and stay away from sending large numbers of low quality emails if you don't want to be categorized as a spammer and blocked.

In our examples we'll use https://mailinator.com which is a service useful for debugging email sending. Mailinator provides public, throw-away email addresses. You can send an email to any.random.address@mailinator.com and see the email in a browser UI.

Sending via smtp server using net/smtp

Go has net/smtp package for sending emails. You need to know the address of smtp server (e.g. gmail's smtp server is smtp.gmail.com).

In smtp protocol you first authenticate with email address and password. For gmail it's your @gmail.com email address and password is your Google login password.

The smtp protocol allows sending authentication credentials and emails without encryption. That is a very bad idea (anyone listening to smtp traffic could read your passwords and your emails) so never do that. Most services (including gmail) disable non-encrypted part anyway, so we'll only show encrypted version.

After authentication you send the email. API provided by net/smtp is very bare-bones so you need to construct a well-formed SMTP message. A plain-text message looks like this:

From: you@gmail.com
To: recipient@mailservice.com
Subject: This is a subject

This is a body of the email.

The structure is: smtp headers followed by empty line and body.

Essential smtp headers are From, To and Subject but there are others like Cc and Bcc.

Here's the essential email send function:

func send(from, password, to, body string) error {
	msg := "From: " + from + "\n" +
		"To: " + to + "\n" +
		"Subject: Hello there\n\n" +
		body

  auth := smtp.PlainAuth("", from, password, smtpAuthServer)
	return smtp.SendMail(smtpSendServer, auth, from, []string{to}, []byte(msg))
}

Sending via gmail

To use the above code with Gmail's smtp servers, you need to know:

const smtpSendServer ="smtp.gmail.com:587"
const smtpAuthServer ="smtp.gmail.com"b

Google is very protective of your account and their smtp servers so first you need to let them know that you're ok with non-google application sending emails via their smtp server. Go to https://myaccount.google.com/lesssecureapps and set "Allow less secure apps" to "ON". This is how the UI looks today (but it might change in the future):

They might also ask you to confirm that via SMS or some other means.

Don't use Gmail to send large number of emails. Google will likely ban your account if they see that.

Be careful with your Gmail password. Follow best practices like not storing it in your source code (to avoid accidentally publishing it to the world).

Sending via Fastmail

// TODO: write me

Using email package

https://github.com/jordan-wright/email

// TODO: write me

// TODO: templating email (see https://nathanleclaire.com/blog/2013/12/17/sending-email-from-gmail-using-golang/)

TODO (from https://kinsta.com/knowledgebase/free-smtp-server/#):

  ↑ ↓ to navigate     ↵ to select     Esc to close