Skip to content

Instantly share code, notes, and snippets.

@jpillora
Last active November 22, 2024 04:14
Show Gist options
  • Save jpillora/cb46d183eca0710d909a to your computer and use it in GitHub Desktop.
Save jpillora/cb46d183eca0710d909a to your computer and use it in GitHub Desktop.
Send email using Go (Golang) via GMail with net/smtp
package main
import (
"log"
"net/smtp"
)
func main() {
send("hello there")
}
func send(body string) {
from := "[email protected]"
pass := "..."
to := "[email protected]"
msg := "From: " + from + "\n" +
"To: " + to + "\n" +
"Subject: Hello there\n\n" +
body
err := smtp.SendMail("smtp.gmail.com:587",
smtp.PlainAuth("", from, pass, "smtp.gmail.com"),
from, []string{to}, []byte(msg))
if err != nil {
log.Printf("smtp error: %s", err)
return
}
log.Print("sent, visit http://foobarbazz.mailinator.com")
}
@puppis42
Copy link

puppis42 commented Oct 15, 2018

Great work! thanks for your codes

@Mooninghnk
Copy link

Much love !! gonna make a package for gmail

@cyberience
Copy link

This is deprecated, since Plain Auth is no longer available with gmail.

@mosleim
Copy link

mosleim commented Nov 12, 2019

@cyberience any other ideas?

@tomVlt
Copy link

tomVlt commented Nov 19, 2019

This isn't deprecated at all. I sent email to my gmail smtp relay this morning using AUTH (RFC 2554) extension. Of course gmail is expecting a client implementing the STARTTLS extension as well, like in this gist. The only problem here is that gmail won't accept clients sending the default EHLO command set with "localhost" (it's written in their docs), which is what the smtp.SendMail() func is doing by default. In order to send a custom EHLO cmd, one need to manually instantiate a new smtp.Client and call the Hello method on it, while supplying it's own valid domain name. Otherwise one will get an EOF error.

@dilip2048
Copy link

why sending mail using net/smtp goes to spam?

@mileung
Copy link

mileung commented Feb 4, 2020

I get the log error :

smtp error: 535 5.7.8 Username and Password not accepted. Learn more at
5.7.8  https://support.google.com/mail/?p=BadCredentials q15sm14168864pgm.47 - gsmtp

and an email saying: "Someone just used your password to try to sign in to your account from a non-Google app. Google blocked them, but you should check what happened. Review your account activity to make sure no one else has access."

Copy link

ghost commented Feb 4, 2020

@bokwoon95
Copy link

Enabling "less secure apps" didn't work for me, I kept getting a Error when sending mail: 535 5.7.8 Username and Password not accepted. Learn more at 5.7.8 https://support.google.com/mail/?p=BadCredentials y19sm6477535pfe.9 - gsmtp even though that was definitely my username and password.

What did was turning turning on 2FA and generating an app password instead. The app password can be used in lieu of your actual gmail password anywhere where your password is required.

@sheetalbhusari
Copy link

Although the email is getting sent. Immediately post that program exits with below error. Please suggest solution

Only one usage of each socket address (protocol/network address/port) is normally permitted.

@nedimf
Copy link

nedimf commented Jun 10, 2020

You can test it with https://mailtrap.io

@KaiserWerk
Copy link

I got this error while using golang,
2015/11/26 15:04:45 smtp error: x509: certificate signed by unknown authority
testing in python show gmail works fine
any suggestion?

That just means the CA that signed the certificate isn't recognized. This is usually the case with selfsigned certificates.

@alex-hunter3
Copy link

My god you have literally no idea how long I have been trying to solve this one tiny little issue with sending the actual email and this just solved it for me. Thank you so much!

@ashishtiwari1993
Copy link

package main

import (
	"log"
	"net/smtp"
	"errors"
)

type loginAuth struct {
  username, password string
}

func LoginAuth(username, password string) smtp.Auth {
	return &loginAuth{username, password}
}

func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
	return "LOGIN", []byte{}, nil
}

func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
	if more {
		switch string(fromServer) {
		case "Username:":
			return []byte(a.username), nil
		case "Password:":
			return []byte(a.password), nil
		default:
			return nil, errors.New("Unkown fromServer")
		}
	}
	return nil, nil
}

