outbound

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComposeMessage

func ComposeMessage(from string, to []string, cc []string, subject, body, contentType, replyToMsgID, fromDomain, replyTo, conversationID string) ([]byte, error)

ComposeMessage builds an RFC 2822 email message (single content type). Message-ID is omitted — SES assigns one on send. If to is empty, the To: header is omitted entirely (CC-only send). BCC is never written to headers — it is handled at the SMTP envelope level. When conversationID is non-empty, an X-E2A-Conversation-ID header is written so recipient agents on this platform can continue the same application thread without depending on In-Reply-To chains.

func ComposeMessageWithAttachments

func ComposeMessageWithAttachments(from string, to []string, cc []string, subject, textBody, htmlBody, replyToMsgID, fromDomain, replyTo, conversationID string, attachments []Attachment) ([]byte, error)

ComposeMessageWithAttachments builds an RFC 2822 multipart/mixed email with attachments. If no attachments are provided, falls back to ComposeMultipartMessage.

func ComposeMultipartMessage

func ComposeMultipartMessage(from string, to []string, cc []string, subject, textBody, htmlBody, replyToMsgID, fromDomain, replyTo, conversationID string) ([]byte, error)

ComposeMultipartMessage builds an RFC 2822 multipart/alternative email with text and HTML parts. If htmlBody is empty, falls back to a single text/plain message via ComposeMessage.

func DecodeAttachmentData

func DecodeAttachmentData(data string) ([]byte, error)

DecodeAttachmentData decodes a base64-encoded attachment data string.

func IsValidationError

func IsValidationError(err error) bool

IsValidationError returns true if err is a ValidationError.

Types

type Attachment

type Attachment struct {
	Filename    string `json:"filename" example:"report.pdf"`
	ContentType string `json:"content_type" example:"application/pdf"`
	Data        string `json:"data" example:"base64-encoded-content"` // base64-encoded

} // @name Attachment

Attachment is a base64-encoded file attachment.

type ReplyRecipients

type ReplyRecipients struct {
	To []string
	CC []string
}

ReplyRecipients holds the resolved To and CC lists for a reply.

func ParseReplyRecipients

func ParseReplyRecipients(rawMessage []byte, replyAll bool, extraCC []string) (*ReplyRecipients, error)

ParseReplyRecipients resolves reply recipients from a raw inbound email.

Reply To is determined by Reply-To if present, otherwise From — both parsed as address lists. All parsed mailboxes become To recipients.

If replyAll is true, original To and CC recipients are added to CC. The agent's own address is excluded from all fields. Explicit extraCC addresses are merged into CC.

Normalization, deduplication, and self-removal are handled downstream by Sender.Send(). This function does best-effort parsing and returns raw lowercase addresses.

type SMTPRelay

type SMTPRelay struct {
	// contains filtered or unexported fields
}

func NewSMTPRelay

func NewSMTPRelay(cfg *config.OutboundSMTPConfig) *SMTPRelay

func (*SMTPRelay) Configured

func (r *SMTPRelay) Configured() bool

func (*SMTPRelay) Send

func (r *SMTPRelay) Send(from string, recipients []string, message []byte) (string, error)

Send sends an email to one or more recipients and returns the Message-ID assigned by the remote server (e.g. SES).

func (*SMTPRelay) SendWithEnvelope

func (r *SMTPRelay) SendWithEnvelope(envelopeFrom string, recipients []string, message []byte) (string, error)

SendWithEnvelope sends an email using envelopeFrom for SMTP MAIL FROM. Issues RCPT TO for each recipient. If any RCPT TO is rejected, the transaction is aborted. Returns the Message-ID assigned by the remote SMTP server from the DATA response. Retries transient SMTP errors (4xx) up to 3 times with backoff.

type SendRequest

type SendRequest struct {
	From             string       `json:"from,omitempty"`
	To               []string     `json:"to"`
	CC               []string     `json:"cc,omitempty"`
	BCC              []string     `json:"bcc,omitempty"`
	Subject          string       `json:"subject"`
	Body             string       `json:"body"`
	HTMLBody         string       `json:"html_body,omitempty"`
	ReplyToMessageID string       `json:"reply_to_message_id"`
	ConversationID   string       `json:"conversation_id,omitempty"`
	Attachments      []Attachment `json:"attachments,omitempty"`
}

SendRequest is the outbound email contract.

type SendResult

type SendResult struct {
	MessageID string   `json:"message_id"`
	Method    string   `json:"method"` // "smtp"
	To        []string `json:"-"`      // canonicalized To recipients
	CC        []string `json:"-"`      // canonicalized CC recipients
	BCC       []string `json:"-"`      // canonicalized BCC recipients
}

SendResult contains the result of a successful send, including the canonicalized recipient lists for persistence.

type Sender

type Sender struct {
	// contains filtered or unexported fields
}

func NewSender

func NewSender(smtpRelay *SMTPRelay, fromDomain string) *Sender

func (*Sender) Send

func (s *Sender) Send(agent *identity.AgentIdentity, req SendRequest) (*SendResult, error)

Send normalizes recipients, composes, and sends an email via SMTP relay. Returns a ValidationError for caller errors (bad addresses, no visible recipients) and a plain error for transport failures.

type ValidationError

type ValidationError struct {
	Message string
}

ValidationError indicates a caller error (invalid addresses, no visible recipients). Handlers should map this to HTTP 400.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

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