Documentation
¶
Overview ¶
Package emlbuilder provides a Lark-API-compatible RFC 2822 EML message builder.
It is designed for use with the Lark mail drafts API (POST /open-apis/mail/v1/user_mailboxes/me/drafts), which requires the complete EML to be base64url-encoded and placed in the "raw" request field. After creating a draft, send it via POST .../drafts/{draft_id}/send.
Key differences from standard MIME libraries:
- Line endings are LF (\n), not CRLF — Lark API requires this.
- Content-Type parameters are never folded onto a new line — Lark's MIME parser does not handle header folding correctly.
- Non-ASCII body content is encoded as base64 (StdEncoding) — 7bit and 8bit are rejected by Lark for non-ASCII content.
- BuildBase64URL() produces the base64url (URLEncoding) output that goes directly into the API's "raw" field.
MIME structure produced by Build():
multipart/mixed ← only when attachments exist
└─ multipart/related ← only when CID inline/other parts exist
└─ multipart/alternative ← only when multiple body types coexist
├─ text/plain
├─ text/html
└─ text/calendar
└─ inline/other parts (CID)
└─ attachments
Usage:
raw, err := emlbuilder.New().
From("", "alice@example.com").
To("", "bob@example.com").
Subject("Hello").
TextBody([]byte("Hi Bob")).
HTMLBody([]byte("<p>Hi Bob</p>")).
AddInline(imgBytes, "image/png", "logo.png", "logo").
BuildBase64URL()
Index ¶
- Constants
- type Builder
- func (b Builder) AddAttachment(content []byte, contentType, fileName string) Builder
- func (b Builder) AddFileAttachment(path string) Builder
- func (b Builder) AddFileInline(path, contentID string) Builder
- func (b Builder) AddFileOtherPart(path, contentID string) Builder
- func (b Builder) AddInline(content []byte, contentType, fileName, contentID string) Builder
- func (b Builder) AddOtherPart(content []byte, contentType, fileName, contentID string) Builder
- func (b Builder) AllRecipients() []string
- func (b Builder) AllowNoRecipients() Builder
- func (b Builder) BCC(name, addr string) Builder
- func (b Builder) BCCAddrs(addrs []mail.Address) Builder
- func (b Builder) Build() ([]byte, error)
- func (b Builder) BuildBase64URL() (string, error)
- func (b Builder) CC(name, addr string) Builder
- func (b Builder) CCAddrs(addrs []mail.Address) Builder
- func (b Builder) CalendarBody(body []byte) Builder
- func (b Builder) Date(date time.Time) Builder
- func (b Builder) Error() error
- func (b Builder) From(name, addr string) Builder
- func (b Builder) HTMLBody(body []byte) Builder
- func (b Builder) Header(name, value string) Builder
- func (b Builder) InReplyTo(id string) Builder
- func (b Builder) LMSReplyToMessageID(id string) Builder
- func (b Builder) MessageID(id string) Builder
- func (b Builder) References(refs string) Builder
- func (b Builder) ReplyTo(name, addr string) Builder
- func (b Builder) Subject(subject string) Builder
- func (b Builder) TextBody(body []byte) Builder
- func (b Builder) To(name, addr string) Builder
- func (b Builder) ToAddrs(addrs []mail.Address) Builder
Constants ¶
const MaxEMLSize = 25 * 1024 * 1024 // 25 MB
MaxEMLSize is the maximum allowed raw EML size in bytes.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder constructs a Lark-compatible RFC 2822 EML message. All setter methods return a copy of the Builder (immutable/fluent style), so a base builder can be reused across multiple goroutines safely.
func (Builder) AddAttachment ¶
AddAttachment appends a file attachment. contentType should be a valid MIME type (e.g. "application/pdf"). If contentType is empty, "application/octet-stream" is used. Returns an error builder if contentType or fileName contains CR or LF.
func (Builder) AddFileAttachment ¶
AddFileAttachment reads a file from disk and appends it as an attachment. The backend canonicalizes regular attachments to application/octet-stream on save/readback, so the builder aligns with that behavior instead of inferring a richer MIME type from the local file extension. If reading the file fails, the error is stored and returned by Build().
func (Builder) AddFileInline ¶
AddFileInline reads a file from disk and appends it as a CID inline part. The content type is inferred from the file extension. If reading the file fails, the error is stored and returned by Build().
func (Builder) AddFileOtherPart ¶
AddFileOtherPart reads a file from disk and appends it as a CID other-part (no Content-Disposition header). See AddOtherPart for details. If reading the file fails, the error is stored and returned by Build().
func (Builder) AddInline ¶
AddInline appends a CID-referenced inline part (e.g. an embedded image). The part is written with Content-Disposition: inline, causing most mail clients to render it inline rather than as a download. contentID is a unique identifier without angle brackets; it matches the "cid:" reference in the HTML body (e.g. contentID="logo.png" matches src="cid:logo.png"). When inline parts are present, the message body is automatically wrapped in multipart/related. Returns an error builder if contentType or fileName contains CR or LF, or if contentID contains any ASCII control character.
func (Builder) AddOtherPart ¶
AddOtherPart appends a CID-referenced embedded part without Content-Disposition. Unlike AddInline, this part carries no Content-Disposition header, which is appropriate for resources referenced via "cid:" that should not appear as inline attachments in the client UI (e.g. calendar objects or custom data blobs). When other parts are present, the message body is automatically wrapped in multipart/related. Returns an error builder if contentType or fileName contains CR or LF, or if contentID contains any ASCII control character.
func (Builder) AllRecipients ¶
AllRecipients returns all recipient addresses (To + CC + BCC). Useful for SMTP envelope construction.
func (Builder) AllowNoRecipients ¶
AllowNoRecipients tells Build() to skip the recipient-required check. Use this for draft creation, where saving without recipients is valid.
func (Builder) BCC ¶
BCC appends an address to the Bcc list. Bcc addresses are included in AllRecipients() but not written to the EML headers.
func (Builder) Build ¶
Build validates the builder and returns the raw EML bytes.
Constraints (Lark API requirements):
- From is mandatory.
- At least one of To/CC/BCC must be set.
- Line endings are LF (\n), not CRLF.
- Content-Type parameters are written on a single line (no header folding).
- Non-ASCII body content is base64 (StdEncoding) encoded.
func (Builder) BuildBase64URL ¶
BuildBase64URL returns the EML encoded as base64url (RFC 4648). This is the value to place in the Lark API "raw" field.
func (Builder) CalendarBody ¶
CalendarBody sets the text/calendar body (e.g. for meeting invitations). May be combined with TextBody and/or HTMLBody; the resulting parts are wrapped in multipart/alternative.
func (Builder) Header ¶
Header appends an extra header to the message. Multiple calls with the same name result in multiple header lines. Returns an error builder if name or value contains CR, LF, or (for names) ':'.
func (Builder) InReplyTo ¶
InReplyTo sets the In-Reply-To header (the smtp_message_id of the original mail, without angle brackets). Used for reply threading. Returns an error builder if id contains CR or LF.
func (Builder) LMSReplyToMessageID ¶
LMSReplyToMessageID sets the Lark internal message_id of the original message. Written as X-LMS-Reply-To-Message-Id when In-Reply-To is also set. Returns an error builder if id contains CR or LF.
func (Builder) MessageID ¶
MessageID sets the Message-ID header value (without angle brackets). If not set, Build() generates a unique ID. Returns an error builder if id contains CR or LF.
func (Builder) References ¶
References sets the References header value verbatim. Typically a space-separated list of message IDs including angle brackets, e.g. "<id1@host> <id2@host>". Returns an error builder if refs contains CR or LF.
func (Builder) Subject ¶
Subject sets the Subject header. Non-ASCII characters are automatically RFC 2047 B-encoded. Returns an error builder if subject contains CR or LF.