📧 Easy to use, yet comprehensive library for sending mails with Go https://go-mail.dev
Find a file
Winni Neessen ebef1fe476
Fixes #8
We were using `io.Copy` to write to the body string/alternative string to the io.Writer. This placed the byte position of the buffer to be at the EOF after the first `WriteTo()` call leaving the output of a 2nd call to `WriteTo()` empty.
2022-05-27 12:47:33 +02:00
.github Update sonarqube.yml 2022-04-12 23:25:23 +02:00
.idea Calling it a day... 2022-03-11 16:57:14 +01:00
auth Update auth_test.go to cover the new response 2022-03-20 19:31:30 +01:00
.cirrus.yml Verbose testing is needed 2022-03-16 21:06:12 +01:00
.gitignore Integrate with SonarQube 2022-04-12 15:51:18 +02:00
auth.go Some progress was made: 2022-03-12 15:10:01 +01:00
client.go Rename Write() to WriteTo() so it satisfies the io.WriteTo interface 2022-05-24 15:46:59 +02:00
client_test.go More tests for client.go 2022-03-21 12:18:08 +01:00
CODE_OF_CONDUCT.md Added CoC 2022-03-21 16:47:47 +01:00
codecov.yml Updated codecov.yml 2022-03-21 12:00:49 +01:00
doc.go Rename Write() to WriteTo() so it satisfies the io.WriteTo interface 2022-05-24 15:46:59 +02:00
doc_test.go Lots of tests and helpers added 2022-03-13 10:49:07 +01:00
encoding.go Implemented MIME multipart handling for alternative content 2022-03-13 17:15:23 +01:00
encoding_test.go More tests. encoding.go has now 100% coverage 2022-03-18 10:46:12 +01:00
file.go Switched write functions to return the number of bytes. Due to failing tests in Msg.Write() 2022-03-18 17:08:05 +01:00
file_test.go Tests for file.go added 2022-03-18 11:12:36 +01:00
go.mod Forgot to update go.mod/.sum 2022-03-13 17:25:57 +01:00
go.sum Forgot to update go.mod/.sum 2022-03-13 17:25:57 +01:00
header.go Added String() methods for AddrHeader and Header (incl. tests) 2022-03-18 10:35:51 +01:00
header_test.go Added String() methods for AddrHeader and Header (incl. tests) 2022-03-18 10:35:51 +01:00
LICENSE Initial commit 2022-03-05 12:03:35 +01:00
msg.go Fixes #8 2022-05-27 12:47:33 +02:00
msg_nowin_test.go MacOS tests on GH seem to have issued with the sendmail as well. Let's try timeouts 2022-03-18 23:23:59 +01:00
msg_test.go Fixes #8 2022-05-27 12:47:33 +02:00
msgwriter.go Rename Write() to WriteTo() so it satisfies the io.WriteTo interface 2022-05-24 15:46:59 +02:00
msgwriter_test.go Rename Write() to WriteTo() so it satisfies the io.WriteTo interface 2022-05-24 15:46:59 +02:00
part.go Switched write functions to return the number of bytes. Due to failing tests in Msg.Write() 2022-03-18 17:08:05 +01:00
part_test.go Fix nil pointer deref in part_test.go 2022-03-18 15:09:34 +01:00
README.md Updating the README.md to explain the sendmail feature 2022-05-24 16:33:41 +02:00
SECURITY.md Create SECURITY.md 2022-03-14 16:00:04 +01:00
sonar-project.properties Update sonar-project.properties 2022-04-12 23:12:12 +02:00
tls.go Slow progress 2022-03-07 16:24:49 +01:00
tls_test.go Lots of tests and helpers added 2022-03-13 10:49:07 +01:00

go-mail - Simple and easy way to send mails in Go

GoDoc codecov Go Report Card Build Status Mentioned in Awesome Go buy ma a coffee

The main idea of this library was to provide a simple interface to sending mails for my JS-Mailer project. It quickly evolved into a full-fledged mail library.