func main() {
	// Choose auth method and set it up
	auth := LoginAuth("user","pass")

	// Here we do it all: connect to our server, set up a message and send it
	to := []string{"[email protected]"}
	msg := []byte("To: [email protected]\r\n" +
		"Subject: New Hack\r\n" +
		"\r\n" +
		"Wonderful solution\r\n")
	err := smtp.SendMail("smtp.gmail.com:587", auth, "[email protected]", to, msg)
	if err != nil {
		log.Fatal(err)
	}
}

Wonderful hack by https://gist.github.com/andelf/5118732

I don't know why Standard library not implementing LOGIN Mechanism.

@gocs
Copy link

gocs commented May 21, 2021

gmail users: if you've seen this error: "https://support.google.com/mail/?p=InvalidSecondFactor", it means make an App Password

@elimisteve
Copy link

@ashishtiwari1993 That worked great for me, thanks!

@kunal-pahwa
Copy link

can anyone help me to change the display name of the sender i.e if I am sending mail from [email protected] so I am seeing [email protected] in the mail list of receiver inbox but I want my custom sender name instead of [email protected],
I am using SMTP plain auth

from:= [email protected]
auth := smtp.PlainAuth("", from, password, smtpHost)
smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, body.Bytes())

@whoiscarlo
Copy link

package main

import (
	"log"
	"net/smtp"
	"errors"
)

type loginAuth struct {
  username, password string
}

func LoginAuth(username, password string) smtp.Auth {
	return &loginAuth{username, password}
}

func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
	return "LOGIN", []byte{}, nil
}

func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
	if more {
		switch string(fromServer) {
		case "Username:":
			return []byte(a.username), nil
		case "Password:":
			return []byte(a.password), nil
		default:
			return nil, errors.New("Unkown fromServer")
		}
	}
	return nil, nil
}

func main() {
	// Choose auth method and set it up
	auth := LoginAuth("user","pass")

	// Here we do it all: connect to our server, set up a message and send it
	to := []string{"[email protected]"}
	msg := []byte("To: [email protected]\r\n" +
		"Subject: New Hack\r\n" +
		"\r\n" +
		"Wonderful solution\r\n")
	err := smtp.SendMail("smtp.gmail.com:587", auth, "[email protected]", to, msg)
	if err != nil {
		log.Fatal(err)
	}
}

Wonderful hack by https://gist.github.com/andelf/5118732

I don't know why Standard library not implementing LOGIN Mechanism.

@ashishtiwari1993 Thank you so much for this! I was going crazy trying to figure it out!!

@luizuatanabe
Copy link

Enabling "less secure apps" didn't work for me, I kept getting a Error when sending mail: 535 5.7.8 Username and Password not accepted. Learn more at 5.7.8 https://support.google.com/mail/?p=BadCredentials y19sm6477535pfe.9 - gsmtp even though that was definitely my username and password.

What did was turning turning on 2FA and generating an app password instead. The app password can be used in lieu of your actual gmail password anywhere where your password is required.

Thanks brother, this worked for me (replacing password for app password).

@parkare
Copy link

parkare commented Sep 30, 2022

Hi @luizuatanabe. The same thing happens to me. Due to Google's policy change in May 2022, it is now no longer possible to disable the "less secure apps" option. Do you know if there is a way to perform this validation to send emails?

@gfeyer
Copy link

gfeyer commented Oct 23, 2022

@parkare same thing here. Did you figure out a solution?

@erielmejias99
Copy link

The "less secure apps" is available for google enterprise accounts.

@saikumar1607
Copy link

https://gist.github.com/jpillora/cb46d183eca0710d909a?permalink_comment_id=3519541#gistcomment-3519541

This worked! Instead of password generate a app password and use it as password. Works like charm!!

@zodigancode
Copy link

upd: this work for me, need add parametr from in msg object
msg := []byte("From: ***@mail.com\r\n" +
"To: ***@gmail.com\r\n" +
"Subject: New Hack\r\n" +
"\r\n" +
"Wonderful solution\r\n")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment