gomailconn

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2026 License: MIT Imports: 23 Imported by: 0

README

gomailconn

Other languages: 简体中文

A Go library for IMAP/SMTP email: connect to your mailbox, get notified when new mail arrives, and send mail. Built on go-imap/v2.

  • What it does: Keeps a long-lived connection to an IMAP server, calls your handler for each new message (with parsed body and attachments), and optionally sends mail via SMTP.
  • Who it’s for: Services that need to watch a mailbox (e.g. QQ Mail, NetEase 163) or automate read/send without running a full mail client.
  • In one line: Configure once, run StartWithHandler, and handle incoming mail in your code.

Features

  • IMAP: Long-lived connection with automatic reconnect and backoff
  • IDLE or polling: Uses IMAP IDLE when the server supports it; falls back to configurable polling
  • New-mail handler: Your callback receives parsed MailMessage (envelope, body parts, attachments)
  • Attachments: Optional save to a local directory with size limits; RFC 2047 filename decoding (e.g. GBK)
  • SMTP: Send mail with optional TLS (port 465) or STARTTLS (port 587)
  • Config: JSON-friendly struct; can be loaded from env or config files

Requirements

  • Go 1.25.7 or later

Installation

go get github.com/blingmoon/gomailconn

Quick start

package main

import (
    "context"
    "log"

    "github.com/blingmoon/gomailconn"
)

func main() {
    cfg := &gomailconn.Config{
        Username:   "your@email.com",
        Password:   "your-password",
        IMAPServer: "imap.example.com",
        IMAPPort:   993,
        UseTLS:     true,
        Mailbox:    "INBOX",
    }

    client, err := gomailconn.NewClient(cfg)
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()
    err = client.StartWithHandler(ctx, func(ctx context.Context, msg *gomailconn.MailMessage) error {
        log.Printf("New mail: UID=%d From=%q Subject=%q", msg.UID, msg.From, msg.Subject)
        return nil
    })
    if err != nil {
        log.Fatal(err)
    }

    defer client.Stop(ctx)
    // ... wait for shutdown (e.g. signal)
}

Configuration

Field Description
Username, Password Login credentials
IMAPServer, IMAPPort IMAP host and port (0 = 993 with TLS, 143 without)
UseTLS Use TLS for IMAP (default port 993)
Mailbox Mailbox name (default INBOX)
ConnectWithID Send IMAP ID command after login (required for some servers, e.g. 163)
CheckInterval Polling interval in seconds when IDLE is not used (default 30)
ForcedPolling Disable IDLE and always poll at CheckInterval
AttachmentDir Directory to save attachments (empty = do not save)
AttachmentMaxBytes, BodyMaxBytes Size limits (0 = use defaults or no limit)
SMTPServer, SMTPPort, SMTPUseTLS SMTP settings for Send() (optional)

Sending email

If SMTPServer is set, you can send mail:

err := client.Send(ctx, &gomailconn.SendMailMessage{
    To:      "recipient@example.com",
    Subject: "Subject",
    Body:    []string{"Plain text body."},
    // Attachments: []*gomailconn.AttachmentInfo{ ... },
})

Example

A runnable example that loads config from a .env file (or env vars) and runs the client until Ctrl+C:

cd example
cp .env.example .env   # edit with your credentials
go run .

From the repository root:

go run ./example

License

See LICENSE.

Documentation

Overview

Package gomailconn provides IMAP-based mail receiving and SMTP-based sending, with parsing of message body and attachments and a callback for new messages.

Receiving (IMAP)

Configure the client with Config (IMAP server, credentials, mailbox, etc.), create a client with NewClient, then call StartWithHandler with a handler to listen for new mail in the background (IDLE or polling). Each new message is parsed into MailMessage with subject, from, body parts (MailBodyPart) and attachments (MailAttachment). Attachments can be saved to a local directory (AttachmentDir) with optional size limits (BodyMaxBytes, AttachmentMaxBytes). Common charsets such as GBK are supported. If the server does not support IDLE, enable ForcedPolling and set CheckInterval for polling.

Sending (SMTP)

Set Config.SMTPServer (and optionally SMTPPort, SMTPUseTLS), then call Client.Send with a SendMailMessage (to, subject, body, optional attachments) to send mail via SMTP.

Basic usage

