Documentation
¶
Index ¶
- Constants
- func Apply(dctx *DraftCtx, snapshot *DraftSnapshot, patch Patch) error
- func BuildSignatureHTML(sigID, content string) string
- func ExtractSignatureBlock(html string) string
- func FindMatchingCloseDiv(html string, startPos int) int
- func FindOrphanedCIDs(html string, addedCIDs []string) []string
- func HTMLContainsLargeAttachment(html string) bool
- func InsertBeforeQuoteOrAppend(html, block string) string
- func IsLargeAttachmentHeader(name string) bool
- func MustJSON(v interface{}) string
- func ParseLargeAttachmentItemsFromHTML(htmlBody string) map[string]LargeAttachmentSummary
- func PlaceSignatureBeforeSystemTail(html, sigBlock string) string
- func RemoveLargeFileItemFromHTML(htmlBody, token string) (string, bool)
- func RemoveSignatureHTML(html string) string
- func Send(runtime *common.RuntimeContext, mailboxID, draftID, sendTime string) (map[string]interface{}, error)
- func Serialize(snapshot *DraftSnapshot) (string, error)
- func SignatureSpacing() string
- func SignatureSpacingRe() *regexp.Regexp
- func SplitAtLargeAttachment(html string) (before, card, after string)
- func SplitAtQuote(html string) (body, quote string)
- func ValidateCIDReferences(html string, availableCIDs []string) error
- type Address
- type AttachmentTarget
- type DraftCtx
- type DraftProjection
- type DraftRaw
- type DraftResult
- type DraftSnapshot
- type Header
- type LargeAttachmentSummary
- type LocalImageRef
- type Part
- type PartSummary
- type Patch
- type PatchOp
- type PatchOptions
- type SignatureImage
Constants ¶
const ( LargeFileContainerIDPrefix = "large-file-area-" LargeFileItemID = "large-file-item" LargeAttachmentTokenAttr = "data-mail-token" )
Well-known anchors for the large attachment HTML card generated by CLI and the desktop client. The HTML structure is:
<div id="large-file-area-{timestamp}" ...>
<div>Title</div>
<div id="large-file-item" ...>
... filename, size, <a data-mail-token="..."> ...
</div>
<div id="large-file-item" ...> ... </div>
</div>
const LargeAttachmentIDsHeader = "X-Lms-Large-Attachment-Ids"
LargeAttachmentIDsHeader is the header name CLI writes when creating or editing a draft. The value is base64-encoded JSON: [{"id":"<token>"}].
const QuoteWrapperClass = "history-quote-wrapper"
QuoteWrapperClass is the CSS class name used by Lark's mail composer for reply/forward quote blocks. Both +reply and +forward wrap the quoted original message in a <div> with this class. Exported so that mail_quote.go (the generator) and projection.go (the detector) share a single source of truth.
const ServerLargeAttachmentHeader = "X-Lark-Large-Attachment"
ServerLargeAttachmentHeader is the header name the mail server returns on readback. The value is base64-encoded JSON with richer metadata: [{"file_key":"<token>","file_name":"...","file_size":...}].
const SignatureWrapperClass = "lark-mail-signature"
SignatureWrapperClass is the CSS class for the mail signature container.
Variables ¶
This section is empty.
Functions ¶
func BuildSignatureHTML ¶ added in v1.0.12
BuildSignatureHTML wraps signature content in the standard signature container div. sigID is HTML-escaped to prevent attribute injection.
func ExtractSignatureBlock ¶ added in v1.0.16
ExtractSignatureBlock returns the signature block (including any preceding spacing that would be removed by RemoveSignatureHTML) from html. Returns "" when html has no signature.
Symmetric to RemoveSignatureHTML: RemoveSignatureHTML(html) + ExtractSignatureBlock(html) reconstitutes the original html.
func FindMatchingCloseDiv ¶ added in v1.0.12
FindMatchingCloseDiv finds the position after the closing </div> that matches the <div at startPos, tracking nesting depth.
func FindOrphanedCIDs ¶ added in v1.0.6
FindOrphanedCIDs returns CIDs from addedCIDs that are not referenced in the HTML body via <img src="cid:...">. These would appear as unexpected attachments when the email is sent.
func HTMLContainsLargeAttachment ¶ added in v1.0.16
HTMLContainsLargeAttachment reports whether the given HTML fragment contains a large attachment card container (`<div ... id="large-file-area-..."`). Used to detect whether a user-supplied set_body value already carries a card, in which case auto-preservation is skipped.
func InsertBeforeQuoteOrAppend ¶ added in v1.0.16
InsertBeforeQuoteOrAppend inserts block into html right before the outermost quote wrapper (<div ... class="history-quote-wrapper">), or appends it to the end when no quote block is present. Matching uses quoteWrapperRe (an actual element with the class attribute), avoiding false positives from plain-text or code-snippet occurrences of the class name.
func IsLargeAttachmentHeader ¶ added in v1.0.16
IsLargeAttachmentHeader returns true if the header name matches either the CLI-written or server-returned large attachment header.
func ParseLargeAttachmentItemsFromHTML ¶ added in v1.0.16
func ParseLargeAttachmentItemsFromHTML(htmlBody string) map[string]LargeAttachmentSummary
ParseLargeAttachmentItemsFromHTML walks the HTML body looking for large attachment card items (<div id="large-file-item">) and returns a map from token (data-mail-token attribute value) to filename + size.
The size is parsed best-effort from the displayed string (e.g. "25.0 MB"); it carries the precision of the formatted value and is not byte-exact.
func PlaceSignatureBeforeSystemTail ¶ added in v1.0.16
PlaceSignatureBeforeSystemTail is the single source of truth for signature placement. It removes any existing signature from html, then inserts sigBlock at the split point between the user-authored region and the system-managed tail (large attachment card or history quote wrapper, whichever comes first).
Used by both compose-time signature injection (mail/signature_compose.go) and edit-time insert_signature op (draft/patch.go), guaranteeing they produce a consistent HTML layout [user][sig][card?][quote?].
When sigBlock is empty, behaves as a simple "remove signature" on the HTML string level — note that callers needing MIME-part orphan cleanup should handle that separately.
func RemoveLargeFileItemFromHTML ¶ added in v1.0.16
RemoveLargeFileItemFromHTML parses the HTML, finds the large-file-item containing an <a> whose token matches (via data-mail-token attribute or href URL token= parameter), removes that item, and if the enclosing large-file-area container becomes empty, removes the container as well. Returns the updated HTML and a changed flag.
func RemoveSignatureHTML ¶ added in v1.0.12
RemoveSignatureHTML removes the signature block and its preceding spacing from HTML. Returns the HTML unchanged if no signature is found.
func Send ¶
func Send(runtime *common.RuntimeContext, mailboxID, draftID, sendTime string) (map[string]interface{}, error)
func Serialize ¶
func Serialize(snapshot *DraftSnapshot) (string, error)
func SignatureSpacing ¶ added in v1.0.12
func SignatureSpacing() string
SignatureSpacing returns the 2 empty-line divs placed before the signature, matching the structure generated by the Lark mail editor.
func SignatureSpacingRe ¶ added in v1.0.12
SignatureSpacingRe returns the compiled regex for signature spacing detection.
func SplitAtLargeAttachment ¶ added in v1.0.16
SplitAtLargeAttachment splits HTML into three pieces around the first large-file-area container: content before, the entire container block, and content after. If no container is present, returns (html, "", "").
Used by set_body / set_reply_body to preserve the large attachment card across body replacements.
func SplitAtQuote ¶ added in v1.0.12
SplitAtQuote splits an HTML body into the user-authored content and the trailing reply/forward quote block. If no quote block is found, quote is empty and body is the original html unchanged.
func ValidateCIDReferences ¶ added in v1.0.6
ValidateCIDReferences checks that every cid: reference in the HTML body has a matching entry in availableCIDs. Returns an error for the first missing CID. Both sides are compared case-insensitively.
Types ¶
type AttachmentTarget ¶
type AttachmentTarget struct {
PartID string `json:"part_id,omitempty"`
CID string `json:"cid,omitempty"`
// Token selects a large attachment by its file token (registered via
// the X-Lms-Large-Attachment-Ids header). Only valid for
// remove_attachment; replace_inline/remove_inline operate on MIME
// parts and do not accept Token.
Token string `json:"token,omitempty"`
}
type DraftCtx ¶ added in v1.0.7
DraftCtx carries runtime dependencies for draft operations. It is separate from DraftSnapshot to keep the snapshot a pure data model.
type DraftProjection ¶
type DraftProjection struct {
Subject string `json:"subject"`
To []Address `json:"to,omitempty"`
Cc []Address `json:"cc,omitempty"`
Bcc []Address `json:"bcc,omitempty"`
ReplyTo []Address `json:"reply_to,omitempty"`
InReplyTo string `json:"in_reply_to,omitempty"`
References string `json:"references,omitempty"`
BodyText string `json:"body_text,omitempty"`
BodyHTMLSummary string `json:"body_html_summary,omitempty"`
HasQuotedContent bool `json:"has_quoted_content,omitempty"`
HasSignature bool `json:"has_signature,omitempty"`
SignatureID string `json:"signature_id,omitempty"`
AttachmentsSummary []PartSummary `json:"attachments_summary,omitempty"`
LargeAttachmentsSummary []LargeAttachmentSummary `json:"large_attachments_summary,omitempty"`
InlineSummary []PartSummary `json:"inline_summary,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
func Project ¶
func Project(snapshot *DraftSnapshot) DraftProjection
type DraftResult ¶ added in v1.0.16
func CreateWithRaw ¶
func CreateWithRaw(runtime *common.RuntimeContext, mailboxID, rawEML string) (DraftResult, error)
func UpdateWithRaw ¶
func UpdateWithRaw(runtime *common.RuntimeContext, mailboxID, draftID, rawEML string) (DraftResult, error)
type DraftSnapshot ¶
type DraftSnapshot struct {
DraftID string
Headers []Header
Body *Part
Subject string
From []Address
To []Address
Cc []Address
Bcc []Address
ReplyTo []Address
MessageID string
InReplyTo string
References string
PrimaryTextPartID string
PrimaryHTMLPartID string
}
func Parse ¶
func Parse(raw DraftRaw) (*DraftSnapshot, error)
type LargeAttachmentSummary ¶ added in v1.0.16
type LargeAttachmentSummary struct {
Token string `json:"token"`
FileName string `json:"filename,omitempty"`
SizeBytes int64 `json:"size_bytes,omitempty"`
}
LargeAttachmentSummary describes a single large attachment registered in the draft via the X-Lms-Large-Attachment-Ids header. Unlike normal attachments, large attachments have no MIME part — their existence is conveyed by the header plus an HTML card in the body.
func ParseLargeAttachmentSummariesFromHeader ¶ added in v1.0.16
func ParseLargeAttachmentSummariesFromHeader(headers []Header) []LargeAttachmentSummary
ParseLargeAttachmentSummariesFromHeader extracts full metadata from the large attachment header. Returns non-nil only when the server-format header (X-Lark-Large-Attachment) is found, since it carries file_name and file_size that the CLI-format header lacks.
type LocalImageRef ¶ added in v1.0.6
type LocalImageRef struct {
FilePath string // original src value from the HTML
CID string // generated Content-ID
}
LocalImageRef represents a local image found in an HTML body that needs to be embedded as an inline MIME part.
func ResolveLocalImagePaths ¶ added in v1.0.6
func ResolveLocalImagePaths(html string) (string, []LocalImageRef, error)
ResolveLocalImagePaths scans HTML for <img src="local/path"> references, validates each path, generates CIDs, and returns the modified HTML with cid: URIs plus the list of local image references to embed as inline parts. This function handles only the HTML transformation; callers are responsible for embedding the actual file data (e.g., via emlbuilder.AddFileInline).
type Part ¶
type Part struct {
PartID string
Headers []Header
MediaType string
MediaParams map[string]string
ContentDisposition string
ContentDispositionArg map[string]string
ContentID string
TransferEncoding string
Children []*Part
Body []byte
Preamble []byte
Epilogue []byte
RawEntity []byte
Dirty bool
// EncodingProblem is set when the part's body could not be decoded as
// declared (e.g. malformed base64, bad charset, unparseable Content-Type).
// The part still contains usable data (raw bytes or fallback decode) and
// can round-trip through RawEntity, but callers should treat Body as
// potentially degraded.
EncodingProblem bool
}
func FindHTMLBodyPart ¶ added in v1.0.16
FindHTMLBodyPart walks the MIME tree and returns the first text/html body part (skipping attachment-disposition parts), or nil when none exists.
func FindTextBodyPart ¶ added in v1.0.16
FindTextBodyPart walks the MIME tree and returns the first text/plain body part (skipping attachment-disposition parts), or nil when none exists.
func (*Part) IsMultipart ¶
type PartSummary ¶
type Patch ¶
type Patch struct {
Ops []PatchOp `json:"ops"`
Options PatchOptions `json:"options,omitempty"`
}
type PatchOp ¶
type PatchOp struct {
Op string `json:"op"`
Value string `json:"value,omitempty"`
Field string `json:"field,omitempty"`
Address string `json:"address,omitempty"`
Name string `json:"name,omitempty"`
Addresses []Address `json:"addresses,omitempty"`
BodyKind string `json:"body_kind,omitempty"`
Selector string `json:"selector,omitempty"`
Path string `json:"path,omitempty"`
CID string `json:"cid,omitempty"`
FileName string `json:"filename,omitempty"`
ContentType string `json:"content_type,omitempty"`
Target AttachmentTarget `json:"target,omitempty"`
SignatureID string `json:"signature_id,omitempty"`
// RenderedSignatureHTML is set by the shortcut layer (not from JSON) after
// fetching and interpolating the signature. The patch layer uses this
// pre-rendered content for insert_signature ops.
RenderedSignatureHTML string `json:"-"`
SignatureImages []SignatureImage `json:"-"`
}