Golang package for send email. Support keep alive connection, TLS and SSL. Easy for bulk SMTP.

Overview

Go Simple Mail

The best way to send emails in Go with SMTP Keep Alive and Timeout for Connect and Send.

Go Report Card go.dev

IMPORTANT

Examples in this README are for v2.2.0 and above. Examples for older versions can be found here.

The minimum Go version is 1.13, for Go 1.12 and older use branch go1.12.

Breaking change in 2.2.0: The signature of SetBody and AddAlternative used to accept strings ("text/html" and "text/plain") and not require on of the contentType constants (TextHTML or TextPlain). Upgrading, while not quite following semantic versioning, is quite simple:

  email := mail.NewMSG()
- email.SetBody("text/html", htmlBody)
- email.AddAlternative("text/plain", plainBody)
+ email.SetBody(mail.TextHTML, htmlBody)
+ email.AddAlternative(mail.TextPlain, plainBody)

Introduction

Go Simple Mail is a simple and efficient package to send emails. It is well tested and documented.

Go Simple Mail can only send emails using an SMTP server. But the API is flexible and it is easy to implement other methods for sending emails using a local Postfix, an API, etc.

This package contains (and is based on) two packages by Joe Grasse:

A lot of changes in Go Simple Mail were sent with not response.

Features

Go Simple Mail supports:

  • Multiple Attachments with path
  • Multiple Attachments in base64
  • Multiple Attachments from bytes (since v2.6.0)
  • Inline attachments from file, base64 and bytes (bytes since v2.6.0)
  • Multiple Recipients
  • Priority
  • Reply to
  • Set sender
  • Set from
  • Allow sending mail with different envelope from (since v2.7.0)
  • Embedded images
  • HTML and text templates
  • Automatic encoding of special characters
  • SSL and TLS
  • Unencrypted connection (not recommended)
  • Sending multiple emails with the same SMTP connection (Keep Alive or Persistent Connection)
  • Timeout for connect to a SMTP Server
  • Timeout for send an email
  • Return Path
  • Alternative Email Body
  • CC and BCC
  • Add Custom Headers in Message
  • Send NOOP, RESET, QUIT and CLOSE to SMTP client
  • PLAIN, LOGIN and CRAM-MD5 Authentication (since v2.3.0)
  • Custom TLS Configuration (since v2.5.0)

Documentation

https://pkg.go.dev/github.com/xhit/go-simple-mail/v2?tab=doc

Download

This package uses go modules.

$ go get github.com/xhit/go-simple-mail/v2

Usage

package main

import (
	"log"

	"github.com/xhit/go-simple-mail/v2"
)

const htmlBody = `<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Hello Gophers!</title>
	</head>
	<body>
		<p>This is the <b>Go gopher</b>.</p>
		<p><img src="cid:Gopher.png" alt="Go gopher" /></p>
		<p>Image created by Renee French</p>
	</body>
</html>`

func main() {
	server := mail.NewSMTPClient()

	// SMTP Server
	server.Host = "smtp.example.com"
	server.Port = 587
	server.Username = "[email protected]"
	server.Password = "examplepass"
	server.Encryption = mail.EncryptionTLS

	// Since v2.3.0 you can specified authentication type:
	// - PLAIN (default)
	// - LOGIN
	// - CRAM-MD5
	// server.Authentication = mail.AuthPlain

	// Variable to keep alive connection
	server.KeepAlive = false

	// Timeout for connect to SMTP Server
	server.ConnectTimeout = 10 * time.Second

	// Timeout for send the data and wait respond
	server.SendTimeout = 10 * time.Second

	// Set TLSConfig to provide custom TLS configuration. For example,
	// to skip TLS verification (useful for testing):
	server.TLSConfig = &tls.Config{InsecureSkipVerify: true}

	// SMTP client
	smtpClient,err := server.Connect()

	if err != nil{
		log.Fatal(err)
	}

	// New email simple html with inline and CC
	email := mail.NewMSG()
	email.SetFrom("From Example <[email protected]>").
		AddTo("[email protected]").
		AddCc("[email protected]").
		SetSubject("New Go Email")

	email.SetBody(mail.TextHTML, htmlBody)

	email.AddInline("/path/to/image.png", "Gopher.png")

	// Call Send and pass the client
	err = email.Send(smtpClient)
	if err != nil {
		log.Println(err)
	} else {
		log.Println("Email Sent")
	}
}

