fix(mail): Blob/get 兼容 Stalwart 的 data:asText 纯文本字段

Stalwart v0.11 对 text/* 直接返回 data:asText(非标准 base64 的 data),fetchEmailBody 优先读 data:asText,缺失时回退 atob(data)
This commit is contained in:
TermiNexus committed 2026-08-11 01:26:21 +08:00
1 parent 3e0af7596e
commit 4ba18370a4
1 file changed
+14 -9
+14 -9
View File
@@ -109,25 +109,30 @@ export class JmapClient {
}
/** 拉取邮件正文内容——Stalwart v0.11 的 Email/get 不返回 bodyValues,
* 正文通过 Blob/get 按 blobId 获取(base64 编码),HTML 正文提取纯文本 */
* 正文通过 Blob/get 按 blobId 获取。注意 Stalwart 对 text/* 直接返回
* data:asText(纯文本),标准 base64 则走 data 字段 */
async fetchEmailBody(email: JmapEmail): Promise<string> {
const parts = [...(email.textBody || []), ...(email.htmlBody || [])]
for (const p of parts) {
if (!p.blobId) continue
try {
const payload = await this.call<{ list?: Array<{ id: string; data?: string }> }>(
const payload = await this.call<{ list?: Array<{ id: string; data?: string; 'data:asText'?: string }> }>(
'Blob/get',
{ accountId: this.accountId, ids: [p.blobId] },
['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:blob'],
)
const data = payload.list?.[0]?.data
if (data) {
const text = atob(data)
if ((p.type || '').toLowerCase() === 'text/html') {
return text.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim()
}
return text
const item = payload.list?.[0]
if (!item) continue
// Stalwart v0.11 文本正文直接给 data:asText;标准实现用 base64 的 data
let text = item['data:asText']
if (text == null) {
if (!item.data) continue
text = atob(item.data)
}
if ((p.type || '').toLowerCase() === 'text/html') {
return text.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim()
}
return text
} catch {
/* 尝试下一个 part */
}