diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-07-01 17:29:07 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-07-01 17:29:07 +0800 |
commit | f4d60fb87f9c6d86a584eba11e6a3d17479af201 (patch) | |
tree | 37f1a7577e67acc06ddcfc918affb1ecd0df6038 /deno/mail/mail.ts | |
parent | 5e250ddcdbd6307989071e4ea794b1ad39e928e5 (diff) | |
download | crupest-f4d60fb87f9c6d86a584eba11e6a3d17479af201.tar.gz crupest-f4d60fb87f9c6d86a584eba11e6a3d17479af201.tar.bz2 crupest-f4d60fb87f9c6d86a584eba11e6a3d17479af201.zip |
mail: remove 'aws' of aws message id map.
Diffstat (limited to 'deno/mail/mail.ts')
-rw-r--r-- | deno/mail/mail.ts | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/deno/mail/mail.ts b/deno/mail/mail.ts index 9cc591c..b88ce2b 100644 --- a/deno/mail/mail.ts +++ b/deno/mail/mail.ts @@ -1,5 +1,8 @@ import { encodeBase64 } from "@std/encoding/base64"; import { parse } from "@std/csv/parse"; + +import { StringUtils } from "@crupest/base"; + import { simpleParseMail } from "./mail-parsing.ts"; export class Mail { @@ -47,7 +50,9 @@ export interface MailDeliverRecipientResult { export class MailDeliverResult { message?: string; - smtpMessage?: string; + messageForSmtp?: string; + newMessageId?: string; + recipients = new Map<string, MailDeliverRecipientResult>(); constructor(public mail: Mail) {} @@ -58,8 +63,8 @@ export class MailDeliverResult { generateLogMessage(prefix: string) { const lines = []; if (this.message != null) lines.push(`${prefix} message: ${this.message}`); - if (this.smtpMessage != null) { - lines.push(`${prefix} smtpMessage: ${this.smtpMessage}`); + if (this.messageForSmtp != null) { + lines.push(`${prefix} smtpMessage: ${this.messageForSmtp}`); } for (const [name, result] of this.recipients.entries()) { const { kind, message } = result; @@ -67,6 +72,13 @@ export class MailDeliverResult { } return lines.join("\n"); } + + generateMessageForSmtp(): string { + if (this.messageForSmtp != null) return this.messageForSmtp; + return `2.0.0 OK${ + StringUtils.prependNonEmpty(this.newMessageId) + } Message accepted for delivery`; + } } export class MailDeliverContext { @@ -232,3 +244,61 @@ export class AliasRecipientMailHook implements MailDeliverHook { } } } + +export class MessageIdRewriteHook implements MailDeliverHook { + readonly #lookup; + + constructor(lookup: (origin: string) => Promise<string | null>) { + this.#lookup = lookup; + } + + async callback(context: MailDeliverContext): Promise<void> { + const addresses = context.mail.simpleFindAllAddresses(); + for (const address of addresses) { + const newMessageId = await this.#lookup(address); + if (newMessageId != null && newMessageId.length !== 0) { + console.info( + context.logTag, + `Rewrite address-line string in mail: ${address} => ${newMessageId}.`, + ); + context.mail.raw = context.mail.raw.replaceAll(address, newMessageId); + } + } + } +} + +export class MessageIdSaveHook implements MailDeliverHook { + readonly #record; + + constructor( + record: ( + original: string, + newMessageId: string, + context: MailDeliverContext, + ) => Promise<void>, + ) { + this.#record = record; + } + + async callback(context: MailDeliverContext): Promise<void> { + const { messageId } = context.mail.parsed; + if (messageId == null) { + console.warn( + context.logTag, + "Original mail doesn't have message id, skip saving message id map.", + ); + return; + } + if (context.result.newMessageId != null) { + console.info( + context.logTag, + `Save message id map: ${messageId} => ${context.result.newMessageId}.`, + ); + context.mail.raw = context.mail.raw.replaceAll( + messageId, + context.result.newMessageId, + ); + await this.#record(messageId, context.result.newMessageId, context); + } + } +} |