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.");    }  } | 
