Install smtppool v2
masterTo use smtppool in your Go project, install the v2 package using go get:
go get github.com/knadh/smtppool/v2repository·master·Indexed 41 days ago
https://github.com/knadh/smtppoolA Go library for high-throughput emailing that maintains a pool of reusable SMTP connections. It provides automatic connection management, including idle timeouts, retries, and connection limits, and includes a comprehensive Email struct for constructing RFC-compliant MIME messages with support for HTML, attachments, and custom headers.
To use smtppool in your Go project, install the v2 package using go get:
go get github.com/knadh/smtppool/v2The SSL field in Opt determines how the connection to the SMTP server is established using the SSLType enum:
SSLNone: A plain unencrypted connection (default).SSLTLS: An SSL (TLS) connection established immediately without using the STARTTLS extension.SSLSTARTTLS: A non-TLS connection that is upgraded to TLS using the STARTTLS extension.// Example: Using STARTTLS
opt := smtppool.Opt{
Host: "smtp.example.com",
Port: 587,
SSL: smtppool.SSLSTARTTLS,
TLSConfig: &tls.Config{ /* ... */ },
}To send an email, define an smtppool.Email struct and pass it to the pool.Send() method. The Email struct supports standard fields like From, To, Bcc, Cc, Subject, Text, and HTML. You can also attach files using the AttachFile method.
package main
import (
"log"
"time"
"github.com/knadh/smtppool/v2"
)
func main() {
// Create a new pool.
pool, err := smtppool.New(smtppool.Opt{
Host: "localhost",
Port: 1025,
MaxConns: 10,
IdleTimeout: time.Second * 10,
PoolWaitTimeout: time.Second * 3,
SSL: smtppool.SSLNone
})
if err != nil {
log.Fatalf("error creating pool: %v", err)
}
e := smtppool.Email{
From: "John Doe <john@example.com>",
To: []string{"doe@example.com"},
// Optional.
Bcc: []string{"doebcc@example.com"},
Cc: []string{"doecc@example.com"},
Subject: "Hello, World",
Text: []byte("This is a test e-mail"),
HTML: []byte("<strong>This is a test e-mail</strong>"),
}
// Add attachments.
if _, err := e.AttachFile("test.txt"); err != nil {
log.Fatalf("error attaching file: %v", err)
}
if err := pool.Send(e); err != nil {
log.Fatalf("error sending e-mail: %v", err)
}
}Use smtppool.New to initialize a pool of reusable SMTP connections. This pool manages connection lifecycles, including idle timeouts and maximum connection limits, to support high-throughput emailing.
Configuration is provided via the smtppool.Opt struct.
import (
"time"
"github.com/knadh/smtppool/v2"
)
// ...
pool, err := smtppool.New(smtppool.Opt{
Host: "localhost",
Port: 1025,
MaxConns: 10,
IdleTimeout: time.Second * 10,
PoolWaitTimeout: time.Second * 3,
SSL: smtppool.SSLNone
})The Opt struct defines the configuration for the SMTP pool. Use these fields to control connection behavior, security, and reliability.
| Field | Type | Description |
|---|---|---|
Host | string | The SMTP server's hostname. |
Port | int | The SMTP server port. |
HelloHostname | string | Optional hostname passed with the HELO command. Defaults to "localhost". |
MaxConns | int | Maximum allowed concurrent SMTP connections. |
MaxMessageRetries | int | Number of retries for a failed message. Min is 1. |
MessageRetryDelay | time.Duration | Duration to wait before retrying a failed message. |
IdleTimeout | time.Duration | Max time to wait for activity on a connection before closing it. |
PoolWaitTimeout | time.Duration | Max time to wait to obtain a connection or create a new one. |
SSL | SSLType | Connection security type (SSLNone, SSLTLS, or SSLSTARTTLS). |
Auth | smtp.Auth | The smtp.Auth authentication scheme. |
TLSConfig | *tls.Config | Optional TLS configuration. |
Call Close() on the *Pool to shut down the pool. This marks the pool as closed, prevents new connections from being borrowed, and signals the idle connection sweeper to stop. Any subsequent calls to Send() will return ErrPoolClosed.
pool.Close()Use New(o Opt) to create a new *Pool instance. The pool manages a set of reusable SMTP connections to improve throughput.
Important Defaults & Constraints:
MaxConns must be $\ge 1$.MaxMessageRetries is 0, it defaults to 1.PoolWaitTimeout is less than 1 second, it defaults to 2 seconds.IdleTimeout is $\ge 1$ second and MaxConns > 1, an internal connection sweeper goroutine is started automatically to clean up idle connections.import "github.com/knadh/smtppool"
opt := smtppool.Opt{
Host: "smtp.example.com",
Port: 587,
MaxConns: 10,
}
pool, err := smtppool.New(opt)
if err != nil {
panic(err)
}Use NewEmailFromReader(r io.Reader) to parse an existing email stream (in RFC 5322 format) into an Email struct. This function automatically decodes headers, parses MIME parts, and populates the Text, HTML, and Attachments fields.
email, err := smtppool.NewEmailFromReader(reader)
if err != nil {
// handle error
}
fmt.Println("Subject:", email.Subject)You can add attachments to an Email instance using two methods:
Attach(r io.Reader, filename string, c string): Attaches content from an io.Reader. If the content type c is empty, it defaults to application/octet-stream.AttachFile(filename string): Automatically opens a file from the local filesystem, determines its MIME type based on the extension, and attaches it.Both methods return the created Attachment object.
// Attach from a reader
email.Attach(bytes.NewReader(data), "document.pdf", "application/pdf")
// Attach from a file
email.AttachFile("/path/to/image.png")The Send(e Email) method sends an email using an available connection from the pool.
Behavior:
MaxMessageRetries times.RSET) and returned to the pool for reuse.// Assuming 'pool' is an initialized *smtppool.Pool
// and 'email' is an implementation of the smtppool.Email interface
err := pool.Send(email)
if err != nil {
// Handle error
}The Bytes() method converts the Email struct into a complete, RFC-compliant MIME-encoded []byte slice. This includes all necessary headers, boundaries for multipart messages (alternative, mixed, or related), and base64 encoding for attachments. This byte slice is what you would typically pass to an SMTP client to send the message.
data, err := email.Bytes()
if err != nil {
// handle error
}
// 'data' is now ready to be sent via SMTPThe following constants define standard MIME content types used by the package:
ContentTypePlain: text/plainContentTypeHTML: text/htmlContentTypeOctetStream: application/octet-streamContentTypeMultipartAlt: multipart/alternativeContentTypeMultipartMixed: multipart/mixedContentTypeMultipartRelated: multipart/relatedconst (
ContentTypePlain = "text/plain"
ContentTypeHTML = "text/html"
ContentTypeOctetStream = "application/octet-stream"
ContentTypeMultipartAlt = "multipart/alternative"
ContentTypeMultipartMixed = "multipart/mixed"
ContentTypeMultipartRelated = "multipart/related"
)