cfg := &gomailconn.Config{
    Username: "user", Password: "pass",
    IMAPServer: "imap.example.com", Mailbox: "INBOX",
    SMTPServer: "smtp.example.com",
}
client, _ := gomailconn.NewClient(cfg)
client.StartWithHandler(ctx, func(ctx context.Context, msg *gomailconn.MailMessage) error {
    // handle msg body and attachments
    return nil
})
client.Send(ctx, &gomailconn.SendMailMessage{To: "to@example.com", Subject: "Hi", Body: []string{"Hello"}})
client.Stop(ctx)

See the example directory for a full runnable example.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotRunning         = errors.New("client is not running")
	ErrAlreadyInitialized = errors.New("client is already initialized")
	ErrInvalidConfig      = errors.New("invalid config")
	ErrInvalidParams      = errors.New("invalid params")
)

Functions

This section is empty.

Types

type AttachmentInfo

type AttachmentInfo struct {
	AttachmentName   string
	AttachmentReader io.Reader
}

type BodyContentType

type BodyContentType = string
const (
	BodyContentTypeText BodyContentType = "text"
	BodyContentTypeHtml BodyContentType = "html"
)

type Client

type Client struct {
	Status ClientStatus
	// contains filtered or unexported fields
}

func NewClient

func NewClient(cfg *Config) (*Client, error)

func (*Client) Send

func (c *Client) Send(ctx context.Context, msg *SendMailMessage) error

Send builds and sends an email via SMTP. Caller must set Config.SMTPServer (and optionally SMTPPort, SMTPUseTLS).

func (*Client) StartWithHandler

func (c *Client) StartWithHandler(ctx context.Context, handler func(ctx context.Context, mailMessage *MailMessage) error) error

func (*Client) Stop

func (c *Client) Stop(ctx context.Context) error

type ClientStatus

type ClientStatus string
const (
	ClientStatusInit     ClientStatus = "init"
	ClientStatusIniting  ClientStatus = "initing"
	ClientStatusRunning  ClientStatus = "running"
	ClientStatusStopped  ClientStatus = "stopped"
	ClientStatusAbnormal ClientStatus = "abnormal"
)

type Config

type Config struct {
	// basic auth
	Username string `json:"username"`
	Password string `json:"password"`

	// listen config
	IMAPServer string `json:"imap_server"`
	IMAPPort   int    `json:"imap_port"`
	// if true, after login, execute ID COMMAND
	// some email server require this command to be executed to get the mailbox info
	// eg: 163.com
	ConnectWithID bool   `json:"connect_with_id"`
	Mailbox       string `json:"mailbox"` // default "INBOX"
	// seconds, default 30s; polling when IDLE disabled, if not configured, use default 30s
	CheckInterval int  `json:"check_interval"`
	UseTLS        bool `json:"use_tls"`
	// ForcedPolling: when the mail server does not implement IDLE/NOOP per spec,
	// set true to use app-level polling at CheckInterval.
	ForcedPolling bool `json:"forced_polling"`
	// if not configured, will not save attachments to the local filesystem
	AttachmentDir string `json:"attachment_dir"`
	// all attachments in the email will be saved to the attachment directory,
	// if not configured, use no limit, 0 = use default
	AttachmentMaxBytes int64 `json:"attachment_max_bytes"`
	// max size per body part (text/plain, text/html) to avoid unbounded io.ReadAl,
	// if not configured, use no limit, 0 = use default
	BodyMaxBytes int64 `json:"body_max_bytes"`

	// SMTP send (optional, if not configured, Send is not available)
	SMTPServer string `json:"smtp_server"`
	SMTPPort   int    `json:"smtp_port"` // if not configured, use default port 465 or 587
	// 465  use true, 587  use false+STARTTLS
	SMTPUseTLS bool `json:"smtp_use_tls"`
}

type MailAttachment

type MailAttachment struct {
	AttachmentName     string
	SafeAttachmentName string
	LocalPath          string
	IsParsed           bool
	ParseError         error
}

type MailBodyPart

type MailBodyPart struct {
	ContentType BodyContentType
	Body        string
	IsParsed    bool
	ParseError  error
}

type MailMessage

type MailMessage struct {
	UID         uint32
	Subject     string
	From        string
	To          string
	BodyParts   []*MailBodyPart
	Attachments []*MailAttachment
}

type SendMailMessage

type SendMailMessage struct {
	To          string //required, use "," to separate multiple recipients
	Subject     string
	Body        []string
	Attachments []*AttachmentInfo
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL