/// import { GetObjectCommand, ListObjectsV2Command, S3Client, } from "@aws-sdk/client-s3"; import { generateTimeStringForFileName, getEnvRequired } from "../base.ts"; import { getLogger } from "../logger.ts"; import { AwsContext } from "./base.ts"; import { MailDeliverer } from "../mail.ts"; export class AwsMailRetriever { mailBucket = getEnvRequired( "AWS_MAIL_BUCKET", "aws s3 bucket saving raw mails", ); liveMailPrefix = "mail/live/"; archiveMailPrefix = "mail/archive/"; private s3Client; private liveMailRecyclerAborter = new AbortController(); constructor(private aws: AwsContext, private localDeliverer: MailDeliverer) { const { region, credentials } = aws; this.s3Client = new S3Client({ region, credentials }); } setupLiveMailRecycler() { Deno.cron("live-mail-recycler", "0 */6 * * *", { signal: this.liveMailRecyclerAborter.signal, }, () => { }); } generateArchivePrefix(instant: Date | Temporal.Instant): string { return `${this.archiveMailPrefix}${ generateTimeStringForFileName(instant, true) }/`; } async listLiveMails(): Promise { 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) { result.push(object.Key); } else { getLogger().warn( "Listing live mails in S3 returns an object with no Key.", ); } } return result; } async deliverS3MailObject(messageId: string) { const command = new GetObjectCommand({ Bucket: this.mailBucket, Key: `${this.liveMailPrefix}${messageId}`, }); const res = await this.s3Client.send(command); if (res.Body == null) { // TODO: Better error. throw new Error(); } const rawMail = await res.Body.transformToString(); await this.localDeliverer.deliverRaw(rawMail); const archiveCommand = new } async recycleLiveMails() { const mails = await this.listLiveMails(); } }