fix(mail): 发信改用 JMAP bodyValues 标准格式并检查投递结果

Stalwart v0.11 不允许 textBody/htmlBody 内联 value(invalidProperties Cannot set property),改用 partId+bodyValues;补 EmailSubmission 响应检查避免误报成功
This commit is contained in:
TermiNexus committed 2026-08-08 13:43:35 +08:00
1 parent 5da9dd04eb
commit 03fd87df13
1 file changed
+18 -2
+18 -2
View File
@@ -159,8 +159,16 @@ export class JmapClient {
to: opts.to.map((t) => ({ name: t.name || '', email: t.email })),
subject: opts.subject,
}
if (opts.htmlBody) emailData.htmlBody = [{ type: 'text/html', value: opts.htmlBody }]
if (opts.textBody) emailData.textBody = [{ type: 'text/plain', value: opts.textBody }]
// 正文必须用标准 JMAP bodyValues + partId 引用方式:
// Stalwart v0.11 不允许在 textBody/htmlBody 数组里内联 value(报 invalidProperties "Cannot set property.")
if (opts.htmlBody) {
emailData.htmlBody = [{ partId: '2', type: 'text/html' }]
emailData.bodyValues = { '2': { value: opts.htmlBody } }
}
if (opts.textBody) {
emailData.textBody = [{ partId: '1', type: 'text/plain' }]
emailData.bodyValues = { ...(emailData.bodyValues as Record<string, unknown>), '1': { value: opts.textBody } }
}
const result = await this.request([
['Email/set', { accountId: this.accountId, create: { d1: emailData } }, 'c1'],
@@ -186,5 +194,13 @@ export class JmapClient {
const firstErr = Object.values(err.notCreated || {})[0] as { type?: string; description?: string } | undefined
throw new Error(firstErr?.description || '创建邮件失败')
}
// 检查 EmailSubmission/set 结果(methodResponses[1]):Email/set 成功不代表已投递
const [, submitted] = result.methodResponses[1] || []
const submittedData = submitted as unknown as { created?: Record<string, unknown>; notCreated?: Record<string, unknown> }
if (!submittedData?.created) {
const subErr = Object.values(submittedData?.notCreated || {})[0] as { type?: string; description?: string } | undefined
throw new Error(subErr?.description || '邮件发送失败')
}
}
}