aboutsummaryrefslogtreecommitdiff
path: root/services/docker/mail-server/aws-sendmail/aws/retriever.ts
diff options
context:
space:
mode:
Diffstat (limited to 'services/docker/mail-server/aws-sendmail/aws/retriever.ts')
-rw-r--r--services/docker/mail-server/aws-sendmail/aws/retriever.ts90
1 files changed, 90 insertions, 0 deletions
diff --git a/services/docker/mail-server/aws-sendmail/aws/retriever.ts b/services/docker/mail-server/aws-sendmail/aws/retriever.ts
new file mode 100644
index 0000000..de577b0
--- /dev/null
+++ b/services/docker/mail-server/aws-sendmail/aws/retriever.ts
@@ -0,0 +1,90 @@
+/// <reference types="npm:@types/node" />
+
+import {
+ GetObjectCommand,
+ ListObjectsV2Command,
+ S3Client,
+} from "@aws-sdk/client-s3";
+
+import { AwsContext, s3MoveObject } from "./context.ts";
+import { getLogger } from "../logger.ts";
+import { getConfig } from "../config.ts";
+import { Mail } from "../mail.ts";
+
+export class AwsMailRetriever {
+ readonly liveMailPrefix = "mail/live/";
+ readonly archiveMailPrefix = "mail/archive/";
+ readonly mailBucket = getConfig().getValue("awsMailBucket");
+
+ private readonly s3Client;
+
+ constructor(
+ aws: AwsContext,
+ private readonly callback: (mail: Mail) => Promise<void>,
+ ) {
+ const { region, credentials } = aws;
+ this.s3Client = new S3Client({ region, credentials });
+ }
+
+ async listLiveMails(): Promise<string[]> {
+ const listCommand = new ListObjectsV2Command({
+ Bucket: this.mailBucket,
+ Prefix: this.liveMailPrefix,
+ });
+ const res = await this.s3Client.send(listCommand);
+
+ if (res.Contents == null) {
+ getLogger().warn("Listing live mails in S3 returns null Content.");
+ return [];
+ }
+
+ const result: string[] = [];
+ for (const object of res.Contents) {
+ if (object.Key != null) {
+ // TODO: check prefix consistence here.
+ result.push(object.Key.slice(this.liveMailPrefix.length));
+ } else {
+ getLogger().warn(
+ "Listing live mails in S3 returns an object with no Key.",
+ );
+ }
+ }
+ return result;
+ }
+
+ async deliverS3MailObject(messageId: string) {
+ const mailPath = `${this.liveMailPrefix}${messageId}`;
+ const command = new GetObjectCommand({
+ Bucket: this.mailBucket,
+ Key: mailPath,
+ });
+ const res = await this.s3Client.send(command);
+
+ if (res.Body == null) {
+ // TODO: Better error.
+ throw new Error();
+ }
+
+ const rawMail = await res.Body.transformToString();
+ const mail = new Mail(rawMail);
+ mail.awsMessageId = messageId;
+ await this.callback(mail);
+
+ // TODO: Continue here.
+ await s3MoveObject(
+ this.s3Client,
+ this.mailBucket,
+ mailPath,
+ `${this.archiveMailPrefix}${
+ mail.simpleGetDateString("invalid-date")
+ }/${messageId}`,
+ );
+ }
+
+ async recycleLiveMails() {
+ const mails = await this.listLiveMails();
+ for (const messageId of mails) {
+ await this.deliverS3MailObject(messageId);
+ }
+ }
+}