Send multiple emails in same connection

	//Set your smtpClient struct to keep alive connection
	server.KeepAlive = true

	for _, to := range []string{
		"[email protected]",
		"[email protected]",
		"[email protected]",
	} {
		// New email simple html with inline and CC
		email := mail.NewMSG()
		email.SetFrom("From Example <[email protected]>").
			AddTo(to).
			SetSubject("New Go Email")

		email.SetBody(mail.TextHTML, htmlBody)
		email.AddInline("/path/to/image.png", "Gopher.png")

		// Call Send and pass the client
		err = email.Send(smtpClient)
		if err != nil {
			log.Println(err)
		} else {
			log.Println("Email Sent")
		}
	}

More examples

See example/example_test.go.

Issues
  • Unify attachment handling API

    Unify attachment handling API

    Currently we have the following function signatures for adding attachments to an Email struct:

    func (email *Email) AddAttachment(file string, name ...string) *Email
    func (email *Email) AddAttachmentBase64(b64File, name string) *Email
    func (email *Email) AddAttachmentData(data []byte, filename, mimeType string) *Email
    func (email *Email) AddInline(file string, name ...string) *Email
    func (email *Email) AddInlineBase64(b64File, name, mimeType string) *Email
    func (email *Email) AddInlineData(data []byte, filename, mimeType string) *Email
    

    For some reason AddAttachment and AddInline are variadic but only accept one name:

            if len(name) > 1 {
                    email.Error = errors.New("Mail Error: Attach can only have a file and an optional name")
                    return email
            }
    

    Other functions take name as parameter and possibly also mimeType.

    I propose we modify all these functions to accept name and mimeType. So the API would become:

    func (email *Email) AddAttachment(file, name, mimeType string) *Email
    func (email *Email) AddAttachmentBase64(b64Data, name, mimeType string) *Email
    func (email *Email) AddAttachmentData(data []byte, name, mimeType string) *Email
    func (email *Email) AddInline(file, name, mimeType string) *Email
    func (email *Email) AddInlineBase64(b64Data, name, mimeType string) *Email
    func (email *Email) AddInlineData(data []byte, name, mimeType string) *Email
    

    edit. I changed argument name b64File -> b64Data so it is consistent with file and data arguments.

    enhancement 
    opened by jlinnosa 13
  • Create interface from type to improve the testability of this library

    Create interface from type to improve the testability of this library

    It is very hard to test the usage of this library in other projects.

    With these interfaces, it will be easy to mock this library.

    When developing other projects, the functionality of external libraries should not have to be tested as well.

    opened by nikolaistraessle 8
  • Allow to add inplace in-memory data

    Allow to add inplace in-memory data

    I can't use files in some environment - the file system is read-only.

    opened by falconandy 8
  • Allow sending mail with different envelope from.

    Allow sending mail with different envelope from.

    It's often necessary to send mails where the 'From' header and the SMTP envelope email address differ. The new function 'SendEnvelopeFrom' allows this.

    opened by davrux 6
  • Rfc1870 fix

    Rfc1870 fix

    As i'm see client not support SIZE as expected. I add message SIZE as it described in RFC 1870.

    Can you check my propose for extend mail command in smtp.go ? I also need this extensions

    • CHECKPOINT RFC 1845
    • BINARYMIME RFC 3030
    • CHUNKING RFC 3030

    CHECKPOINT also need extend mail from command like this PR for size

    And CHUNKING and BINARYMIME need additional command and disable break commands on lines limit by 80

    opened by norguhtar 5
  • Client does not reconnect on network failure, even with KeepAlive

    Client does not reconnect on network failure, even with KeepAlive

    I had a smtp connexion OK (with keepalive), when suddently the remote server closed it. Since this event no mail were sent, event if the remote server is back online.

    Here is the log i have each time i send a mail since the event.

    write tcp 127.0.0.1:60591->127.0.0.1:25: wsasend: An existing connection was forcibly closed by the remote host.  
    

    The only way to get my mails sent again, was by killing/starting my app.

    You can easily reproduce this case with mailHog, by activating "JIM" with -invite-jim -jim-disconnect "1"

    opened by vjeantet 5
  • Thread safety

    Thread safety

    Hi! Is it thread save to invoke server.Connect on multiple "threads", or I need to create new server each time?

    opened by saesols 4
  • Support for gmail?

    Support for gmail?

    Many clients simply error out on gmail due to "Less Secure Access"; Does this library have a fix for that?

    opened by fr3fou 4
  • Can't go get

    Can't go get

    $ go get -u github.com/xhit/go-simple-mail/v2
    cannot find package "github.com/xhit/go-simple-mail/v2" in any of:
            ...\github.com\xhit\go-simple-mail\v2 (from $GOROOT)
            ...\github.com\xhit\go-simple-mail\v2 (from $GOPATH)
    

    I guess this is related to go modules?

    opened by ivanjaros 4
  • Weird naming `NewSMTPClient`

    Weird naming `NewSMTPClient`

    NewSMTPClient should be NewSMTPServer or at least it should be documented, why this is how it is.

    documentation 
    opened by IceflowRE 3
  • Add methods to inspect body

    Add methods to inspect body

    Hey, Firstly I would like to say that this is an awesome package.

    I would to request a set of methods to access the msg body for both html and alternative/text. Would this be possible?

    enhancement 
    opened by Jaskerv 3
  • email.GetMessage not return Bcc address ?

    email.GetMessage not return Bcc address ?

    i need get full msg for append to draft mailbox.

    needs decision 
    opened by andiksetyawan 3
  • Context

    Context

    Can you make connecting to the server and sending messages using context?

    help wanted 
    opened by geoirb 6
  • Get encrypted function

    Get encrypted function

    Please provide a function that can get the encryption, For example: SMTP = > encryption TLS

    const (
    	// EncryptionNone uses no encryption when sending email
    	EncryptionNone encryption = iota
    	// EncryptionSSL sets encryption type to SSL when sending email
    	EncryptionSSL
    	// EncryptionTLS sets encryption type to TLS when sending email
    	EncryptionTLS
    )
    
    enhancement 
    opened by hb0730 6
  • Use mail.Address instead of plain strings

    Use mail.Address instead of plain strings

    With simple plain strings we are unable to set the name, only the address of the recipient(s). Use mail.Address.String() for headers, where full format works, and use mail.Address.Address for smtp's mail and rcpt methods to make it work with the smtp protocol.

    enhancement 
    opened by ivanjaros 4
  • How to run tests?

    How to run tests?

    The example_test.go wants to connect to localhost:25. I'm not certain, I want to install a mail server on my machine. I definitively won't install a Go environment on my mail server.

    $ go test ./...
    --- FAIL: TestSendMail (0.00s)
        example_test.go:50: Expected nil, got Mail Error on dailing with encryption type None: dial tcp [::1]:25: connect: connection refused connecting to client
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
            panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x63d18c]
    
    goroutine 19 [running]:
    testing.tRunner.func1.1(0x6749a0, 0x8a9cf0)
            /home/dm/.local/go/src/testing/testing.go:941 +0x3d0
    testing.tRunner.func1(0xc00014e240)
            /home/dm/.local/go/src/testing/testing.go:944 +0x3f9
    panic(0x6749a0, 0x8a9cf0)
            /home/dm/.local/go/src/runtime/panic.go:967 +0x15d
    github.com/xhit/go-simple-mail/v2.(*SMTPClient).Noop(...)
            /home/dm/code/go-simple-mail/email.go:830
    github.com/xhit/go-simple-mail/v2.TestSendMail(0xc00014e240)
            /home/dm/code/go-simple-mail/example_test.go:55 +0x1bc
    testing.tRunner(0xc00014e240, 0x6cc578)
            /home/dm/.local/go/src/testing/testing.go:992 +0xdc
    created by testing.(*T).Run
            /home/dm/.local/go/src/testing/testing.go:1043 +0x357
    FAIL    github.com/xhit/go-simple-mail/v2       0.005s
    FAIL
    

    I'd be OK with running the tests in a confined environment, like a Docker container. Do you have something prepared for this?

    In the same vein: Are there plans to automate test runs on commit, with say Github Actions?

    help wanted 
    opened by dmke 10
Releases(v2.10.0)
  • v2.10.0(Jul 7, 2021)

  • v2.9.1(May 21, 2021)

  • v2.9.0(May 6, 2021)

    This version add a new API for attachments called Attach that receive a new public struct called File with the file to attach. The old APIs are deprecated.

    Added a new API SetBodyData to set body from []byte to help reducing the memory allocation when converting a []byte-> string-> []byte buffer. #36

    Also, thanks to @jlinnosa to help with these changes and the new Attach API:

    • Implement inline attachment support for Base64 encoded strings with new API func (email *Email) AddInlineBase64(b64File string, name string, mimeType string)
    • Refactor attachments and test added.
    Source code(tar.gz)
    Source code(zip)
  • v2.8.1(Apr 2, 2021)

    Correct encryption types SSL/TLS and STARTTLS

    Previously EncryptionTLS correspond to STARTTLS and EncryptionSSL correspond to SSL/TLS.

    To avoid confusion in names, two new const were created:

    • EncryptionSTARTTLS for STARTTLS
    • EncryptionSSLTLS for SSL/TLS

    EncryptionTLS and EncryptionSSL are deprecated and will be removed in future.

    Also, thanks for this contributors for these changes:

    @simaotwx

    • Fix typo in error message 8dcac4eda

    @simonerota

    • Properly detect mime type when attaching using base64 c1a7db715
    Source code(tar.gz)
    Source code(zip)
  • v2.8.0(Feb 15, 2021)

    @davrux:

    • Allows to use a helo other than 'localhost'.

    @norguhtar

    • Fix add header to correct get from headers.
    • RFC1870 fix (send size if extension is supported)

    @alex1989hu

    • Add golangci-lint action

    @yene

    • Changed Encryption type to be public so the value can be passed around

    @vjeantet

    • New public function to get recipients of email GetRecipients
    • New function to send a RFC822 formatted message SendMessage
    Source code(tar.gz)
    Source code(zip)
  • v2.7.0(Dec 15, 2020)

  • v2.6.0(Dec 10, 2020)

  • v2.5.1(Aug 19, 2020)

  • v2.5.0(Jul 16, 2020)

    • Custom TLS Configuration
    • Allow to unwrap textproto errors from smtp connection failures

    This version requires Go 1.13+

    Thanks to @codestation!

    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(May 26, 2020)

  • v2.3.1(Apr 11, 2020)

  • v2.3.0(Dec 17, 2019)

    In this version is possible to specify PLAIN, LOGIN and CRAM-MD5 authentication

    For this, in SMTPServer struct obtained by NewSMTPClient() function, the Authentication variable should be a authType: AuthPlain, AuthLogin, AuthCRAMMD5

    If was not specified, default is AuthPlain.

    Also, added compatibility to Go Modules.

    Source code(tar.gz)
    Source code(zip)
  • v2.2.2(Oct 27, 2019)

    iota corrections and SendTimeout improved

    • new private function sendMailProcess for send the mail. Function is called in private function send
    • improved SendTimeout, if 0 then send call directly to sendMailProcess, else, sendMailProcess is called in goroutine and return the result in channel smtpSendChannel if timeout never happens
    • change direction of iota for encryption, encoding, and contentType (this don't break anything)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Oct 16, 2019)

    smtp.go: expectCode correction for RCPT for match 25x return code.

    Earlier versions match only 250.

    Match 25x return like valid code the 251 (User not local; will forward to )

    251 code is deprecated in SMTP, but who knows who still uses it.

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Oct 9, 2019)

    This version break your code!

    • SetBody and AddAlternative receive contentType var type instead string. Earlier the string were text/html and text/plain, now you need call mail.TextHTML or mail.TextPlain

    • Code refactored for make all smtp and auth functions private. If you use it or you need a function in these files, pull a request for add it to email.go if need it.

    • Added header.go and test, now you don't need download other dependencies.

    • Comments updated in al files

    • Updated readme and test

    Source code(tar.gz)
    Source code(zip)
  • v2.1.3(Sep 27, 2019)

    Timeout type time.Duration instead int. Be sure you cast it!

    • ConnectTimeout and SendTimeout are type time.Duration instead int
    • NewSMTPClient() return by default 10 seconds for ConnectTimeout and SendTimeout and default Encryption is EncryptionNone
    • Updated readme and example_test

    PD: v2.1.2 not exists. A simple mistake.

    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(Sep 27, 2019)

  • v2.1.0(Sep 21, 2019)

    This update change you connect and send email. Useful for create multiples clients and send with persistent connection with a lot of connections

    -NewSMTPServer() change to NewSMTPClient() and return new SMTPClient struct -New() change to NewMSG() -Public function Send() only receive SMTPClient struct -Private function send() receive SMTPClient struct instead SendTimeout, Client and KeepAlive -Double verification in send, first that SMTPClient struct is not nil and Client is not nil -Public function Connect() return SMTPClient struct -Private function checkKeepAlive() only receive SMTPClient struct -Updated readme

    Note: this update is for v2.1.0 and is not compatible with v2.0.0

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Sep 18, 2019)

    V2.0.0 make changes to support persistent connection aka Keep Alive

    Also there are a new timeout called SendTimeout, is used to limit the time in seconds sending an email after client is connected.

    Source code(tar.gz)
    Source code(zip)
Owner
Santiago De la Cruz
Doing some private stuffs.
Santiago De la Cruz
envio de email via SMTP com anexo usando Go

gosendmail - SMTP This repo is a simple net/smtp abstraction for sending emails using SMTP. With it we can send emails With copy, with blind copy and

Jefferson Otoni Lima 8 Nov 12, 2021
VMail - check the markup (HTML, CSS) of HTML email template compatibility with email clients

VMail - check the markup (HTML, CSS) of HTML email template compatibility with email clients Email clients use different rendering standards. This is

Alexey Vasiliev 10 Dec 1, 2021
๐Ÿ“ฎ Simple (but useful) email sender written in pure Go v1.17. Support HTML templates and attachments.

?? Go Email Sender Simple (but useful) email sender written in pure Go v1.17. Yes, yet another email package here! ?? Support HTML templates and attac

Vic Shรณstak 5 Nov 20, 2021
golang honeypot smtp server

honeygogo-smtp standalone honeypot A lightweight SMTP honeypot server written in Go, leveraging go-smtp. A stand alone version of a module from honeyg

jothflee 0 Nov 11, 2021
Web and API based SMTP testing

MailHog Inspired by MailCatcher, easier to install. Download and run MailHog Configure your outgoing SMTP server View your outgoing email in a web UI

