Documentation
¶
Overview ¶
Package email is the gateway's email channel: a mailbox the agent answers. IMAP (SSL :993) is polled for NEW mail past a durable UID cursor; replies go out over SMTP (STARTTLS :587) with proper threading headers. The mailbox can be the agent's own dedicated account OR a personal inbox: the channel reads with BODY.PEEK and acks by advancing its cursor, NEVER by setting \Seen — it leaves flags, folders, and read state exactly as it found them, and the gateway's allow-list decides which senders it answers at all.
Ack semantics match the gateway contract: the cursor advances ONLY after Deliver returns nil, so a crash between fetch and durable record just re-fetches it. On first connect (or a UIDVALIDITY reset) the cursor initializes to the mailbox's current end — pre-existing mail, including a personal inbox's whole history, is never read, never answered. The durable dedup key is <mailbox>/<UIDVALIDITY>/<UID> — the provider-side identity, robust against malformed or duplicated Message-IDs (which serve threading, not dedup).
IDENTITY CAVEAT: the principal is the RFC From address — weaker than the other channels' platform-authenticated ids, since From can be spoofed by mail that evades the provider's SPF/DKIM/DMARC filtering. The mailbox provider's authentication is the real gate (a mainstream provider rejects or junks spoofed mail before we poll it). Enforcing Authentication-Results=pass explicitly is a tracked follow-up.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Channel ¶
type Channel struct {
// contains filtered or unexported fields
}
Channel is an email (IMAP+SMTP) connection.
func New ¶
func New(address, password, imapHost, smtpHost string, poll time.Duration, mediaDir string, store CursorStore) *Channel
New builds an email channel. store persists the mailbox cursor. poll <= 0 uses the default (15s). mediaDir is the gateway media spool inbound attachments are saved into; "" disables attachment handling.
type CursorStore ¶ added in v0.17.0
type CursorStore interface {
Cursor(ctx context.Context, channel string) (string, error)
SetCursor(ctx context.Context, channel, cursor string) error
}
CursorStore persists the mailbox position (UIDVALIDITY/last-UID) so a restart resumes where it left off. The gateway state store implements it.