diff --git a/src/backend/clients/email/EmailClient.ts b/src/backend/clients/email/EmailClient.ts index 60faf2116..7e274c470 100644 --- a/src/backend/clients/email/EmailClient.ts +++ b/src/backend/clients/email/EmailClient.ts @@ -45,11 +45,18 @@ export interface SendMailOptions { to: string; cc?: string; bcc?: string; + /** Optional transport recipients when they differ from visible headers. */ + envelope?: { + from?: string; + to: string; + }; subject: string; html?: string; text?: string; replyTo?: string; attachments?: EmailAttachment[]; + /** Extra message headers (e.g. List-Unsubscribe), passed to the transport. */ + headers?: Record; } export type EmailValidator = (email: string) => Promise | boolean; diff --git a/src/puter-js/src/modules/Email.js b/src/puter-js/src/modules/Email.js index 833abcf86..98cb2836d 100644 --- a/src/puter-js/src/modules/Email.js +++ b/src/puter-js/src/modules/Email.js @@ -22,6 +22,16 @@ import * as utils from '../lib/utils.js'; * }); * * Positional form: `await puter.email.send(to, subject, body)`. + * + * Every mail automatically gets an unsubscribe / report-abuse footer. + * Recipients who unsubscribe are dropped from future sends — they come + * back in the result's `suppressed` array — and a send whose `to` list + * is entirely unsubscribed is rejected. + * + * Each recipient gets a private delivery. A recipient whose delivery + * fails comes back in the result's `failed` array (everyone else got + * their copy — retry with just those addresses); the call only rejects + * when no recipient could be delivered. */ class Email { /** diff --git a/src/puter-js/types/modules/email.d.ts b/src/puter-js/types/modules/email.d.ts index 50435a763..3b2b820a1 100644 --- a/src/puter-js/types/modules/email.d.ts +++ b/src/puter-js/types/modules/email.d.ts @@ -36,10 +36,18 @@ export interface EmailSendOptions { } export interface EmailSendResult { - /** Transport message id, when the mail server reports one. */ + /** First transport message id reported for this send, when available. */ messageId: string | null; /** Total charge for this send, in microcents. */ cost: number; + /** Recipients omitted because they opted out of this sender's mail. */ + suppressed: string[]; + /** + * Recipients whose delivery attempt failed. Everyone else got their + * copy — retry with just these addresses. A send where every delivery + * fails rejects instead. + */ + failed: string[]; } /**