feat: add /api/translate proxy and expose email body to plugins
This commit is contained in:
@@ -5,6 +5,40 @@
|
||||
import type { Email } from '@/lib/jmap/types';
|
||||
import type { EmailReadView } from '@/lib/plugin-types';
|
||||
|
||||
// Resolve a message's plain-text body from its JMAP body parts. Plugins that
|
||||
// translate or scan content need the real body, not just the short `preview`
|
||||
// snippet. Prefers text/plain parts; falls back to stripped HTML, then preview.
|
||||
function plainTextFromEmail(email: Email): string {
|
||||
const values = email.bodyValues || {};
|
||||
const collect = (parts?: { partId: string }[]) =>
|
||||
(parts || [])
|
||||
.map((p) => values[p.partId]?.value)
|
||||
.filter((v): v is string => typeof v === 'string' && v.length > 0)
|
||||
.join('\n')
|
||||
.trim();
|
||||
|
||||
const text = collect(email.textBody);
|
||||
if (text) return text;
|
||||
|
||||
const html = collect(email.htmlBody);
|
||||
if (html) {
|
||||
return html
|
||||
.replace(/<(script|style)[\s\S]*?<\/\1>/gi, ' ')
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/ /gi, ' ')
|
||||
.replace(/&/gi, '&')
|
||||
.replace(/</gi, '<')
|
||||
.replace(/>/gi, '>')
|
||||
.replace(/'|'/gi, "'")
|
||||
.replace(/"/gi, '"')
|
||||
.replace(/[ \t]{2,}/g, ' ')
|
||||
.replace(/\n{3,}/g, '\n\n')
|
||||
.trim();
|
||||
}
|
||||
|
||||
return (email.preview || '').trim();
|
||||
}
|
||||
|
||||
export function emailToReadView(email: Email): EmailReadView {
|
||||
return {
|
||||
id: email.id,
|
||||
@@ -19,6 +53,7 @@ export function emailToReadView(email: Email): EmailReadView {
|
||||
isFlagged: !!email.keywords?.['$flagged'],
|
||||
hasAttachment: email.hasAttachment,
|
||||
preview: email.preview || '',
|
||||
text: plainTextFromEmail(email),
|
||||
keywords: Object.keys(email.keywords || {}).filter(k => email.keywords[k]),
|
||||
auth: email.authenticationResults,
|
||||
};
|
||||
|
||||
@@ -374,6 +374,10 @@ export interface EmailReadView {
|
||||
hasAttachment: boolean;
|
||||
preview: string;
|
||||
keywords: string[];
|
||||
/** Full plain-text body of the message (HTML-only bodies are stripped to
|
||||
* text). Empty string when the host hasn't loaded the body. Same
|
||||
* `email:read` sensitivity as the rest of this view. */
|
||||
text: string;
|
||||
/**
|
||||
* Parsed Authentication-Results header (SPF, DKIM, DMARC, reverse-DNS).
|
||||
* Absent on stores that didn't parse the header (e.g. bodies not yet
|
||||
|
||||
Reference in New Issue
Block a user