mail

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package mail defines provider-agnostic email types. Nothing in this package knows about Gmail, IMAP, or any other backend; concrete providers translate into these types at their boundary so the UI never depends on a service.

Index

Constants

View Source
const (
	LabelInbox     = "INBOX"
	LabelUnread    = "UNREAD"
	LabelStarred   = "STARRED"
	LabelSent      = "SENT"
	LabelDraft     = "DRAFT"
	LabelTrash     = "TRASH"
	LabelSpam      = "SPAM"
	LabelImportant = "IMPORTANT"
)

Well-known label identifiers. Gmail uses these verbatim; other providers map their own concepts onto them.

Variables

View Source
var (
	Archive    = LabelDelta{Remove: []string{LabelInbox}}
	Unarchive  = LabelDelta{Add: []string{LabelInbox}}
	Star       = LabelDelta{Add: []string{LabelStarred}}
	Unstar     = LabelDelta{Remove: []string{LabelStarred}}
	MarkRead   = LabelDelta{Remove: []string{LabelUnread}}
	MarkUnread = LabelDelta{Add: []string{LabelUnread}}
	Delete     = LabelDelta{Add: []string{LabelTrash}, Remove: []string{LabelInbox}}
	Restore    = LabelDelta{Remove: []string{LabelTrash}, Add: []string{LabelInbox}}
	MarkSpam   = LabelDelta{Add: []string{LabelSpam}, Remove: []string{LabelInbox}}
	NotSpam    = LabelDelta{Remove: []string{LabelSpam}, Add: []string{LabelInbox}}
)

Triage actions expressed as label deltas. Delete is a move to Trash rather than a permanent removal, which keeps Postline out of the broadest OAuth scope and keeps the action recoverable.

Functions

func Apply

func Apply(ctx context.Context, p Provider, d LabelDelta, threadIDs ...string) error

Apply runs a delta against a provider for the given threads.

func DisplayAddresses

func DisplayAddresses(addrs []Address) string

DisplayAddresses joins addresses for compact on-screen display.

func FormatAddresses

func FormatAddresses(addrs []Address) string

FormatAddresses joins addresses for header rendering.

Types

type Address

type Address struct {
	Name  string
	Email string
}

Address is a single mail participant.

func ParseAddresses

func ParseAddresses(s string) []Address

ParseAddresses reads a comma-separated address list. It is tolerant: real mail headers are frequently malformed, and showing a bare address beats dropping a recipient.

func (Address) Display

func (a Address) Display() string

Display prefers a human name and falls back to the raw address.

func (Address) String

func (a Address) String() string

String renders RFC 5322 form, quoting the display name when it contains characters that would otherwise break the header.

type Attachment

type Attachment struct {
	ID       string
	Filename string
	MimeType string
	Size     int64
}

Attachment describes a file on a message. Content is fetched separately and on demand, since attachments are frequently large and rarely opened.

type Draft

type Draft struct {
	To      []Address
	Cc      []Address
	Bcc     []Address
	Subject string
	Body    string

	ThreadID   string
	InReplyTo  string
	References string
}

Draft is an outbound message. A reply carries ThreadID, InReplyTo, and References so the provider can thread it correctly.

func Forward

func Forward(msg Message) Draft

Forward builds a draft passing msg along, with recipients left for the user.

func Reply

func Reply(msg Message, all bool, account string) Draft

Reply builds a draft answering msg. When all is true the other recipients are carried into Cc, minus the account itself so the sender is not copied on their own reply.

type Label

type Label struct {
	ID     string
	Name   string
	Unread int
	Total  int
	Kind   LabelKind
}

Label is a mailbox or tag.

type LabelDelta

type LabelDelta struct {
	Add    []string
	Remove []string
}

LabelDelta is a set of labels to add and remove.

type LabelKind

type LabelKind int

LabelKind separates provider-defined labels from user-created ones so the sidebar can group them.

const (
	LabelKindSystem LabelKind = iota
	LabelKindUser
)

type Message

type Message struct {
	ID       string
	ThreadID string

	From Address
	To   []Address
	Cc   []Address
	Bcc  []Address

	Subject string
	Date    time.Time

	// Body is plain text. HTML-only mail is converted at the provider boundary
	// so that no part of the UI needs an HTML renderer, and so remote images
	// are never fetched.
	Body        string
	Attachments []Attachment

	Labels []string
	Unread bool

	// MessageID and References carry the RFC 5322 headers needed to thread a
	// reply correctly.
	MessageID  string
	References string
}

Message is a single email within a thread.

type Provider

type Provider interface {
	// Name identifies the service for display, e.g. "Gmail".
	Name() string

	// Account returns the authenticated address.
	Account() string

	// Labels lists all mailboxes and tags.
	Labels(ctx context.Context) ([]Label, error)

	// Threads returns one page of conversation summaries.
	Threads(ctx context.Context, q ThreadQuery) (ThreadPage, error)

	// Thread returns every message in a conversation, oldest first.
	Thread(ctx context.Context, id string) ([]Message, error)

	// Attachment fetches attachment content on demand.
	Attachment(ctx context.Context, msgID, attachmentID string) ([]byte, error)

	// Modify applies a label delta to whole threads.
	Modify(ctx context.Context, threadIDs []string, add, remove []string) error

	// Send delivers a draft.
	Send(ctx context.Context, d Draft) error
}

Provider is the seam between the application and a mail service. Adding a service means implementing this interface; no other layer changes.

Every triage action collapses into Modify with a label delta, which keeps this surface small enough that a new provider stays tractable.

type Thread

type Thread struct {
	ID           string
	Subject      string
	Snippet      string
	Participants []Address
	Date         time.Time
	MessageCount int

	Labels         []string
	Unread         bool
	Starred        bool
	HasAttachments bool
}

Thread is a conversation summary, the unit shown in the list view.

func (Thread) HasLabel

func (t Thread) HasLabel(id string) bool

HasLabel reports whether the thread carries the given label.

type ThreadPage

type ThreadPage struct {
	Threads       []Thread
	NextPageToken string
}

ThreadPage is one page of results plus the cursor for the next.

type ThreadQuery

type ThreadQuery struct {
	LabelID   string
	Search    string
	PageToken string
	Limit     int
}

ThreadQuery selects a page of threads.

Directories

Path Synopsis
Package fake provides an in-memory mail.Provider for tests and offline development, so UI behavior can be exercised without network access.
Package fake provides an in-memory mail.Provider for tests and offline development, so UI behavior can be exercised without network access.
Package gmail implements mail.Provider against the Gmail API.
Package gmail implements mail.Provider against the Gmail API.

Jump to

Keyboard shortcuts

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