go-mail follows idiomatic Go style and best practice. It's only dependency is the Go Standard Library. It combines a lot of functionality from the standard library to give easy and convenient access to mail and SMTP related tasks.

Parts of this library (especially some parts of msgwriter.go) have been forked/ported from the go-mail/mail respectively go-gomail/gomail which both seems to not be maintained anymore.

Features

Some of the features of this library:

  • Only Standard Library dependant
  • Modern, idiomatic Go
  • Sane and secure defaults
  • Explicit SSL/TLS support
  • Implicit StartTLS support with different policies
  • Makes use of contexts for a better control flow and timeout/cancelation handling
  • SMTP Auth support (LOGIN, PLAIN, CRAM-MD)
  • RFC5322 compliant mail address validation
  • Support for common mail header field generation (Message-ID, Date, Bulk-Precedence, Priority, etc.)
  • Reusing the same SMTP connection to send multiple mails
  • Support for attachments and inline embeds
  • Support for different encodings (existing but not fully tested)
  • Support sending mails via a local sendmail command

go-mail works like a programatic email client and provides lots of methods and functionalities you would consider standard in a MUA.

Examples

The package is shipped with GoDoc example code for difference scenarios. Check them out on its GoDoc page

For ease of use, here is a full usage example:

package main

import (
	"fmt"
	"github.com/wneessen/go-mail"
	"os"
)

func main() {
	// Create a new mail message
	m := mail.NewMsg()

	// To set address header fields like "From", "To", "Cc" or "Bcc" you have different methods
	// at your hands. Some perform input validation, some ignore invalid addresses. Some perform
	// the formating for you.
	// 
	if err := m.FromFormat("Toni Tester", "sender@example.com"); err != nil {
		fmt.Printf("failed to set FROM address: %s\n", err)
		os.Exit(1)
	}
	if err := m.To(`"Max Mastermind <rcpt@example.com>"`); err != nil {
		fmt.Printf("failed to set TO address: %s\n", err)
		os.Exit(1)
	}
	m.CcIgnoreInvalid("cc@example.com", "invalidaddress+example.com")

	// Set a subject line
	m.Subject("This is a great email")

	// And some other common headers...
	//
	// Sets a valid "Date" header field with the current time
	m.SetDate()
	//
	// Generates a valid and unique "Message-ID"
	m.SetMessageID()
	//
	// Sets the "Precedence"-Header to "bulk" to indicate a "bulk mail"
	m.SetBulk()
	//
	// Set a "high" importance to the mail (this sets several Header fields to 
	// satisfy the different common mail clients like Mail.app and Outlook)
	m.SetImportance(mail.ImportanceHigh)

	// Add your mail message to body
	m.SetBodyString(mail.TypeTextPlain, "This is a great message body text.")

	// Attach a file from your local FS
	// We override the attachment name using the WithFileName() Option
	m.AttachFile("/home/ttester/test.txt", mail.WithFileName("attachment.txt"))

	// Next let's create a Client
	// We have lots of With* options at our disposal to stear the Client. It will set sane
	// options by default, though
	//
	// Let's assume we need to perform SMTP AUTH with the sending server, though. Since we
	// use SMTP PLAIN AUTH, let's also make sure to enforce strong TLS
	host := "relay.example.com"
	c, err := mail.NewClient(host,
		mail.WithSMTPAuth(mail.SMTPAuthPlain), mail.WithUsername("ttester"),
		mail.WithPassword("V3rySecUr3!Pw."), mail.WithTLSPolicy(mail.TLSMandatory))
	if err != nil {
		fmt.Printf("failed to create new mail client: %s\n", err)
		os.Exit(1)
	}

	// Now that we have our client, we can connect to the server and send our mail message
	// via the convenient DialAndSend() method. You have the option to Dial() and Send()
	// seperately as well
	if err := c.DialAndSend(m); err != nil {
		fmt.Printf("failed to send mail: %s\n", err)
		os.Exit(1)
	}

	fmt.Println("Mail successfully sent.")
}