diff options
Diffstat (limited to 'deno/mail-relay/aws')
-rw-r--r-- | deno/mail-relay/aws/app.ts | 5 | ||||
-rw-r--r-- | deno/mail-relay/aws/deliver.ts | 25 | ||||
-rw-r--r-- | deno/mail-relay/aws/fetch.ts | 40 | ||||
-rw-r--r-- | deno/mail-relay/aws/mail.ts | 26 |
4 files changed, 50 insertions, 46 deletions
diff --git a/deno/mail-relay/aws/app.ts b/deno/mail-relay/aws/app.ts index a8a9895..c8a90c8 100644 --- a/deno/mail-relay/aws/app.ts +++ b/deno/mail-relay/aws/app.ts @@ -110,7 +110,7 @@ function createOutbound( new AwsMailMessageIdSaveHook( async (original, aws, context) => { await db.addMessageIdMap({ message_id: original, aws_message_id: aws }); - void local?.saveNewSent(context.mail, original); + void local?.saveNewSent(context.logTag, context.mail, original); }, ), ); @@ -213,11 +213,14 @@ function createServerServices() { const smtp = createSmtp(outbound); const hono = createHono(outbound, inbound); + + let counter = 1; setupAwsHono(hono, { path: config.get("awsInboundPath"), auth: config.get("awsInboundKey"), callback: (s3Key, recipients) => { return fetcher.consumeS3Mail( + `[inbound ${counter++}]`, s3Key, (rawMail, _) => inbound.deliver({ mail: new Mail(rawMail), recipients }).then(), diff --git a/deno/mail-relay/aws/deliver.ts b/deno/mail-relay/aws/deliver.ts index ae010a7..0195369 100644 --- a/deno/mail-relay/aws/deliver.ts +++ b/deno/mail-relay/aws/deliver.ts @@ -4,7 +4,7 @@ import { SESv2ClientConfig, } from "@aws-sdk/client-sesv2"; -import { Mail, MailDeliverContext, SyncMailDeliverer } from "../mail.ts"; +import { Mail, MailDeliverContext, MailDeliverer } from "../mail.ts"; declare module "../mail.ts" { interface MailDeliverResult { @@ -12,13 +12,13 @@ declare module "../mail.ts" { } } -export class AwsMailDeliverer extends SyncMailDeliverer { +export class AwsMailDeliverer extends MailDeliverer { readonly name = "aws"; readonly #aws; readonly #ses; constructor(aws: SESv2ClientConfig) { - super(); + super(true); this.#aws = aws; this.#ses = new SESv2Client(aws); } @@ -27,8 +27,6 @@ export class AwsMailDeliverer extends SyncMailDeliverer { mail: Mail, context: MailDeliverContext, ): Promise<void> { - console.info("Begin to call aws send-email api..."); - try { const sendCommand = new SendEmailCommand({ Content: { @@ -36,23 +34,28 @@ export class AwsMailDeliverer extends SyncMailDeliverer { }, }); + console.info(context.logTag, "Calling aws send-email api..."); const res = await this.#ses.send(sendCommand); if (res.MessageId == null) { - console.warn("Aws send-email returns no message id."); + console.warn( + context.logTag, + "AWS send-email returned null message id.", + ); } else { context.result.awsMessageId = `${res.MessageId}@${this.#aws.region}.amazonses.com`; } - context.result.smtpMessage = `AWS Message ID: ${context.result.awsMessageId}`; + context.result.smtpMessage = + `AWS Message ID: ${context.result.awsMessageId}`; context.result.recipients.set("*", { - kind: "done", - message: `Successfully called aws send-email.`, + kind: "success", + message: `Succeeded to call aws send-email api.`, }); } catch (cause) { context.result.recipients.set("*", { - kind: "fail", - message: "An error was thrown when calling aws send-email." + cause, + kind: "failure", + message: "A JS error was thrown when calling aws send-email." + cause, cause, }); } diff --git a/deno/mail-relay/aws/fetch.ts b/deno/mail-relay/aws/fetch.ts index 9278e63..c603a35 100644 --- a/deno/mail-relay/aws/fetch.ts +++ b/deno/mail-relay/aws/fetch.ts @@ -50,8 +50,6 @@ export class AwsMailFetcher { } async listLiveMails(): Promise<string[]> { - console.info("Begin to retrieve live mails."); - const listCommand = new ListObjectsV2Command({ Bucket: this.#bucket, Prefix: this.#livePrefix, @@ -59,14 +57,14 @@ export class AwsMailFetcher { const res = await this.#s3.send(listCommand); if (res.Contents == null) { - console.warn("Listing live mails in S3 returns null Content."); + console.warn("S3 API returned null Content."); return []; } const result: string[] = []; for (const object of res.Contents) { if (object.Key == null) { - console.warn("Listing live mails in S3 returns an object with no Key."); + console.warn("S3 API returned null Key."); continue; } @@ -77,10 +75,12 @@ export class AwsMailFetcher { return result; } - async consumeS3Mail(s3Key: string, consumer: AwsS3MailConsumer) { - console.info(`Begin to consume s3 mail ${s3Key} ...`); - - console.info(`Fetching s3 mail ${s3Key}...`); + async consumeS3Mail( + logTag: string, + s3Key: string, + consumer: AwsS3MailConsumer, + ) { + console.info(logTag, `Fetching s3 mail ${s3Key}...`); const mailPath = `${this.#livePrefix}${s3Key}`; const command = new GetObjectCommand({ Bucket: this.#bucket, @@ -89,39 +89,37 @@ export class AwsMailFetcher { const res = await this.#s3.send(command); if (res.Body == null) { - throw new Error("S3 mail returns a null body."); + throw new Error("S3 API returns a null body."); } const rawMail = await res.Body.transformToString(); - console.info(`Done fetching s3 mail ${s3Key}.`); - console.info(`Calling consumer...`); + console.info(logTag, `Calling consumer...`); await consumer(rawMail, s3Key); - console.info(`Done consuming s3 mail ${s3Key}.`); - const date = new Mail(rawMail) - .startSimpleParse() - .sections() - .headers() - .date(); + const { date } = new Mail(rawMail).parsed; const dateString = date != null ? toFileNameString(date, true) : "invalid-date"; const newPath = `${this.#archivePrefix}${dateString}/${s3Key}`; - console.info(`Archiving s3 mail ${s3Key} to ${newPath}...`); + console.info(logTag, `Archiving s3 mail ${s3Key} to ${newPath}...`); await s3MoveObject(this.#s3, this.#bucket, mailPath, newPath); - console.info(`Done archiving s3 mail ${s3Key}.`); - console.info(`Done consuming s3 mail ${s3Key}.`); + console.info(logTag, `Done consuming s3 mail ${s3Key}.`); } async recycleLiveMails(consumer: AwsS3MailConsumer) { console.info("Begin to recycle live mails..."); const mails = await this.listLiveMails(); console.info(`Found ${mails.length} live mails`); + let counter = 1; for (const s3Key of mails) { - await this.consumeS3Mail(s3Key, consumer); + await this.consumeS3Mail( + `[${counter++}/${mails.length}]`, + s3Key, + consumer, + ); } } } diff --git a/deno/mail-relay/aws/mail.ts b/deno/mail-relay/aws/mail.ts index 7ac2332..26f3ea0 100644 --- a/deno/mail-relay/aws/mail.ts +++ b/deno/mail-relay/aws/mail.ts @@ -8,17 +8,17 @@ export class AwsMailMessageIdRewriteHook implements MailDeliverHook { } async callback(context: MailDeliverContext): Promise<void> { - console.info("Rewrite message ids..."); const addresses = context.mail.simpleFindAllAddresses(); - console.info(`Addresses found in mail: ${addresses.join(", ")}.`); for (const address of addresses) { const awsMessageId = await this.#lookup(address); if (awsMessageId != null && awsMessageId.length !== 0) { - console.info(`Rewrite ${address} to ${awsMessageId}.`); + console.info( + context.logTag, + `Rewrite address-line string in mail: ${address} => ${awsMessageId}.`, + ); context.mail.raw = context.mail.raw.replaceAll(address, awsMessageId); } } - console.info("Done rewrite message ids."); } } @@ -36,24 +36,24 @@ export class AwsMailMessageIdSaveHook implements MailDeliverHook { } async callback(context: MailDeliverContext): Promise<void> { - console.info("Save aws message ids..."); - const messageId = context.mail - .startSimpleParse() - .sections() - .headers() - .messageId(); + const { messageId } = context.mail.parsed; if (messageId == null) { - console.info("Original mail does not have message id. Skip saving."); + console.warn( + context.logTag, + "Original mail doesn't have message id, skip saving message id map.", + ); return; } if (context.result.awsMessageId != null) { - console.info(`Saving ${messageId} => ${context.result.awsMessageId}.`); + console.info( + context.logTag, + `Save message id map: ${messageId} => ${context.result.awsMessageId}.`, + ); context.mail.raw = context.mail.raw.replaceAll( messageId, context.result.awsMessageId, ); await this.#record(messageId, context.result.awsMessageId, context); } - console.info("Done save message ids."); } } |