MailHog 9.3k Dec 5, 2021
Lightweight SMTP client written in Go

Hectane Hectane is both a Go package providing an SMTP queue for sending emails and a standalone application that exposes this functionality via an HT

Hectane 209 Nov 17, 2021
MailHog SMTP Protocol

MailHog SMTP Protocol github.com/mailhog/smtp implements an SMTP server state machine. It attempts to encapsulate as much of the SMTP protocol (plus i

MailHog 65 Sep 24, 2021
Disposable webmail server (similar to Mailinator) with built in SMTP, POP3, RESTful servers; no DB required.

Disposable webmail server (similar to Mailinator) with built in SMTP, POP3, RESTful servers; no DB required.

Inbucket 886 Dec 3, 2021
Simple SMTP Server for Testing

go-smtptester Simple SMTP Server for Testing. How it works All received mails are saved in a sync.Map with a key: From+Recipient1+Recipient2 Mails to

null 1 Nov 18, 2021
An easy way to send emails with attachments in Go

PROJECT DISCONTINUED This repository only exists for archival purposes. email An easy way to send emails with attachments in Go Install go get github.

Santiago Corredoira 250 Nov 9, 2021
An email MIME artist for golang

Marcel is a tool to generate IETF compliant emails in raw MIME format. I mainly use this for generating emails with attachments and sending them via amazon SES. If that's what you're doing too, you may want notifications

David Banham 21 Sep 27, 2021
EMail Searcher By Golang

GiveMeMail โ–„โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–“ โ–ˆโ–ˆโ–’ โ–ˆโ–ˆโ–“ โ–“โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–„ โ–„โ–ˆโ–ˆโ–ˆโ–“โ–“โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–„ โ–„โ–ˆโ–ˆโ–ˆโ–“ โ–ˆโ–ˆ โ–ˆโ–ˆโ–“ โ–ˆโ–ˆโ–“ โ–ˆโ–ˆโ–’ โ–€โ–ˆโ–’ โ–“โ–ˆโ–ˆโ–’ โ–“โ–ˆโ–ˆโ–‘ โ–ˆโ–’ โ–“โ–ˆ โ–€ โ–“โ–ˆโ–ˆโ–’โ–€โ–ˆโ–€ โ–ˆโ–ˆโ–’โ–“โ–ˆ

ConsT27 9 Oct 20, 2021
Robust and flexible email library for Go

email Robust and flexible email library for Go Email for humans The email package is designed to be simple to use, but flexible enough so as not to be

Jordan Wright 1.9k Nov 28, 2021
a simple api that sent spam via sms and email

a simple api that sent spam via sms and email routes: /sms /email example request with python

null 3 Oct 19, 2021
Monitoring and automation for Open Source email servers, starting with Postfix.

Welcome to Lightmeter Control Center, the Open Source mailops monitoring application.

Lightmeter 68 Nov 9, 2021
:white_check_mark: A Go library for email verification without sending any emails.

email-verifier โœ‰๏ธ A Go library for email verification without sending any emails. Features Email Address Validation: validates if a string contains a

AfterShip Ltd. 337 Dec 2, 2021
โœ‰๏ธ A Go library for email verification without sending any emails.

email-verifier โœ‰๏ธ A Go library for email verification without sending any emails. Features Email Address Validation: validates if a string contains a

AfterShip Ltd. 248 Jun 24, 2021
End-to-end encrypted email for the mesh networking age

Yggmail It's email, but not as you know it. Introduction Yggmail is a single-binary all-in-one mail transfer agent which sends and receives email nati

Neil Alexander 56 Nov 15, 2021
Go implementation of the JWZ email threading algorithm

The JWZ Threading algorithm written in Go This is an open source Go implementation of the widely known JWZ message threading algorithm originally writ

GatherStars 14 Sep 30, 2021